class Google::Apis::Core::BatchCommand

Wrapper request for batching multiple calls in a single server request

Constants

MULTIPART_MIXED

Public Class Methods

new(method, url) click to toggle source

@param [symbol] method

HTTP method

@param [String,Addressable::URI, Addressable::Template] url

HTTP URL or template
Calls superclass method
# File lib/google/apis/core/batch.rb, line 48
def initialize(method, url)
  super(method, url)
  @calls = []
  @base_id = SecureRandom.uuid
end

Public Instance Methods

add(call, &block) click to toggle source

Add a new call to the batch request.

@param [Google::Apis::Core::HttpCommand] call API Request to add @yield [result, err] Result & error when response available @return [Google::Apis::Core::BatchCommand] self

# File lib/google/apis/core/batch.rb, line 60
def add(call, &block)
  ensure_valid_command(call)
  @calls << [call, block]
  self
end

Protected Instance Methods

decode_response_body(content_type, body) click to toggle source

Deconstruct the batch response and process the individual results

@param [String] content_type

Content type of body

@param [String, read] body

Response body

@return [Object]

Response object
# File lib/google/apis/core/batch.rb, line 77
def decode_response_body(content_type, body)
  m = /.*boundary=(.+)/.match(content_type)
  if m
    parts = split_parts(body, m[1])
    deserializer = CallDeserializer.new
    parts.each_index do |index|
      response = deserializer.to_http_response(parts[index])
      outer_header = response.shift
      call_id = header_to_id(outer_header['Content-ID'].first) || index
      call, callback = @calls[call_id]
      begin
        result = call.process_response(*response) unless call.nil?
        success(result, &callback)
      rescue => e
        error(e, &callback)
      end
    end
  end
  nil
end
ensure_valid_command(command) click to toggle source
# File lib/google/apis/core/batch.rb, line 123
def ensure_valid_command(command)
  if command.is_a?(Google::Apis::Core::BaseUploadCommand) || command.is_a?(Google::Apis::Core::DownloadCommand) || command.is_a?(Google::Apis::Core::StorageDownloadCommand) || command.is_a?(Google::Apis::Core::StorageUploadCommand)
    fail Google::Apis::ClientError, 'Can not include media requests in batch'
  end
  fail Google::Apis::ClientError, 'Invalid command object' unless command.is_a?(HttpCommand)
end
header_to_id(content_id) click to toggle source
# File lib/google/apis/core/batch.rb, line 134
def header_to_id(content_id)
  match = /<response-.*\+(\d+)>/.match(content_id)
  return match[1].to_i if match
  return nil
end
id_to_header(call_id) click to toggle source
# File lib/google/apis/core/batch.rb, line 130
def id_to_header(call_id)
  return sprintf('<%s+%i>', @base_id, call_id)
end
prepare!() click to toggle source

Encode the batch request @return [void] @raise [Google::Apis::BatchError] if batch is empty

Calls superclass method
# File lib/google/apis/core/batch.rb, line 106
def prepare!
  fail BatchError, 'Cannot make an empty batch request' if @calls.empty?

  serializer = CallSerializer.new
  multipart = Multipart.new(content_type: MULTIPART_MIXED)
  @calls.each_index do |index|
    call, _ = @calls[index]
    content_id = id_to_header(index)
    io = serializer.to_part(call)
    multipart.add_upload(io, content_type: 'application/http', content_id: content_id)
  end
  self.body = multipart.assemble

  header['Content-Type'] = multipart.content_type
  super
end
split_parts(body, boundary) click to toggle source
# File lib/google/apis/core/batch.rb, line 98
def split_parts(body, boundary)
  parts = body.split(/\r?\n?--#{Regexp.escape(boundary)}/)
  parts[1...-1]
end