module Angus::Remote::ServiceDirectory

Public Class Methods

api_url(code_name, version = nil) click to toggle source

Returns the api url from the configuration file

@param [String] code_name Name of the service. @param [String] version Version of the service.

If no version given, it reads the version from the configuration file.

@raise (see .service_version)

# File lib/angus/remote/service_directory.rb, line 83
def self.api_url(code_name, version = nil)
  version ||= service_version(code_name)

  config = service_configuration(code_name)

  config["v#{version}"]['api_url']
end
doc_url(code_name, version = nil) click to toggle source

Returns the documentation url from the configuration file

@param [String] code_name Name of the service. @param [String] version Version of the service.

If no version given, it reads the version from the configuration file.

@raise (see .service_version)

# File lib/angus/remote/service_directory.rb, line 54
def self.doc_url(code_name, version = nil)
  version ||= service_version(code_name)

  config = service_configuration(code_name)

  config["v#{version}"]['doc_url']
end
get_service_definition(code_name, version = nil) click to toggle source

Requests a service definition.

@param [String] code_name Service code name @param [String] version Service version

@raise (see .service_version)

@return [Angus::SDoc::Definitions::Service]

# File lib/angus/remote/service_directory.rb, line 166
def self.get_service_definition(code_name, version = nil)
  version ||= service_version(code_name)
  doc_url = self.doc_url(code_name, version)

  if doc_url.match('file://(.*)') || doc_url.match('file:///(.*)')
    Angus::SDoc::DefinitionsReader.service_definition($1)
  else
    definition_hash = fetch_remote_service_definition(doc_url, code_name, version)
    Angus::SDoc::DefinitionsReader.build_service_definition(definition_hash)
  end
end
join_proxy(code_name, version, remote_code_name) click to toggle source

Queries a service for definitions of proxy operations for the given remote service.

Merges those definitions and returns the result.

@param [String] code_name Service that acts as a proxy. @param [String] version Service version. @param [String] remote_code_name Remote service that implements operations for

the proxy service

@return [Angus::SDoc::Definitions::Service]

# File lib/angus/remote/service_directory.rb, line 138
def self.join_proxy(code_name, version, remote_code_name)

  service_definition = self.service_definition(code_name, version)

  @service_definitions_proxies ||= []
  if @service_definitions_proxies.include?([code_name, version, remote_code_name])
    return service_definition
  end

  proxy_doc_url = self.proxy_doc_url(code_name, version, remote_code_name)

  definition_hash = fetch_remote_service_definition(proxy_doc_url, code_name, version)

  proxy_service_definition = Angus::SDoc::DefinitionsReader.build_service_definition(definition_hash)

  service_definition.merge(proxy_service_definition)

  service_definition
end
lookup(*args) click to toggle source

Builds and returns a Client object for the service and version received

# File lib/angus/remote/service_directory.rb, line 17
def self.lookup(*args)
  if args.length == 1
    definition = args.first
    code_name = definition.delete(:code_name)
    version = definition.delete(:version)
    set_service_configuration(code_name, version, definition)
  else
    code_name, version = args
  end

  version ||= service_version(code_name)

  @clients_cache ||= {}
  if @clients_cache.include?([code_name, version])
    return @clients_cache[[code_name, version]]
  end

  begin
    service_definition = self.service_definition(code_name, version)
    client = Angus::Remote::Builder.build(code_name, service_definition,
                                          self.api_url(code_name, version),
                                          service_settings(code_name, version))
    @clients_cache[[code_name, version]] = client

  rescue Errno::ECONNREFUSED => e
    raise RemoteConnectionError.new("#{self.api_url(code_name, version)} - #{e.class}: #{e.message}")
  end
end
proxy_doc_url(code_name, version, remote_code_name) click to toggle source

Returns the documentation url for proxy operations hosted by the service.

@param [String] code_name Service code name. @param [String] version Service version. @param [String] remote_code_name Service which implements proxy operations.

@return [String]

# File lib/angus/remote/service_directory.rb, line 69
def self.proxy_doc_url(code_name, version, remote_code_name)
  doc_url = self.doc_url(code_name, version)

  "#{doc_url}/proxy/#{remote_code_name}"
end
service_definition(code_name, version = nil) click to toggle source

Returns the service’s definition for the given service name and version

@param [String] code_name Service that acts as a proxy. @param [String] version Service version.

@raise (see .service_version)

@return [Angus::SDoc::Definitions::Service]

# File lib/angus/remote/service_directory.rb, line 116
def self.service_definition(code_name, version = nil)
  version ||= service_version(code_name)

  @service_definitions_cache ||= {}
  if @service_definitions_cache.include?([code_name, version])
    return @service_definitions_cache[[code_name, version]]
  end

  service_definition = self.get_service_definition(code_name, version)
  @service_definitions_cache[[code_name, version]] = service_definition
end
service_settings(code_name, version = nil) click to toggle source

Returns the documentation url from the configuration file

@param [String] code_name Name of the service. @param [String] version Version of the service.

If no version given, it reads the version from the configuration file.

@raise (see .service_version)

# File lib/angus/remote/service_directory.rb, line 238
def self.service_settings(code_name, version = nil)
  version ||= service_version(code_name)

  config = service_configuration(code_name)

  service_settings = config["v#{version}"] or
    raise ServiceConfigurationNotFound.new(code_name, version)

  service_settings['code_name'] = code_name
  service_settings['version'] = version

  service_settings
end
service_version(code_name) click to toggle source

Returns the configured version.

@param [String] code_name Service name

@return [String] Version. Ex: 0.1

@raise [TooManyServiceVersions] When there are more than one configured version.

# File lib/angus/remote/service_directory.rb, line 98
def self.service_version(code_name)
  versions = service_configuration(code_name).keys

  if versions.length == 1
    versions.first.gsub(/^v/, '')
  else
    raise TooManyServiceVersions.new(code_name)
  end
end

Private Class Methods

authentication_client(code_name, version) click to toggle source
# File lib/angus/remote/service_directory.rb, line 212
def self.authentication_client(code_name, version)
  @authentication_clients ||= {}

  unless @authentication_clients.include?([code_name, version])
    service_settings = service_settings(code_name, version)

    settings = { :public_key => service_settings['public_key'],
                 :private_key => service_settings['private_key'],
                 :service_id => "#{code_name}.#{version}",
                 :store => Settings.redis.merge({ :namespace => "#{code_name}.#{version}" }) }

    @authentication_clients[[code_name, version]] = Angus::Authentication::Client.new(settings)
  end

  @authentication_clients[[code_name, version]]
end
fetch_remote_service_definition(uri, code_name, version) click to toggle source

Fetches a service definition from a remote http uri.

@param [String] uri URI that publishes a service definition. @param [String] code_name Name of the service. @param [String] version Version of the service.

@return [Hash] Service definition hash

# File lib/angus/remote/service_directory.rb, line 185
def self.fetch_remote_service_definition(uri, code_name, version)
  uri = URI(uri)
  uri.query = URI.encode_www_form({:format => :json})

  connection = Net::HTTP.new(uri.host, uri.port)

  if uri.scheme == 'https'
    connection.use_ssl = true
    connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
  end

  response = connection.start do |http|
    request = Net::HTTP::Get.new(uri.request_uri)

    authentication_client(code_name, version).prepare_request(request, 'GET', uri.path)

    http.request(request)
  end

  authentication_client(code_name, version).store_session_private_key(response)

  JSON(response.body)
rescue Exception => e
  raise RemoteConnectionError.new("#{uri} - #{e.class}: #{e.message}")
end
load_services_configuration_file() click to toggle source
# File lib/angus/remote/service_directory.rb, line 278
def self.load_services_configuration_file
  return {} unless File.exists?(Settings.configuration_file)
  configuration = YAML.load_file(Settings.configuration_file)

  configuration = {} unless configuration.is_a?(Hash)

  configuration
end
service_configuration(code_name) click to toggle source

Returns the connection configuration for a given service.

@param [String] code_name Service name

@return [Hash]

@raise [ServiceConfigurationNotFound] When no configuration for the given service

# File lib/angus/remote/service_directory.rb, line 259
def self.service_configuration(code_name)
  @services_configuration ||= load_services_configuration_file

  @services_configuration[code_name] or
    raise ServiceConfigurationNotFound.new(code_name)
end
set_service_configuration(code_name, version, configuration) click to toggle source
# File lib/angus/remote/service_directory.rb, line 267
def self.set_service_configuration(code_name, version, configuration)
  @services_configuration ||= load_services_configuration_file
  @services_configuration[code_name] ||= {}

  @services_configuration[code_name]["v#{version}"] = configuration.inject({}) do |config, entry|
    k, v = entry
    config.merge!({ k.to_s => v })
  end
end