Class: Icss::Meta::Protocol

Inherits:
Object show all
Includes:
ReceiverModel, ReceiverModel::ActsAsCatalog
Defined in:
lib/icss/protocol.rb,
lib/icss/message/message_sample.rb

Overview

Describes an Avro Protocol Declaration

Avro protocols describe RPC interfaces. The Protocol class will receive an Avro JSON

A Protocol has the following attributes:

  • protocol, a string, the name of the protocol (required). name is provided as an alias for protocol.

  • namespace, a string that qualifies the name (optional).

  • doc, a string describing this protocol (optional).

  • types, an optional list of definitions of named types (records, enums, fixed and errors). An error definition is just like a record definition except it uses “error” instead of “record”. Note that forward references to named types are not permitted.

  • messages, an optional JSON object whose keys are message names and whose values are objects whose attributes are described below. No two messages may have the same name.

The name and namespace qualification rules defined for schema objects apply to protocols as well: see the documentation for Icss::Meta::Type.

For example, one may define a simple HelloWorld protocol with:

{
  "namespace":    "com.acme",
  "protocol":     "HelloWorld",
  "doc":          "Protocol Greetings",
  "types": [
    { "name":     "Greeting",
      "type":     "record",
      "fields":   [ {"name": "message", "type": "string"} ]},
    { "name":     "Curse",
      "type":     "error",
      "fields":   [ {"name": "message", "type": "string"} ]}
  ],
  "messages": {
    "hello": {
      "doc":      "Say hello.",
      "request":  [{"name": "greeting", "type": "Greeting" }],
      "response": "Greeting",
      "errors":   ["Curse"]
    }
  }
}

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ReceiverModel::ActsAsCatalog

included, #register

Methods included from ReceiverModel

included, #tree_merge!

Methods included from ReceiverModel::ActsAsTuple

included, #to_tuple

Methods included from RecordModel

#attr_set?, included, #receive!, #to_zaml

Methods included from ReceiverModel::ActsAsLoadable

#merge_from_file!

Methods included from ReceiverModel::ActsAsHash

#[], #[]=, #attributes, #delete, included, #keys

Class Method Details

.catalog_sectionsObject



164
165
166
# File 'lib/icss/protocol.rb', line 164

def self.catalog_sections
  ['core', 'datasets', 'old']
end

Instance Method Details

#find_message(nm) ⇒ Object



125
126
127
128
129
# File 'lib/icss/protocol.rb', line 125

def find_message nm
  return if messages.blank?
  nm = nm.to_s.gsub("/", ".").split(".").last
  messages[nm]
end

#fullnameObject

String: namespace.basename



116
117
118
# File 'lib/icss/protocol.rb', line 116

def fullname
  [namespace, basename].compact.join(".")
end

#licenseObject



82
83
84
# File 'lib/icss/protocol.rb', line 82

def license
  Icss::Meta::License.find(license_id) unless license_id.blank?
end

#message_samples_hashObject

a hash for dumping to file: @example: from the whole thing, would dump only this:

namespace: util.time
protocol: chronic
messages:
  parse:
    samples:
      - url:            "?now=5%3A06%3A07%202010-08-08&time_str=Yesterday"
        response:       { "time": "2010-08-07 05:06:07 UTC", "epoch_seconds": 1281225967 }


120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/icss/message/message_sample.rb', line 120

def message_samples_hash
  hsh = { :namespace => namespace, :protocol => protocol, :messages => {} }
  messages.each do |msg_name, msg|
    hsh[:messages][msg_name] = { :samples => [] }
    msg.samples.each do |sample_req|
      sample_hsh = {
        :name     => sample_req.name,
        :doc      => sample_req.doc,
      }
      if sample_req.response.present?
      then sample_hsh[:response] =  sample_req.response
      else sample_hsh[:error]    =  sample_req.error
      end
      if sample_req.url.present?
      then sample_hsh[:url]      = sample_req.url.to_s
      else sample_hsh[:request]  = sample_req.request
      end
      sample_hsh.compact_blank!
      hsh[:messages][msg_name][:samples] << sample_hsh
    end
  end
  return hsh
end

#pathObject

a / separated version of the fullname, with no / at start



121
122
123
# File 'lib/icss/protocol.rb', line 121

def path
  fullname.gsub('.', '/')
end

#receive_messages(types) ⇒ Object



140
141
142
143
144
145
146
147
# File 'lib/icss/protocol.rb', line 140

def receive_messages(types)
  # this is a horrible, horrible kludge so that messages with simple names ('do_bob') can become
  # properly namespaced ('foo.bar.do_bob') even when they haven't met their parents (and even 
  # where the calls to receive_messages are nested/recursive)
  Icss::Meta::TypeFactory.with_namespace(namespace) do
    super(types)
  end
end

#receive_protocol(nm) ⇒ Object



149
150
151
152
153
# File 'lib/icss/protocol.rb', line 149

def receive_protocol(nm)
  name_segs = nm.to_s.gsub("/", ".").split(".")
  self.protocol  = name_segs.pop
  self.namespace = name_segs.join('.') if name_segs.present?
end

#receive_targets(tgts) ⇒ Object



155
156
157
158
159
160
161
162
# File 'lib/icss/protocol.rb', line 155

def receive_targets(tgts)
  return unless tgts.present?
  self.targets ||= {}
  tgts.symbolize_keys!.each do |target_name, target_info_list|
    targets[target_name] = TargetListFactory.receive(target_info_list, target_name) # array of targets
  end
  targets
end

#receive_types(types) ⇒ Object



131
132
133
134
135
136
137
138
# File 'lib/icss/protocol.rb', line 131

def receive_types(types)
  # this is a horrible, horrible kludge so that types with simple names ('bob') can become
  # properly namespaced ('foo.bar.bob') even when they haven't met their parents (and even 
  # where the calls to receive types are nested/recursive)
  Icss::Meta::TypeFactory.with_namespace(namespace) do
    super(types)
  end
end

#sourcesObject



86
87
88
# File 'lib/icss/protocol.rb', line 86

def sources
  @sources ||= credits.inject(Hash.new){|hash, credit| hash[credit[0].to_sym] = Icss::Meta::Source.find(credit[1]); hash }
end

#targets_to_hashObject



187
188
189
190
191
192
# File 'lib/icss/protocol.rb', line 187

def targets_to_hash
  return unless targets
  targets.inject({}) do |hsh,(k,targs)|
    hsh[k] = targs.map(&:to_hash).map(&:compact_blank) ; hsh
  end
end

#to_hashObject



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/icss/protocol.rb', line 168

def to_hash()
  {
    :namespace   => @namespace, # use accessor so unset namespace isn't given
    :protocol    => protocol,
    :license_id  => license_id,
    :credits     => credits,
    :tags        => tags,
    :categories  => categories,
    :doc         => doc,
    :types       => (types       && types.map(&:to_schema)),
    :messages    => messages.inject({}){|h,(k,v)| h[k.to_sym] = v.to_hash; h },
    :data_assets => data_assets.map(&:to_hash).map(&:compact_blank),
    :code_assets => code_assets.map(&:to_hash).map(&:compact_blank),
    :update_frequency    => update_frequency,
    :under_consideration => under_consideration,
    :targets     => targets_to_hash,
  }.reject{|k,v| v.nil? }
end

#to_json(*args) ⇒ Object

This will cause funny errors when it is an element of something that’s to_json’ed



195
# File 'lib/icss/protocol.rb', line 195

def to_json(*args) to_hash.to_json(*args) ; end