class Scalaroid::JSONConnection

Abstracts connections to Scalaris using JSON

Public Class Methods

check_fail_abort(result) click to toggle source

Processes the result of some Scalaris operation and raises a TimeoutError if found.

result: {‘status’: ‘ok’} or

{'status': 'fail', 'reason': 'timeout'}
# File lib/scalaroid/json_connection.rb, line 77
def self.check_fail_abort(result)
  if result == {:status => 'fail', :reason => 'timeout'}
    raise TimeoutError.new(result)
  end
end
create_delete_result(result) click to toggle source

Creates a new DeleteResult from the given result list.

result: [‘ok’ or ‘locks_set’ or ‘undef’]

# File lib/scalaroid/json_connection.rb, line 293
def self.create_delete_result(result)
  ok = 0
  locks_set = 0
  undefined = 0
  if result.is_a?(Array)
    for element in result
      if element == 'ok'
          ok += 1
      elsif element == 'locks_set'
          locks_set += 1
      elsif element == 'undef'
          undefined += 1
      else
        raise UnknownError.new(:'Unknown reason ' + element + :'in ' + result)
      end
    end
    return DeleteResult.new(ok, locks_set, undefined)
  end
  raise UnknownError.new(:'Unknown result ' + result)
end
decode_value(value) click to toggle source

Decodes the value from the Scalaris JSON API form to a native type

# File lib/scalaroid/json_connection.rb, line 61
def self.decode_value(value)
  if not (value.has_key?('type') and value.has_key?('value'))
    raise ConnectionError.new(value)
  end
  if value['type'] == 'as_bin'
    return Base64.decode64(value['value'])
  else
    return value['value']
  end
end
encode_value(value, binary = false) click to toggle source

Encodes the value to the form required by the Scalaris JSON API

# File lib/scalaroid/json_connection.rb, line 52
def self.encode_value(value, binary = false)
  if binary
    return { :type => :as_bin, :value => Base64.encode64(value) }
  else
    return { :type => :as_is, :value => value }
  end
end
new(url = DEFAULT_URL, timeout = nil) click to toggle source

Creates a JSON connection to the given URL using the given TCP timeout (or default)

# File lib/scalaroid/json_connection.rb, line 5
def initialize(url = DEFAULT_URL, timeout = nil)
  begin
    @uri = URI.parse(url)
    @timeout = timeout
    start
  rescue Exception => error
    raise ConnectionError.new(error)
  end
end
new_req_list_t(other = nil) click to toggle source

Returns a new ReqList object allowing multiple parallel requests for the Transaction class.

# File lib/scalaroid/json_connection.rb, line 354
def self.new_req_list_t(other = nil)
  JSONReqListTransaction.new(other)
end
new_req_list_tso(other = nil) click to toggle source

Returns a new ReqList object allowing multiple parallel requests for the TransactionSingleOp class.

# File lib/scalaroid/json_connection.rb, line 360
def self.new_req_list_tso(other = nil)
  JSONReqListTransactionSingleOp.new(other)
end
process_result_add_del_on_list(result) click to toggle source

Processes the result of a add_del_on_list operation. Raises the appropriate exception if the operation failed.

results: {‘status’: ‘ok’} or

{'status': 'fail', 'reason': 'timeout' or 'not_a_list'}
# File lib/scalaroid/json_connection.rb, line 146
def self.process_result_add_del_on_list(result)
  if result.is_a?(Hash) and result.has_key?('status')
    if result == {'status' => 'ok'}
      return nil
    elsif result['status'] == 'fail' and result.has_key?('reason')
      if result.length == 2
        if result['reason'] == 'timeout'
          raise TimeoutError.new(result)
        elsif result['reason'] == 'not_a_list'
          raise NotAListError.new(result)
        end
      end
    end
  end
  raise UnknownError.new(result)
end
process_result_add_on_nr(result) click to toggle source

Processes the result of a add_on_nr operation. Raises the appropriate exception if the operation failed.

results: {‘status’: ‘ok’} or

{'status': 'fail', 'reason': 'timeout' or 'not_a_number'}
# File lib/scalaroid/json_connection.rb, line 168
def self.process_result_add_on_nr(result)
  if result.is_a?(Hash) and result.has_key?('status')
    if result == {'status' => 'ok'}
      return nil
    elsif result['status'] == 'fail' and result.has_key?('reason')
      if result.length == 2
        if result['reason'] == 'timeout'
          raise TimeoutError.new(result)
        elsif result['reason'] == 'not_a_number'
          raise NotANumberError.new(result)
        end
      end
    end
  end
  raise UnknownError.new(result)
end
process_result_commit(result) click to toggle source

Processes the result of a commit operation. Raises the appropriate exception if the operation failed.

result: {‘status’ => ‘ok’} or

{'status' => 'fail', 'reason' => 'abort', 'keys' => <list>} or
{'status' => 'fail', 'reason' => 'timeout'}
# File lib/scalaroid/json_connection.rb, line 126
def self.process_result_commit(result)
  if result.is_a?(Hash) and result.has_key?('status')
    if result == {'status' => 'ok'}
      return true
    elsif result['status'] == 'fail' and result.has_key?('reason')
      if result.length == 2 and result['reason'] == 'timeout'
        raise TimeoutError.new(result)
      elsif result.length == 3 and result['reason'] == 'abort' and result.has_key?('keys')
        raise AbortError.new(result, result['keys'])
      end
    end
  end
  raise UnknownError.new(result)
end
process_result_delete(result) click to toggle source

Processes the result of a delete operation. Returns an Array of {:success => true | :timeout, :ok => <number of deleted items>, :results => <detailed results>} on success. Does not raise an exception if the operation failed unless the result is invalid!

results: {‘ok’: xxx, ‘results’: [‘ok’ or ‘locks_set’ or ‘undef’]} or

{'failure': 'timeout', 'ok': xxx, 'results': ['ok' or 'locks_set' or 'undef']}
# File lib/scalaroid/json_connection.rb, line 275
def self.process_result_delete(result)
  if result.is_a?(Hash) and result.has_key?('ok') and result.has_key?('results')
    if not result.has_key?('failure')
      return {:success => true,
        :ok => result['ok'],
        :results => result['results']}
    elsif result['failure'] == 'timeout'
      return {:success => :timeout,
        :ok => result['ok'],
        :results => result['results']}
    end
  end
  raise UnknownError.new(result)
end
process_result_get_subscribers(result) click to toggle source

Processes the result of a get_subscribers operation. Returns the list of subscribers on success. Raises the appropriate exception if the operation failed.

results: [urls=str()]

# File lib/scalaroid/json_connection.rb, line 259
def self.process_result_get_subscribers(result)
  if result.is_a?(Array)
    return result
  end
  raise UnknownError.new(result)
end
process_result_nop(result) click to toggle source

Processes the result of a nop operation. Raises the appropriate exception if the operation failed.

result: ‘ok’

# File lib/scalaroid/json_connection.rb, line 346
def self.process_result_nop(result)
  if result != 'ok'
    raise UnknownError.new(result)
  end
end
process_result_publish(result) click to toggle source

Processes the result of a publish operation. Raises the appropriate exception if the operation failed.

results: {‘status’: ‘ok’}

# File lib/scalaroid/json_connection.rb, line 214
def self.process_result_publish(result)
  if result == {'status' => 'ok'}
    return nil
  end
  raise UnknownError.new(result)
end
process_result_read(result) click to toggle source

Processes the result of a read operation. Returns the read value on success. Raises the appropriate exception if the operation failed.

result: {‘status’ => ‘ok’, ‘value’: xxx} or

{'status' => 'fail', 'reason' => 'timeout' or 'not_found'}
# File lib/scalaroid/json_connection.rb, line 89
def self.process_result_read(result)
  if result.is_a?(Hash) and result.has_key?('status') and result.length == 2
    if result['status'] == 'ok' and result.has_key?('value')
      return decode_value(result['value'])
    elsif result['status'] == 'fail' and result.has_key?('reason')
      if result['reason'] == 'timeout'
        raise TimeoutError.new(result)
      elsif result['reason'] == 'not_found'
        raise NotFoundError.new(result)
      end
    end
  end
  raise UnknownError.new(result)
end
process_result_req_list_t(result) click to toggle source

Processes the result of a req_list operation of the Transaction class. Returns the Array (:tlog => <tlog>, :result => <result>) on success. Raises the appropriate exception if the operation failed.

results: {‘tlog’: xxx,

'results': [{'status': 'ok'} or {'status': 'ok', 'value': xxx} or
            {'status': 'fail', 'reason': 'timeout' or 'abort' or 'not_found'}]}
# File lib/scalaroid/json_connection.rb, line 321
def self.process_result_req_list_t(result)
  if (not result.has_key?('tlog')) or (not result.has_key?('results')) or
      (not result['results'].is_a?(Array))
    raise UnknownError.new(result)
  end
  {:tlog => result['tlog'], :result => result['results']}
end
process_result_req_list_tso(result) click to toggle source

Processes the result of a req_list operation of the TransactionSingleOp class. Returns <result> on success. Raises the appropriate exception if the operation failed.

results: [{‘status’: ‘ok’} or {‘status’: ‘ok’, ‘value’: xxx} or

{'status': 'fail', 'reason': 'timeout' or 'abort' or 'not_found'}]
# File lib/scalaroid/json_connection.rb, line 335
def self.process_result_req_list_tso(result)
  if not result.is_a?(Array)
    raise UnknownError.new(result)
  end
  result
end
process_result_subscribe(result) click to toggle source

Processes the result of a subscribe operation. Raises the appropriate exception if the operation failed.

results: {‘status’: ‘ok’} or

{'status': 'fail', 'reason': 'timeout' or 'abort'}
# File lib/scalaroid/json_connection.rb, line 226
def self.process_result_subscribe(result)
  process_result_commit(result)
end
process_result_test_and_set(result) click to toggle source

Processes the result of a test_and_set operation. Raises the appropriate exception if the operation failed.

results: {‘status’ => ‘ok’} or

{'status' => 'fail', 'reason' => 'timeout' or 'not_found'} or
{'status' => 'fail', 'reason' => 'key_changed', 'value': xxx}
# File lib/scalaroid/json_connection.rb, line 191
def self.process_result_test_and_set(result)
  if result.is_a?(Hash) and result.has_key?('status')
    if result == {'status' => 'ok'}
      return nil
    elsif result['status'] == 'fail' and result.has_key?('reason')
      if result.length == 2
        if result['reason'] == 'timeout'
          raise TimeoutError.new(result)
        elsif result['reason'] == 'not_found'
          raise NotFoundError.new(result)
        end
      elsif result['reason'] == 'key_changed' and result.has_key?('value') and result.length == 3
        raise KeyChangedError.new(result, decode_value(result['value']))
      end
    end
  end
  raise UnknownError.new(result)
end
process_result_unsubscribe(result) click to toggle source

Processes the result of a unsubscribe operation. Raises the appropriate exception if the operation failed.

results: {‘status’: ‘ok’} or

{'status': 'fail', 'reason': 'timeout' or 'abort' or 'not_found'}
# File lib/scalaroid/json_connection.rb, line 235
def self.process_result_unsubscribe(result)
  if result == {'status' => 'ok'}
    return nil
  elsif result.is_a?(Hash) and result.has_key?('status')
    if result['status'] == 'fail' and result.has_key?('reason')
      if result.length == 2
        if result['reason'] == 'timeout'
          raise TimeoutError.new(result)
        elsif result['reason'] == 'not_found'
          raise NotFoundError.new(result)
        end
      elsif result.length == 3 and result['reason'] == 'abort' and result.has_key?('keys')
        raise AbortError.new(result, result['keys'])
      end
    end
  end
  raise UnknownError.new(result)
end
process_result_write(result) click to toggle source

Processes the result of a write operation. Raises the appropriate exception if the operation failed.

result: {‘status’ => ‘ok’} or

{'status' => 'fail', 'reason' => 'timeout'}
# File lib/scalaroid/json_connection.rb, line 109
def self.process_result_write(result)
  if result.is_a?(Hash)
    if result == {'status' => 'ok'}
      return true
    elsif result == {'status' => 'fail', 'reason' => 'timeout'}
      raise TimeoutError.new(result)
    end
  end
  raise UnknownError.new(result)
end

Public Instance Methods

call(function, params) click to toggle source

Calls the given function with the given parameters via the JSON interface of Scalaris.

# File lib/scalaroid/json_connection.rb, line 27
def call(function, params)
  start
  req = Net::HTTP::Post.new(DEFAULT_PATH)
  req.add_field('Content-Type', 'application/json; charset=utf-8')
  req.body = URI::encode({
    :jsonrpc => :'2.0',
    :method => function,
    :params => params,
    :id => 0 }.to_json({:ascii_only => true}))
  begin
    res = @conn.request(req)
    if res.is_a?(Net::HTTPSuccess)
      data = res.body
      return JSON.parse(data)['result']
    else
      raise ConnectionError.new(res)
    end
  rescue ConnectionError => error
    raise error
  rescue Exception => error
    raise ConnectionError.new(error)
  end
end
close() click to toggle source
# File lib/scalaroid/json_connection.rb, line 364
def close
  if @conn.started?
    @conn.finish()
  end
end

Private Instance Methods

start() click to toggle source
# File lib/scalaroid/json_connection.rb, line 15
def start
  if @conn == nil or not @conn.started?
    @conn = Net::HTTP.start(@uri.host, @uri.port)
    unless @timeout.nil?
      @conn.read_timeout = @timeout
    end
  end
end