Class: Occi::Api::Client::ClientAmqp

Inherits:
Object
  • Object
show all
Defined in:
lib/occi/api/client/client_amqp.rb

Constant Summary collapse

CONNECTION_SETTING =
{
    :host => 'localhost', #IP of the MessageBroker (RabbitMQ)
    :port => 5672,
    :vhost => '/' ,
    :password => 'password'
}
HTTP_CODES =

hash mapping HTTP response codes to human-readable messages

{
    "100" => "Continue",
    "101" => "Switching Protocols",
    "200" => "OK",
    "201" => "Created",
    "202" => "Accepted",
    "203" => "Non-Authoritative Information",
    "204" => "No Content",
    "205" => "Reset Content",
    "206" => "Partial Content",
    "300" => "Multiple Choices",
    "301" => "Moved Permanently",
    "302" => "Found",
    "303" => "See Other",
    "304" => "Not Modified",
    "305" => "Use Proxy",
    "307" => "Temporary Redirect",
    "400" => "Bad Request",
    "401" => "Unauthorized",
    "402" => "Payment Required",
    "403" => "Forbidden",
    "404" => "Not Found",
    "405" => "Method Not Allowed",
    "406" => "Not Acceptable",
    "407" => "Proxy Authentication Required",
    "408" => "Request Time-out",
    "409" => "Conflict",
    "410" => "Gone",
    "411" => "Length Required",
    "412" => "Precondition Failed",
    "413" => "Request Entity Too Large",
    "414" => "Request-URI Too Large",
    "415" => "Unsupported Media Type",
    "416" => "Requested range not satisfiable",
    "417" => "Expectation Failed",
    "500" => "Internal Server Error",
    "501" => "Not Implemented",
    "502" => "Bad Gateway",
    "503" => "Service Unavailable",
    "504" => "Gateway Time-out",
    "505" => "HTTP Version not supported"
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Occi::Api::Client::ClientAmqp

Initializes client data structures and retrieves OCCI model from the server.

Examples:

options = {
  :endpoint => "http://localhost:3300/",
  :auth => {:type => "none"},
  :log => {:out => STDERR, :level => Occi::Log::WARN, :logger => nil},
  :media_type => "text/plain"
}

Occi::Api::Client::ClientAmqp.new options # => #<Occi::Api::Client::ClientAmqp>

Parameters:

  • options, (Hash)

    for available options and defaults see examples


81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/occi/api/client/client_amqp.rb', line 81

def initialize(options = {})

  defaults = {
      :endpoint => "http://localhost:3300/",
      :auth => {:type => "none"},
      :log => {:out => STDERR, :level => Occi::Log::WARN, :logger => nil},
      :media_type => "text/plain"
  }

  options = options.marshal_dump if options.is_a? OpenStruct
  options = defaults.merge options

  # check the validity and canonize the endpoint URI
  prepare_endpoint options[:endpoint]

  # set Occi::Log
  set_logger options[:log]

  # pass auth options to HTTParty
  change_auth options[:auth]

  @media_type = options[:media_type]

  Occi::Log.debug("Media Type: #{@media_type}")

  @connected = false

  Thread.new { run }

  Occi::Log.debug("Waiting for connection amqp ...")

  #TODO find a better solution for the thread issue
  while(!@thread_error && !@connected)
    #dont use sleep - it blocks the eventmachine
  end

  # get model information from the endpoint
  # and create Occi::Model instance
  set_model unless @thread_error
end

Instance Attribute Details

#auth_optionsObject (readonly)

Returns the value of attribute auth_options


10
11
12
# File 'lib/occi/api/client/client_amqp.rb', line 10

def auth_options
  @auth_options
end

#connectedObject (readonly)

Returns the value of attribute connected


10
11
12
# File 'lib/occi/api/client/client_amqp.rb', line 10

def connected
  @connected
end

#endpointObject (readonly)

Returns the value of attribute endpoint


10
11
12
# File 'lib/occi/api/client/client_amqp.rb', line 10

def endpoint
  @endpoint
end

#last_response_statusObject (readonly)

Returns the value of attribute last_response_status


10
11
12
# File 'lib/occi/api/client/client_amqp.rb', line 10

def last_response_status
  @last_response_status
end

#media_typeObject

Returns the value of attribute media_type


11
12
13
# File 'lib/occi/api/client/client_amqp.rb', line 11

def media_type
  @media_type
end

#modelObject

Returns the value of attribute model


11
12
13
# File 'lib/occi/api/client/client_amqp.rb', line 11

def model
  @model
end

Instance Method Details

#change_auth(auth_options) ⇒ Object (private)

Sets auth method and appropriate httparty attributes. Supported auth methods are: ["none"] and nil

Examples:

change_auth { :type => "none" }

Parameters:

  • authentication (Hash)

    options


717
718
719
720
721
722
723
724
725
726
# File 'lib/occi/api/client/client_amqp.rb', line 717

def change_auth(auth_options)
  @auth_options = auth_options

  case @auth_options[:type]
    when "none", nil
      # do nothing
    else
      raise ArgumentError, "Unknown AUTH method [#{@auth_options[:type]}]!"
  end
end

#create(entity, is_wait = true, is_parse_response = true) ⇒ Object

Creates a new resource on the server. Resource must be provided as an instance of Occi::Core::Entity, e.g. instantiated using the get_resource method.

Examples:

res = client.get_resource "compute"

res.title = "MyComputeResource1"
res.mixins << client.find_mixin('small', "resource_tpl")
res.mixins << client.find_mixin('debian6', "os_tpl")

client.create res # => "http://localhost:3300/compute/df7698...f987fa"

232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/occi/api/client/client_amqp.rb', line 232

def create(entity, is_wait = true, is_parse_response = true)

  # check some basic pre-conditions
  raise "Endpoint is not connected!" unless @connected
  raise "#{entity} not an entity" unless entity.kind_of? Occi::Core::Entity

  # is this entity valid?
  entity.model = @model
  entity.check
  kind = entity.kind
  raise "No kind found for #{entity}" unless kind

  # get location for this kind of entity
  location   = entity.kind.location
  collection = Occi::Collection.new

  # is this entity a Resource or a Link?
  collection.resources << entity if entity.kind_of? Occi::Core::Resource
  collection.links << entity if entity.kind_of? Occi::Core::Link

  # make the request
  response_value(post(location, collection), is_wait, is_parse_response)
end

#del(path, filter = nil) ⇒ Boolean (private)

Performs DELETE requests and returns True on success.

Examples:

del "/compute/65sf4g65sf4g-sf6g54sf5g-sfgsf32g3" # => true

Parameters:

  • path (String)

    for the DELETE request

  • collection (Occi::Collection)

    of filters (currently NOT used)

Returns:

  • (Boolean)

    status


638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
# File 'lib/occi/api/client/client_amqp.rb', line 638

def del(path, filter=nil)
  # remove the leading slash
  path.gsub!(/\A\//, '')

  options = {
      :routing_key  => @endpoint_queue,
      :content_type => "text/plain",
      :type         => "delete",
      :reply_to     => reply_queue_name,  #queue for response from the rOCCI
      :message_id   => next_message_id,  #Identifier for message so that the client can match the answer from the rOCCI
      :headers => {
          :accept    => @media_type,
          :path_info => "/#{ path }",
          :auth => {
              :type     => "basic",
              :username => "user",
              :password => "mypass",
          },
      }
  }

  publish('', options)

  return options[:message_id]
end

#delete(resource_type_identifier, is_wait = true, is_parse_response = true) ⇒ Boolean

Deletes a resource or all resource of a certain resource type from the server.

Examples:

client.delete "compute" # => true
client.delete "http://schemas.ogf.org/occi/infrastructure#compute" # => true
client.delete "http://localhost:3300/compute/245j42594...98s9df8s9f" # => true

Parameters:

  • resource (String)

    type identifier, type name or location

Returns:

  • (Boolean)

    status


266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
# File 'lib/occi/api/client/client_amqp.rb', line 266

def delete(resource_type_identifier, is_wait = true, is_parse_response = true)
  # convert type to type identifier
  resource_type_identifier = @model.kinds.select {
      |kind| kind.term == resource_type_identifier
  }.first.type_identifier if @model.kinds.select {
      |kind| kind.term == resource_type_identifier
  }.any?

  # check some basic pre-conditions
  raise "Endpoint is not connected!" unless @connected

  if resource_type_identifier.nil? || resource_type_identifier == "/"
    path = "/"
  else
    raise "Unknown resource identifier! #{resource_type_identifier}" unless resource_type_identifier.start_with? @endpoint
    path = sanitize_resource_link(resource_type_identifier)
  end

  # make the request
  response_value(del(path), is_wait, is_parse_response)
end

#describe(resource_type_identifier = nil, is_wait = true, is_parse_response = true) ⇒ Array<Occi::Collection>

identifier or resource location. If no type identifier or location is specified, all available resources in all available resource types will be described.

Examples:

client.describe
 # => [#<Occi::Collection>, #<Occi::Collection>, #<Occi::Collection>]
client.describe "compute"
 # => [#<Occi::Collection>, #<Occi::Collection>, #<Occi::Collection>]
client.describe "http://schemas.ogf.org/occi/infrastructure#compute"
 # => [#<Occi::Collection>, #<Occi::Collection>, #<Occi::Collection>]
client.describe "http://localhost:3300/compute/j5hk1234jk2524-2j3j2k34jjh234-adfaf1234"
 # => [#<Occi::Collection>]

Parameters:

  • resource (String)

    type identifier, type name or resource location

Returns:


184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/occi/api/client/client_amqp.rb', line 184

def describe(resource_type_identifier=nil, is_wait = true, is_parse_response = true)

  raise "Endpoint is not connected!" unless @connected

  # convert type to type identifier
  resource_type_identifier = @model.kinds.select {
      |kind| kind.term == resource_type_identifier
  }.first.type_identifier if @model.kinds.select {
      |kind| kind.term == resource_type_identifier
  }.any?

  descriptions = []

  if resource_type_identifier.nil?
    descriptions << response_value(get('/'), is_wait, is_parse_response)
  elsif @model.get_by_id resource_type_identifier
    # we got type identifier
    # get all available resources of this type
    locations     = list resource_type_identifier

    # make the requests
    locations.each do |location|
      descriptions << response_value(get(sanitize_resource_link(location)), is_wait, is_parse_response)
    end
  elsif resource_type_identifier.start_with? @endpoint
    # we got resource link
    # make the request
    descriptions << response_value(get(sanitize_resource_link(resource_type_identifier)), is_wait, is_parse_response)
  else
    raise "Unkown resource type identifier! [#{resource_type_identifier}]"
  end

  descriptions
end

#find_mixin(name, type = nil, describe = false) ⇒ String, ...

Looks up a mixin using its name and, optionally, a type as well. Will return mixin's full location (a link) or a description.

Examples:

client.find_mixin "debian6"
 # => "http://my.occi.service/occi/infrastructure/os_tpl#debian6"
client.find_mixin "debian6", "os_tpl"
 # => "http://my.occi.service/occi/infrastructure/os_tpl#debian6"
client.find_mixin "large", "resource_tpl"
 # => "http://my.occi.service/occi/infrastructure/resource_tpl#large"
client.find_mixin "debian6", "resource_tpl" # => nil

Parameters:

  • name (String)

    of the mixin

  • type (String) (defaults to: nil)

    of the mixin

  • should (Boolean)

    we describe the mixin or return its link?

Returns:


365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
# File 'lib/occi/api/client/client_amqp.rb', line 365

def find_mixin(name, type = nil, describe = false)

  Occi::Log.debug("Looking for mixin #{name} + #{type} + #{describe}")

  # is type valid?
  if type
    raise "Unknown mixin type! [#{type}]" unless @mixins.has_key? type.to_sym
  end

  # TODO: extend this code to support multiple matches and regex filters
  # should we look for links or descriptions?
  if describe
    # we are looking for descriptions
    if type
      # get the first match from either os_tpls or resource_tpls
      case
        when type == "os_tpl"
          get_os_templates.select { |mixin| mixin.term == name }.first
        when type == "resource_tpl"
          get_resource_templates.select { |template| template.term == name }.first
        else
          nil
      end
    else
      # try in os_tpls first
      found = get_os_templates.select { |os| os.term == name }.first

      # then try in resource_tpls
      found = get_resource_templates.select {
          |template| template.term == name
      }.first unless found

      found
    end
  else
    # we are looking for links
    # prefix mixin name with '#' to simplify the search
    name = "#" + name
    if type
      # return the first match with the selected type
      @mixins[type.to_sym].select {
          |mixin| mixin.to_s.reverse.start_with? name.reverse
      }.first
    else
      # there is no type preference, return first global match
      @mixins.flatten(2).select {
          |mixin| mixin.to_s.reverse.start_with? name.reverse
      }.first
    end
  end
end

#get(path = '', is_uri_list = false, filter = nil) ⇒ Object (private)

TODO filter


574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
# File 'lib/occi/api/client/client_amqp.rb', line 574

def get(path='', is_uri_list = false, filter=nil)
  raise "OCCI AMQP is not connected!" if !@connected

  options = {
      :routing_key  => @endpoint_queue,
      :type         => "get",
      :content_type => "text/plain",
      :reply_to     => reply_queue_name,
      :message_id   => next_message_id,
      :headers => {
          :accept    => is_uri_list ? "text/uri-list" : @media_type,
          :path_info => "/" + path.gsub(/\A\//, '')
      }
  }

  publish('', options)

  return options[:message_id]
end

#get_os_templatesOcci::Collection

Retrieves available os_tpls from the model.

Examples:

get_os_templates # => #<Occi::Collection>

Returns:


452
453
454
# File 'lib/occi/api/client/client_amqp.rb', line 452

def get_os_templates
  @model.get.mixins.select { |mixin| mixin.related.select { |rel| rel.end_with? 'os_tpl' }.any? }
end

#get_resource(resource_type) ⇒ Occi::Core::Resource

Creates a new resource instance, resource should be specified by its name or identifier.

Examples:

client.get_resource "compute" # => Occi::Core::Resource
client.get_resource "storage" # => Occi::Core::Resource
client.get_resource "http://schemas.ogf.org/occi/infrastructure#network"
 # => Occi::Core::Resource

Parameters:

  • resource (String)

    name or resource identifier

Returns:


428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
# File 'lib/occi/api/client/client_amqp.rb', line 428

def get_resource(resource_type)

  Occi::Log.debug("Instantiating #{resource_type} ...")

  if @model.get_by_id resource_type
    # we got a resource type identifier
    Occi::Core::Resource.new resource_type
  elsif @model.kinds.select { |kind| kind.term == resource_type }.any?
    # we got a resource type name
    Occi::Core::Resource.new @model.kinds.select {
        |kind| kind.term == resource_type
    }.first.type_identifier
  else
    raise "Unknown resource type! [#{resource_type}]"
  end

end

#get_resource_templatesOcci::Collection

Retrieves available resource_tpls from the model.

Examples:

get_resource_templates # => #<Occi::Collection>

Returns:

  • (Occi::Collection)

    collection containing all registered resource templates


462
463
464
# File 'lib/occi/api/client/client_amqp.rb', line 462

def get_resource_templates
  @model.get.mixins.select { |mixin| mixin.related.select { |rel| rel.end_with? 'resource_tpl' }.any? }
end

#handle_channel_exception(channel, channel_close) ⇒ Object (private)


728
729
730
# File 'lib/occi/api/client/client_amqp.rb', line 728

def handle_channel_exception(channel, channel_close)
  Occi::Log.error "OCCI/AMQP: Channel-level exception [ code = #{channel_close.reply_code}, message = #{channel_close.reply_text} ]"
end

#handle_message(metadata, payload) ⇒ Object (private)


519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
# File 'lib/occi/api/client/client_amqp.rb', line 519

def handle_message(, payload)

  correlation_id = .correlation_id

  unless correlation_id.size > 0
    raise "Message has no correlation_id (message_id)"
  end

  @response_messages = Hash.new                             if @response_messages.nil?
  raise "Double Response Message ID: (#{ correlation_id })" if @response_messages.has_key?(correlation_id)

  #save responses message
  @response_messages[correlation_id] = {:payload => payload, :metadata => , :type => @response_waiting[correlation_id][:options][:type]}

  #delete message_id from waiting stack
  @response_waiting.delete(correlation_id) unless @response_waiting.nil?
end

#list(resource_type_identifier = nil, is_wait = true, is_parse_response = true) ⇒ Array<String>

If no type identifier is specified, all available resource are listed. Type identifier can be specified in its shortened format (e.g. "compute", "storage", "network").

Examples:

client.list
 # => [ "http://localhost:3300/compute/jh425jhj3h413-7dj29d7djd9e3-djh2jh4j4j",
 #      "http://localhost:3300/network/kh425jhj3h413-7dj29d7djd9e3-djh2jh4j4j",
 #      "http://localhost:3300/storage/lh425jhj3h413-7dj29d7djd9e3-djh2jh4j4j" ]
client.list "compute"
 # => [ "http://localhost:3300/compute/jh425jhj3h413-7dj29d7djd9e3-djh2jh4j4j" ]
client.list "http://schemas.ogf.org/occi/infrastructure#compute"
 # => [ "http://localhost:3300/compute/jh425jhj3h413-7dj29d7djd9e3-djh2jh4j4j" ]

Parameters:

  • resource (String)

    type identifier or just type name

Returns:

  • (Array<String>)

    list of links


139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/occi/api/client/client_amqp.rb', line 139

def list(resource_type_identifier = nil, is_wait = true, is_parse_response = true)

  if resource_type_identifier
    # convert type to type identifier
    resource_type_identifier = @model.kinds.select {
        |kind| kind.term == resource_type_identifier
    }.first.type_identifier if @model.kinds.select {
        |kind| kind.term == resource_type_identifier
    }.any?

    # check some basic pre-conditions
    raise "Endpoint is not connected!" unless @connected
    raise "Unkown resource type identifier! [#{resource_type_identifier}]" unless @model.get_by_id resource_type_identifier

    # split the type identifier and get the most important part
    uri_part = resource_type_identifier.split('#').last

    # request uri-list from the server
    path = uri_part + '/'
  else
    path = '/'
  end

  message_id = get(path, true)

  return response_value(message_id, is_wait, is_parse_response)
end

#next_message_idObject (private)


704
705
706
707
708
# File 'lib/occi/api/client/client_amqp.rb', line 704

def next_message_id
  @message_id  = 0 if @message_id.nil?
  @message_id += 1
  @message_id.to_s;
end

#parse_delete(payload, metadata) ⇒ Object (private)


496
497
498
# File 'lib/occi/api/client/client_amqp.rb', line 496

def parse_delete(payload, )
  return true
end

#parse_get(payload, metadata) ⇒ Object (private)


480
481
482
483
484
485
486
487
488
489
490
# File 'lib/occi/api/client/client_amqp.rb', line 480

def parse_get(payload, )
  if .content_type == "text/uri-list"
    return payload.split("\n")
  else
    path = .headers["path_info"]
    kind = @model.get_by_location(('/' + path).match(/\/.*\//).to_s) if @model
    kind ? entity_type = kind.entity_type : entity_type = nil
    collection = Occi::Parser.parse(.content_type, payload, path.include?("/-/"), entity_type)
    return collection
  end
end

#parse_message(message_id, delete_response = true) ⇒ Object


327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
# File 'lib/occi/api/client/client_amqp.rb', line 327

def parse_message(message_id, delete_response = true)
  raise "message is empty for message_id(#{ message_id })" if @response_messages.nil? || @response_messages[message_id].nil?

  payload  = @response_messages[message_id][:payload]
  type     = @response_messages[message_id][:type]
   = @response_messages[message_id][:metadata]

  @last_response_status = .headers["status_code"]

  @response_messages.delete(message_id) if delete_response

  raise "OCCI-Server raise error: #{ payload } server status: #{ @last_response_status }" if .headers["is_error"]

  begin
    return method("parse_#{ type }").call(payload, )
  rescue Exception => e
    error_msg = e.message + "\n" + e.backtrace.to_s
    Occi::Log.error error_msg
    raise "Can not parse #{ type } payload: #{ payload } metadata: #{ .inspect }"
  end
end

#parse_post(payload, metadata) ⇒ Object (private)


492
493
494
# File 'lib/occi/api/client/client_amqp.rb', line 492

def parse_post(payload, )
  return URI.parse(payload).to_s
end

#post(path, collection = nil) ⇒ Object (private)

Parameters:

  • path (String)

    path to the resource

  • collection (OCCI::Collection) (defaults to: nil)

597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
# File 'lib/occi/api/client/client_amqp.rb', line 597

def post(path, collection=nil)
  path       = path.reverse.chomp('/').reverse

  if @media_type == 'application/occi+json'
    message = collection.to_json
    content_type = 'application/occi+json'
  else
    message = collection.to_text
    content_type = 'text/plain'
  end

  options = {
      :routing_key  => @endpoint_queue,
      :content_type => content_type,
      :type         => "post",
      :reply_to     => reply_queue_name,  #queue for response from the rOCCI
      :message_id   => next_message_id,  #Identifier for message so that the client can match the answer from the rOCCI
      :headers => {
          :accept    => "text/uri-list",
          :path_info => "/#{ path }",
          :auth => {
              :type     => "basic",
              :username => "user",
              :password => "mypass",
          },
      }
  }

  publish(message, options)

  return options[:message_id]
end

#prepare_endpoint(endpoint) ⇒ String (private)

Checks whether the given endpoint URI is valid and adds a trailing slash if necessary.

Examples:

prepare_endpoint "http://localhost:3300" # => "http://localhost:3300/"

Parameters:

  • endpoint (String)

    URI in a non-canonical string

Returns:

  • (String)

    canonical endpoint URI in a string, with a trailing slash


756
757
758
759
760
761
# File 'lib/occi/api/client/client_amqp.rb', line 756

def prepare_endpoint(endpoint)
  raise 'Endpoint not a valid URI' if (endpoint =~ URI::ABS_URI).nil?

  @endpoint       = endpoint.chomp('/') + '/'
  @endpoint_queue = "amqp.occi.#{@endpoint}"
end

#publish(message, options = {}) ⇒ Object (private)


691
692
693
694
695
696
697
698
# File 'lib/occi/api/client/client_amqp.rb', line 691

def publish(message, options = {})
  raise "No Message Id found" if options[:message_id] == nil?

  @exchange.publish(message, options)

  @response_waiting                       = Hash.new if @response_waiting.nil?
  @response_waiting[options[:message_id]] = {:options => options, :message => message}
end

#refreshObject

Refreshes the Occi::Model used inside the client. Useful for updating the model without creating a new instance or reconnecting. Saves a lot of time in an interactive mode.

Examples:

client.refresh

472
473
474
475
# File 'lib/occi/api/client/client_amqp.rb', line 472

def refresh
  # re-download the model from the server
  set_model
end

#reply_queue_nameObject (private)


700
701
702
# File 'lib/occi/api/client/client_amqp.rb', line 700

def reply_queue_name
  @replies_queue.name
end

#response_value(message_id, is_wait = true, is_parse_response = true) ⇒ Object (private)


664
665
666
667
668
669
670
671
672
673
674
# File 'lib/occi/api/client/client_amqp.rb', line 664

def response_value(message_id, is_wait = true, is_parse_response = true)
  waiting_for_response(message_id) if is_wait || is_parse_response

  if is_parse_response
    value = parse_message(message_id)
  else
    value = message_id
  end

  return value
end

#runObject (private)


500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
# File 'lib/occi/api/client/client_amqp.rb', line 500

def run
  begin
    AMQP.start(CONNECTION_SETTING) do |connection, open_ok|
      @channel  = AMQP::Channel.new(connection)
      @exchange = @channel.default_exchange

      @channel.on_error(&method(:handle_channel_exception))

      @replies_queue = @channel.queue(Time.now.to_f.to_s + Kernel.rand().to_s, :exclusive => true)
      @replies_queue.subscribe(&method(:handle_message))

      @connected = true;
    end
  rescue Exception => e
    @thread_error = true
    Occi::Log.error "Amqp Thread get an Error: #{e.message} \n #{e.backtrace.join("\n")}"
  end
end

Extracts the resource path from a resource link. It will remove the leading @endpoint and replace it with a slash.

Examples:

sanitize_resource_link "http://localhost:3300/compute/35ad4f45gsf-gsfg524s6gsfg-sfgsf4gsfg"
 # => "/compute/35ad4f45gsf-gsfg524s6gsfg-sfgsf4gsfg"

Parameters:

  • string (String)

    containing the full resource link

Returns:

  • (String)

    extracted path, with a leading slash


567
568
569
570
571
# File 'lib/occi/api/client/client_amqp.rb', line 567

def sanitize_resource_link(resource_link)
  raise "Resource link #{resource_link} is not valid!" unless resource_link.start_with? @endpoint

  resource_link.gsub @endpoint, '/'
end

#set_logger(log_options) ⇒ Object (private)

Sets the logger and log levels. This allows users to pass existing logger instances to the rOCCI client.

Examples:

set_logger { :out => STDERR, :level => Occi::Log::WARN, :logger => nil }

Parameters:

  • logger (Hash)

    options


739
740
741
742
743
744
745
746
# File 'lib/occi/api/client/client_amqp.rb', line 739

def set_logger(log_options)
  if log_options[:logger].nil? or (not log_options[:logger].kind_of? Occi::Log)
    logger       = Occi::Log.new(log_options[:out])
    logger.level = log_options[:level]
  end

  self.class.debug_output $stderr if log_options[:level] == Occi::Log::DEBUG
end

#set_modelObject (private)


537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
# File 'lib/occi/api/client/client_amqp.rb', line 537

def set_model
  collection = response_value(get('/-/'))
  @model     = Occi::Model.new(collection)

  @mixins = {
      :os_tpl => [],
      :resource_tpl => [],
      :simulation => []
  }

  #
  get_os_templates.each do |os_tpl|
    @mixins[:os_tpl] << os_tpl.type_identifier unless os_tpl.nil? or os_tpl.type_identifier.nil?
  end

  #
  get_resource_templates.each do |res_tpl|
    @mixins[:resource_tpl] << res_tpl.type_identifier unless res_tpl.nil? or res_tpl.type_identifier.nil?
  end
end

#trigger(resource_type_identifier, action, is_wait = true, is_parse_response = true) ⇒ String

Triggers given action on a specific resource.

Examples:

TODO: add examples

Parameters:

  • resource (String)

    location

  • type (String)

    of action

Returns:

  • (String)

    resource location


296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
# File 'lib/occi/api/client/client_amqp.rb', line 296

def trigger(resource_type_identifier, action, is_wait = true, is_parse_response = true)

  # TODO: not tested
  resource_type_identifier = @model.kinds.select {
      |kind| kind.term == resource_type_identifier
  }.first.type_identifier if @model.kinds.select {
      |kind| kind.term == resource_type_identifier
  }.any?

  # check some basic pre-conditions
  raise "Endpoint is not connected!" unless @connected

  if resource_type_identifier.nil? || resource_type_identifier == "/"
    path = "/"
  else
    raise "Unknown resource identifier! #{resource_type_identifier}" unless resource_type_identifier.start_with? @endpoint
    path = sanitize_resource_link(resource_type_identifier)
  end

  # encapsulate the acion in a collection
  collection   = Occi::Collection.new
  scheme, term = action.split('#')
  collection.actions << Occi::Core::Action.new(scheme + '#', term)

  #@media_type = "text/plain"

  # make the request
  path =  path + '?action=' + term
  response_value(post(path, collection))
end

#waiting_for_response(message_id = '') ⇒ Object (private)

Parameters:

  • message_id (String) (defaults to: '')

    '' == all


677
678
679
680
681
682
683
684
685
686
687
688
689
# File 'lib/occi/api/client/client_amqp.rb', line 677

def waiting_for_response(message_id = '')
  return if @response_waiting.nil?

  if message_id.size > 0
    while !@response_waiting[message_id].nil?
      sleep(0.1)
    end
  else
    while size(@response_waiting) > 0
      sleep(0.1)
    end
  end
end