icss 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.rspec +3 -0
- data/.watchr +20 -0
- data/CHANGELOG.textile +8 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +34 -0
- data/LICENSE.textile +20 -0
- data/README.textile +19 -0
- data/Rakefile +43 -0
- data/VERSION +1 -0
- data/examples/BulkData.avpr +21 -0
- data/examples/complicated.icss.yaml +158 -0
- data/examples/interop.avsc +32 -0
- data/examples/mail.avpr +20 -0
- data/examples/namespace.avpr +28 -0
- data/examples/org/apache/avro/ipc/HandshakeRequest.avsc +11 -0
- data/examples/org/apache/avro/ipc/HandshakeResponse.avsc +15 -0
- data/examples/org/apache/avro/ipc/trace/avroTrace.avdl +64 -0
- data/examples/org/apache/avro/ipc/trace/avroTrace.avpr +82 -0
- data/examples/org/apache/avro/mapred/tether/InputProtocol.avpr +59 -0
- data/examples/org/apache/avro/mapred/tether/OutputProtocol.avpr +75 -0
- data/examples/simple.avpr +70 -0
- data/examples/weather.avsc +9 -0
- data/icss.gemspec +104 -0
- data/icss_specification.textile +370 -0
- data/init.rb +3 -0
- data/lib/icss.rb +19 -0
- data/lib/icss/brevity.rb +136 -0
- data/lib/icss/code_asset.rb +16 -0
- data/lib/icss/core_ext.rb +4 -0
- data/lib/icss/data_asset.rb +22 -0
- data/lib/icss/message.rb +72 -0
- data/lib/icss/old.rb +96 -0
- data/lib/icss/protocol.rb +138 -0
- data/lib/icss/protocol_set.rb +48 -0
- data/lib/icss/sample_message_call.rb +140 -0
- data/lib/icss/target.rb +71 -0
- data/lib/icss/type.rb +517 -0
- data/lib/icss/type/factory.rb +196 -0
- data/lib/icss/validations.rb +16 -0
- data/lib/icss/view_helper.rb +28 -0
- data/spec/icss_spec.rb +7 -0
- data/spec/spec_helper.rb +31 -0
- metadata +218 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
module Icss
|
2
|
+
class CodeAsset
|
3
|
+
include Receiver
|
4
|
+
include Receiver::ActsAsHash
|
5
|
+
|
6
|
+
rcvr_accessor :name, String
|
7
|
+
rcvr_accessor :location, String
|
8
|
+
|
9
|
+
def to_hash()
|
10
|
+
{ :name => name, :location => location}
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_json() to_hash.to_json ; end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Icss
|
2
|
+
class DataAsset
|
3
|
+
include Receiver
|
4
|
+
include Receiver::ActsAsHash
|
5
|
+
|
6
|
+
rcvr_accessor :name, String
|
7
|
+
rcvr_accessor :location, String
|
8
|
+
#overriding ruby's deprecated but still present type attr on objects
|
9
|
+
attr_accessor :type
|
10
|
+
rcvr_accessor :type, String
|
11
|
+
rcvr_accessor :doc, String
|
12
|
+
|
13
|
+
def named? nm
|
14
|
+
name == nm
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_hash()
|
18
|
+
{ :name => name, :location => location, :type => type, :doc => doc }
|
19
|
+
end
|
20
|
+
def to_json() to_hash.to_json ; end
|
21
|
+
end
|
22
|
+
end
|
data/lib/icss/message.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
module Icss
|
2
|
+
|
3
|
+
#
|
4
|
+
# Describes an Avro Message
|
5
|
+
#
|
6
|
+
# A message has attributes:
|
7
|
+
#
|
8
|
+
# * doc: an optional description of the message,
|
9
|
+
# * request: a list of named, typed parameter schemas (this has the same form as the fields of a record declaration);
|
10
|
+
# * response: a valid schema for the response
|
11
|
+
# * errors: an optional union of error schemas.
|
12
|
+
#
|
13
|
+
# A request parameter list is processed equivalently to an anonymous
|
14
|
+
# record. Since record field lists may vary between reader and writer, request
|
15
|
+
# parameters may also differ between the caller and responder, and such
|
16
|
+
# differences are resolved in the same manner as record field differences.
|
17
|
+
#
|
18
|
+
class Message
|
19
|
+
include Receiver
|
20
|
+
include Receiver::ActsAsHash
|
21
|
+
rcvr_accessor :name, String
|
22
|
+
rcvr_accessor :doc, String
|
23
|
+
|
24
|
+
#we're starting to attach a lot of pork to this lib...
|
25
|
+
rcvr_accessor :initial_free_qty, Integer
|
26
|
+
rcvr_accessor :price_per_k_in_cents, Integer
|
27
|
+
|
28
|
+
rcvr_accessor :request, Array, :of => Icss::RecordField, :default => []
|
29
|
+
rcvr_accessor :response, Icss::TypeFactory
|
30
|
+
rcvr_accessor :errors, Icss::UnionType, :default => []
|
31
|
+
attr_accessor :protocol
|
32
|
+
# this is defined in sample_message_call.rb -- since we don't do referenced types yet
|
33
|
+
# rcvr_accessor :samples, Array, :of => Icss::SampleMessageCall, :default => []
|
34
|
+
|
35
|
+
after_receive do |hsh|
|
36
|
+
# track recursion of type references
|
37
|
+
@response_is_reference = true if hsh['response'].is_a?(String) || hsh['response'].is_a?(Symbol)
|
38
|
+
# tie each sample back to this, its parent message
|
39
|
+
(self.samples ||= []).each{|sample| sample.message = self }
|
40
|
+
end
|
41
|
+
|
42
|
+
def path
|
43
|
+
File.join(protocol.path, name)
|
44
|
+
end
|
45
|
+
|
46
|
+
def first_sample_request_param
|
47
|
+
req = samples.first.request.first rescue nil
|
48
|
+
req || {}
|
49
|
+
end
|
50
|
+
|
51
|
+
#
|
52
|
+
# Conversion
|
53
|
+
#
|
54
|
+
def to_hash()
|
55
|
+
{
|
56
|
+
:doc => doc,
|
57
|
+
:request => summary_of_request_attr,
|
58
|
+
:response => summary_of_response_attr,
|
59
|
+
:errors => errors,
|
60
|
+
}.reject{|k,v| v.nil? }
|
61
|
+
end
|
62
|
+
def to_json(*args) to_hash.to_json(*args) ; end
|
63
|
+
|
64
|
+
private
|
65
|
+
def summary_of_response_attr
|
66
|
+
case when response.blank? then response when @response_is_reference then response.name else response.to_hash end
|
67
|
+
end
|
68
|
+
def summary_of_request_attr
|
69
|
+
request.map(&:to_hash)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/lib/icss/old.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
module Icss
|
2
|
+
Protocol.class_eval do
|
3
|
+
|
4
|
+
#
|
5
|
+
# Returns the asset hash with the passed in asset_name
|
6
|
+
#
|
7
|
+
def asset_for_name nm
|
8
|
+
warn "asset_for_name obsolete, please rewrite"
|
9
|
+
data_assets.find{|asset| asset.named?(nm) }
|
10
|
+
end
|
11
|
+
|
12
|
+
#
|
13
|
+
# Returns the full type for the passed in asset hash
|
14
|
+
#
|
15
|
+
def type_for_asset asset
|
16
|
+
warn "type_for_asset obsolete, please rewrite"
|
17
|
+
# types.find{|type| type.name == asset['type']}
|
18
|
+
raise 'use asset.type_obj'
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# Given an asset name, returns the the record it points to
|
23
|
+
#
|
24
|
+
def type_for_asset_name asset_name
|
25
|
+
warn "type_for_asset_name obsolete, please rewrite"
|
26
|
+
asset = asset_for_name(asset_name)
|
27
|
+
type_for_asset(asset)
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# Given an asset name, return the name of the type it points to
|
32
|
+
#
|
33
|
+
def type_name_for_asset_name asset_name
|
34
|
+
warn "type_name_for_asset_name obsolete, please rewrite"
|
35
|
+
asset = asset_for_name(asset_name)
|
36
|
+
asset['type']
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
# Return the avro record with the given name
|
41
|
+
#
|
42
|
+
def type_for_name type_name
|
43
|
+
warn "type_for_name obsolete, please rewrite"
|
44
|
+
# types.find{|record| record.name == type_name}
|
45
|
+
Icss::Type.find(type_name)
|
46
|
+
end
|
47
|
+
|
48
|
+
#
|
49
|
+
# Fetch the avro fields for a named data asset
|
50
|
+
#
|
51
|
+
def fields_for_asset asset_name
|
52
|
+
warn "fields_for_asset obsolete, please rewrite"
|
53
|
+
asset = asset_for_name(asset_name)
|
54
|
+
asset_type = type_for_asset(asset)
|
55
|
+
asset_type.fields
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# Fetch the locations on disk of each data asset. WARNING: Assuming relative paths
|
60
|
+
#
|
61
|
+
def location_for_asset asset_name
|
62
|
+
warn "location_for_asset obsolete, please rewrite"
|
63
|
+
asset = asset_for_name(asset_name)
|
64
|
+
File.join(dirname, asset['location'])
|
65
|
+
end
|
66
|
+
|
67
|
+
#
|
68
|
+
# Return the index of the named field for the named type. Returns (nil) if field
|
69
|
+
# does not exist
|
70
|
+
#
|
71
|
+
def index_of_fieldname asset_name, field_name
|
72
|
+
warn "index_of_fieldname obsolete, please rewrite"
|
73
|
+
type = type_for_asset_name(asset_name)
|
74
|
+
type.index_of_fieldname(field_name)
|
75
|
+
end
|
76
|
+
|
77
|
+
AVRO_PIG_MAPPING = {
|
78
|
+
'string' => 'chararray',
|
79
|
+
'int' => 'int',
|
80
|
+
'long' => 'long',
|
81
|
+
'float' => 'float',
|
82
|
+
'double' => 'double',
|
83
|
+
'bytes' => 'bytearray',
|
84
|
+
'fixed' => 'bytearray'
|
85
|
+
}
|
86
|
+
|
87
|
+
#
|
88
|
+
# Add pig fields to a passed in array of avro fields
|
89
|
+
#
|
90
|
+
def augment_with_pig_fields fields
|
91
|
+
warn "augment_with_pig_fields obsolete, please rewrite"
|
92
|
+
fields.map{|field| field.body['pig_type'] = AVRO_PIG_MAPPING[field.type]; field }
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
module Icss
|
2
|
+
|
3
|
+
#
|
4
|
+
# Describes an Avro Protocol Declaration
|
5
|
+
#
|
6
|
+
# Avro protocols describe RPC interfaces. The Protocol class will receive an
|
7
|
+
# Avro JSON
|
8
|
+
#
|
9
|
+
# A Protocol has the following attributes:
|
10
|
+
#
|
11
|
+
# * protocol, a string, the name of the protocol (required). +name+ is
|
12
|
+
# provided as an alias for +protocol+.
|
13
|
+
#
|
14
|
+
# * namespace, a string that qualifies the name (optional).
|
15
|
+
#
|
16
|
+
# * doc, a string describing this protocol (optional).
|
17
|
+
#
|
18
|
+
# * types, an optional list of definitions of named types (records, enums,
|
19
|
+
# fixed and errors). An error definition is just like a record definition
|
20
|
+
# except it uses "error" instead of "record". Note that forward references
|
21
|
+
# to named types are not permitted.
|
22
|
+
#
|
23
|
+
# * messages, an optional JSON object whose keys are message names and whose
|
24
|
+
# values are objects whose attributes are described below. No two messages
|
25
|
+
# may have the same name.
|
26
|
+
#
|
27
|
+
# The name and namespace qualification rules defined for schema objects apply
|
28
|
+
# to protocols as well: see the documentation for Icss::Type.
|
29
|
+
#
|
30
|
+
# For example, one may define a simple HelloWorld protocol with:
|
31
|
+
#
|
32
|
+
# {
|
33
|
+
# "namespace": "com.acme",
|
34
|
+
# "protocol": "HelloWorld",
|
35
|
+
# "doc": "Protocol Greetings",
|
36
|
+
# "types": [
|
37
|
+
# { "name": "Greeting",
|
38
|
+
# "type": "record",
|
39
|
+
# "fields": [ {"name": "message", "type": "string"} ]},
|
40
|
+
# { "name": "Curse",
|
41
|
+
# "type": "error",
|
42
|
+
# "fields": [ {"name": "message", "type": "string"} ]}
|
43
|
+
# ],
|
44
|
+
# "messages": {
|
45
|
+
# "hello": {
|
46
|
+
# "doc": "Say hello.",
|
47
|
+
# "request": [{"name": "greeting", "type": "Greeting" }],
|
48
|
+
# "response": "Greeting",
|
49
|
+
# "errors": ["Curse"]
|
50
|
+
# }
|
51
|
+
# }
|
52
|
+
# }
|
53
|
+
#
|
54
|
+
class Protocol
|
55
|
+
include Receiver
|
56
|
+
include Receiver::ActsAsHash
|
57
|
+
include Receiver::ActsAsLoadable
|
58
|
+
include Icss::Validations
|
59
|
+
|
60
|
+
rcvr_accessor :protocol, String, :required => true
|
61
|
+
alias_method :name, :protocol
|
62
|
+
rcvr_accessor :namespace, String # must be *dotted* ("foo.bar"), not slashed ("foo/bar")
|
63
|
+
rcvr_accessor :doc, String
|
64
|
+
#
|
65
|
+
rcvr_accessor :types, Array, :of => Icss::TypeFactory, :default => []
|
66
|
+
rcvr_accessor :messages, Hash, :of => Icss::Message, :default => {}
|
67
|
+
# extensions to avro
|
68
|
+
rcvr_accessor :data_assets, Array, :of => Icss::DataAsset, :default => []
|
69
|
+
rcvr_accessor :code_assets, Array, :of => Icss::CodeAsset, :default => []
|
70
|
+
rcvr_accessor :targets, Hash, :of => Icss::TargetListFactory, :default => {}, :merge_as => :hash_of_arrays
|
71
|
+
rcvr_accessor :under_consideration, Boolean
|
72
|
+
rcvr_accessor :update_frequency, String # must be of the form daily, weekly, monthly, quarterly, never
|
73
|
+
|
74
|
+
# attr_accessor :body
|
75
|
+
after_receive do |hsh|
|
76
|
+
# Set each message's protocol to self, and if the name wasn't given, set
|
77
|
+
# it using the message's hash key.
|
78
|
+
self.messages.each{|msg_name, msg| msg.protocol = self; msg.name ||= msg_name }
|
79
|
+
# Set all the type's parent to self (for namespace resolution)
|
80
|
+
self.types.each{|type| type.parent = self }
|
81
|
+
validate_name
|
82
|
+
validate_namespace
|
83
|
+
end
|
84
|
+
|
85
|
+
# String: namespace.name
|
86
|
+
def fullname
|
87
|
+
[namespace, name].compact.join(".")
|
88
|
+
end
|
89
|
+
|
90
|
+
def path
|
91
|
+
fullname.gsub('.', '/')
|
92
|
+
end
|
93
|
+
|
94
|
+
def find_message nm
|
95
|
+
return if messages.blank?
|
96
|
+
nm = nm.to_s.gsub("/", ".").split(".").last
|
97
|
+
messages[nm]
|
98
|
+
end
|
99
|
+
|
100
|
+
def receive_protocol nm
|
101
|
+
namespace_and_name = nm.to_s.gsub("/", ".").split(".")
|
102
|
+
self.protocol = namespace_and_name.pop
|
103
|
+
self.namespace = namespace_and_name.join('.')
|
104
|
+
end
|
105
|
+
|
106
|
+
def receive_targets hsh
|
107
|
+
self.targets = hsh.inject({}) do |target_obj_hsh, (target_name, target_info_list)|
|
108
|
+
target_obj_hsh[target_name] = TargetListFactory.receive(target_info_list, target_name) # returns an arry of targets
|
109
|
+
target_obj_hsh
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def to_hash()
|
114
|
+
{
|
115
|
+
:namespace => @namespace, # use accessor so unset namespace isn't given
|
116
|
+
:protocol => protocol,
|
117
|
+
:doc => doc,
|
118
|
+
:under_consideration => under_consideration,
|
119
|
+
:update_frequency => update_frequency,
|
120
|
+
:types => (types && types.map(&:to_hash)),
|
121
|
+
:messages => messages.inject({}){|h,(k,v)| h[k] = v.to_hash; h },
|
122
|
+
:data_assets => data_assets.map(&:to_hash),
|
123
|
+
:code_assets => code_assets.map(&:to_hash),
|
124
|
+
:targets => targets_to_hash,
|
125
|
+
}.reject{|k,v| v.nil? }.tree_merge! self.message_samples_hash
|
126
|
+
end
|
127
|
+
|
128
|
+
def targets_to_hash
|
129
|
+
return unless targets
|
130
|
+
targets.inject({}) do |hsh,(k,targs)|
|
131
|
+
hsh[k] = targs.map{|t| t.respond_to?(:to_hash) ? t.to_hash : t } ; hsh
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# This will cause funny errors when it is an element of something that's to_json'ed
|
136
|
+
def to_json(*args) to_hash.to_json(*args) ; end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# you must require 'icss/protocol_set' explicitly to use it.
|
2
|
+
|
3
|
+
module Icss
|
4
|
+
#
|
5
|
+
# Holds a set of icss protocols, with helper methods to load them from a
|
6
|
+
# directory tree, to merge in a protocol set yaml file, and so forth
|
7
|
+
#
|
8
|
+
class ProtocolSet
|
9
|
+
attr_accessor :protocols
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
self.protocols = {}
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
def register pr
|
17
|
+
if protocols[pr.fullname]
|
18
|
+
protocols[pr.fullname].tree_merge!(pr)
|
19
|
+
else
|
20
|
+
protocols[pr.fullname] = pr
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# load and register the protocols in the given filenames
|
25
|
+
def load_protocols *icss_filenames
|
26
|
+
icss_filenames = icss_filenames.flatten.compact
|
27
|
+
icss_filenames.each do |icss_filename|
|
28
|
+
register Icss::Protocol.receive_from_file(icss_filename)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# load and register the set of protocols in the given yaml file.
|
33
|
+
# it must be a hash with element 'protocol_set', holding an array of
|
34
|
+
# protocol hashes.
|
35
|
+
#
|
36
|
+
# protocol_set:
|
37
|
+
# - namespace: "..."
|
38
|
+
# protocol: "..."
|
39
|
+
def load_protocol_set protocol_set_filename
|
40
|
+
protocol_set_hsh = YAML.load(File.open(protocol_set_filename))
|
41
|
+
protocol_set_hsh['protocol_set'].each do |hsh|
|
42
|
+
register Icss::Protocol.receive(hsh)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
|
@@ -0,0 +1,140 @@
|
|
1
|
+
module Icss
|
2
|
+
#
|
3
|
+
# Holds a sample call for a message and its expected response
|
4
|
+
#
|
5
|
+
# You may define the request parameters using an array of parameters
|
6
|
+
# or with the corresponding URL it would render to.
|
7
|
+
#
|
8
|
+
# This file also decorates Icss::Message and Icss::Protocol with helper methods for sample calls.
|
9
|
+
#
|
10
|
+
class SampleMessageCall
|
11
|
+
include Receiver
|
12
|
+
rcvr_accessor :name, String
|
13
|
+
rcvr_accessor :doc, String
|
14
|
+
rcvr_accessor :request, Array, :default => []
|
15
|
+
rcvr_accessor :response, Object # a hash suitable for populating the message's @response@ type
|
16
|
+
attr_accessor :raw_response # the raw http response from fetching
|
17
|
+
rcvr_accessor :error, String
|
18
|
+
rcvr_accessor :url, String
|
19
|
+
attr_accessor :message
|
20
|
+
|
21
|
+
# The URL implied by the given hostname and the sample request parameters.
|
22
|
+
#
|
23
|
+
# @param [String] hostname The hostname or hostname:port to include in the URL
|
24
|
+
# @param [Hash] extra_query_params A hash of extra params to in
|
25
|
+
#
|
26
|
+
# The URI expects string values in the hash used to build the query -- if
|
27
|
+
# calling #to_s on a field won't do what you want, clobber the value beforehand.
|
28
|
+
#
|
29
|
+
def full_url hostname, extra_query_params={}
|
30
|
+
host, port = hostname.split(':', 2)
|
31
|
+
u = Addressable::URI.new(:host => host, :port => port, :path => self.path, :scheme => 'http')
|
32
|
+
u.query_values = query_hash(extra_query_params)
|
33
|
+
u
|
34
|
+
end
|
35
|
+
|
36
|
+
def query_hash extra_query_params={}
|
37
|
+
hsh = (@url.present? ? @url.query_values : request.first.to_hash) rescue {}
|
38
|
+
hsh = hsh.merge extra_query_params
|
39
|
+
hsh.each{|k,v| hsh[k] = v.to_s }
|
40
|
+
hsh
|
41
|
+
end
|
42
|
+
|
43
|
+
def path
|
44
|
+
((@url && @url.path).present? ? @url.path : "/#{message.path}" )
|
45
|
+
end
|
46
|
+
|
47
|
+
# @param [String, Addressable::URI]
|
48
|
+
# the URL can be fully-qualified (htttp://api.infochimps.com/this/that?the=other) or relative (this/that?the=other)
|
49
|
+
# and the path must match that of the message.
|
50
|
+
#
|
51
|
+
def url= new_url
|
52
|
+
if new_url.is_a?(String)
|
53
|
+
unless new_url.include?('?') then warn "sample request url should have a '?' introducing its query parameters: {#{new_url}}" ; end
|
54
|
+
new_url = Addressable::URI.parse(new_url)
|
55
|
+
end
|
56
|
+
@url = new_url
|
57
|
+
end
|
58
|
+
|
59
|
+
# Whips up the class implied by the ICSS type of this message's response,
|
60
|
+
# and populates it using the response hash.
|
61
|
+
def response_obj
|
62
|
+
return if response.blank?
|
63
|
+
klass = message.response.ruby_klass
|
64
|
+
klass.receive(response.compact_blank!)
|
65
|
+
end
|
66
|
+
|
67
|
+
# retrieve the response from the given host, storing it in response. this
|
68
|
+
# catches all server errors and constructs a dummy response hash if the call
|
69
|
+
# fails.
|
70
|
+
def fetch_response! hostname="", extra_query_params={}
|
71
|
+
self.raw_response = fetch_raw_response( full_url(hostname, extra_query_params) )
|
72
|
+
begin
|
73
|
+
resp_hsh = JSON.load(raw_response.body)
|
74
|
+
rescue StandardError => e
|
75
|
+
warn [" error parsing response: #{e}"].join("\n")
|
76
|
+
self.response = nil
|
77
|
+
self.error = "JsonParseError"
|
78
|
+
return
|
79
|
+
end
|
80
|
+
if raw_response.code == 200
|
81
|
+
self.response = resp_hsh
|
82
|
+
self.error = nil
|
83
|
+
else
|
84
|
+
self.response = nil
|
85
|
+
self.error = resp_hsh["error"]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
def fetch_raw_response full_url
|
92
|
+
RestClient.get(full_url.to_s) do |response, request, result|
|
93
|
+
response
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
class Icss::Message
|
100
|
+
rcvr_accessor :samples, Array, :of => Icss::SampleMessageCall, :default => []
|
101
|
+
end
|
102
|
+
|
103
|
+
class Icss::Protocol
|
104
|
+
|
105
|
+
#
|
106
|
+
# a hash for dumping to file:
|
107
|
+
# @example: from the whole thing, would dump only this:
|
108
|
+
#
|
109
|
+
# namespace: util.time
|
110
|
+
# protocol: chronic
|
111
|
+
# messages:
|
112
|
+
# parse:
|
113
|
+
# samples:
|
114
|
+
# - url: "?now=5%3A06%3A07%202010-08-08&time_str=Yesterday"
|
115
|
+
# response: { "time": "2010-08-07 05:06:07 UTC", "epoch_seconds": 1281225967 }
|
116
|
+
#
|
117
|
+
def message_samples_hash
|
118
|
+
hsh = { "namespace" => namespace, "protocol" => protocol, "messages" => {} }
|
119
|
+
messages.each do |msg_name, msg|
|
120
|
+
hsh["messages"][msg_name] = { "samples" => [] }
|
121
|
+
msg.samples.each do |sample_req|
|
122
|
+
sample_hsh = {
|
123
|
+
"name" => sample_req.name,
|
124
|
+
"doc" => sample_req.doc,
|
125
|
+
}
|
126
|
+
if sample_req.response.present?
|
127
|
+
then sample_hsh['response'] = sample_req.response
|
128
|
+
else sample_hsh['error'] = sample_req.error
|
129
|
+
end
|
130
|
+
if sample_req.url.present?
|
131
|
+
then sample_hsh['url'] = sample_req.url.to_s
|
132
|
+
else sample_hsh['request'] = sample_req.request
|
133
|
+
end
|
134
|
+
hsh["messages"][msg_name]["samples"] << sample_hsh.compact_blank!
|
135
|
+
end
|
136
|
+
end
|
137
|
+
return hsh
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|