Class: OnlinePayments::SDK::Communication::DefaultConnection

Inherits:
PooledConnection show all
Defined in:
lib/onlinepayments/sdk/communication/default_connection.rb

Instance Method Summary collapse

Constructor Details

#initialize(args) ⇒ DefaultConnection

Returns a new instance of DefaultConnection.

Parameters:

  • args (Hash)

    the parameters to initialize the connection with

Options Hash (args):

Raises:

  • (ArgumentError)


48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/onlinepayments/sdk/communication/default_connection.rb', line 48

def initialize(args)
  raise ArgumentError unless args.is_a? Hash

  # Set timeouts to nil if they are negative
  @connect_timeout = args[:connect_timeout]
  @connect_timeout = nil unless @connect_timeout.nil? || @connect_timeout > 0
  @socket_timeout = args[:socket_timeout]
  @socket_timeout = nil unless @socket_timeout.nil? || @socket_timeout > 0
  @max_connections = args[:max_connections] || CommunicatorConfiguration.default_max_connections
  @proxy_configuration = args[:proxy_configuration]

  # HTTPClient provides the following features:
  # 1) thread safe, an instance can be used by multiple threads without
  # explicit synchronization
  # 2) use persistent connection if HTTP 1.1 is supported. The connection
  # will be left open until explicitly closed or keep_alive_timeout
  # 3) a built-in connection pool with no limit for max connections
  @http_client = create_http_client
  @http_client.connect_timeout = @connect_timeout
  @http_client.send_timeout = @socket_timeout
  @http_client.receive_timeout = @socket_timeout

  @body_obfuscator = OnlinePayments::SDK::Logging::Obfuscation::BodyObfuscator.default_obfuscator
  @header_obfuscator = OnlinePayments::SDK::Logging::Obfuscation::HeaderObfuscator.default_obfuscator
end

Instance Method Details

#closeObject

Frees all networking resources used.



116
117
118
# File 'lib/onlinepayments/sdk/communication/default_connection.rb', line 116

def close
  @http_client.reset_all
end

#close_expired_connectionsObject

HTTPClient automatically closes expired connections so close_expired_connections is a no-operation.



109
110
111
112
113
# File 'lib/onlinepayments/sdk/communication/default_connection.rb', line 109

def close_expired_connections
  # By default, the keep alive timeout is 15 sec, which is the HTTP 1.1
  # standard. To change the value, use keep_alive_timeout= method
  # do nothing, handled by HTTPClient
end

#close_idle_connections(idle_time) ⇒ Object

Closes all connections idle for longer than idle_time seconds. In addition, the keep_alive_timeout is set to idle_time so any future connections idle for longer than idle_time seconds will also be closed.



102
103
104
105
106
# File 'lib/onlinepayments/sdk/communication/default_connection.rb', line 102

def close_idle_connections(idle_time)
  # in sec
  @http_client.keep_alive_timeout = idle_time # set timeout value
  close_expired_connections
end

#delete(uri, request_headers) ⇒ Object

Performs a DELETE request to the Online Payments platform

See Also:



135
136
137
138
139
# File 'lib/onlinepayments/sdk/communication/default_connection.rb', line 135

def delete(uri, request_headers)
  request('delete', uri, request_headers) do |response_status_code, response_headers, response_body|
    yield response_status_code, response_headers, response_body
  end
end

#disable_loggingObject

Disables logging by unregistering any previous logger that might be registered.



268
269
270
# File 'lib/onlinepayments/sdk/communication/default_connection.rb', line 268

def disable_logging
  @communicator_logger = nil
end

#enable_logging(communicator_logger) ⇒ Object

Enables logging outgoing requests and incoming responses by registering the communicator_logger. Note that only one logger can be registered at a time and calling enable_logging a second time will override the old logger instance with the new one.

Parameters:

Raises:

  • (ArgumentError)


261
262
263
264
265
# File 'lib/onlinepayments/sdk/communication/default_connection.rb', line 261

def enable_logging(communicator_logger)
  raise ArgumentError, 'communicator_logger is required' unless communicator_logger

  @communicator_logger = communicator_logger
end

#get(uri, request_headers) ⇒ Object

Performs a GET request to the Online Payments platform

See Also:



127
128
129
130
131
# File 'lib/onlinepayments/sdk/communication/default_connection.rb', line 127

def get(uri, request_headers)
  request('get', uri, request_headers) do |response_status_code, response_headers, response_body|
    yield response_status_code, response_headers, response_body
  end
end

#post(uri, request_headers, body) ⇒ Object

Performs a POST request to the Online Payments platform

See Also:



143
144
145
146
147
# File 'lib/onlinepayments/sdk/communication/default_connection.rb', line 143

def post(uri, request_headers, body)
  request('post', uri, request_headers, body) do |response_status_code, response_headers, response_body|
    yield response_status_code, response_headers, response_body
  end
end

#put(uri, request_headers, body) ⇒ Object

Performs a PUT request to the Online Payments platform

See Also:



151
152
153
154
155
# File 'lib/onlinepayments/sdk/communication/default_connection.rb', line 151

def put(uri, request_headers, body)
  request('put', uri, request_headers, body) do |response_status_code, response_headers, response_body|
    yield response_status_code, response_headers, response_body
  end
end

#request(method, uri, request_headers, body = nil) {|Integer, Array<OnlinePayments::SDK::Communication::ResponseHeader>, IO| ... } ⇒ Object

Performs a HTTP request and yields the response as the status code, headers and body. Also ensures the request is logged when sent and its response is logged when received.

Parameters:

Yields:

Raises:



166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
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
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/onlinepayments/sdk/communication/default_connection.rb', line 166

def request(method, uri, request_headers, body = nil)
  request_headers = convert_from_sdk_headers(request_headers)
  request_id = SecureRandom.uuid
  content_type = request_headers[CONTENT_TYPE]

  original_body_for_logging = body

  encoding_present = request_headers.keys.any? { |k| k.casecmp(CONTENT_ENCODING).zero? }

  if body.is_a?(String) &&
     content_type && content_type.downcase.start_with?(JSON_CONTENT_TYPE) &&
     encoding_present

    gzip_buffer  = StringIO.new
    gzip = Zlib::GzipWriter.new(gzip_buffer)
    gzip.write(body)
    gzip.close
    body = gzip_buffer.string
  end

  info = { headers: request_headers, content_type: content_type, body: original_body_for_logging }

  log_request(request_id, method.upcase, uri, info)

  start_time = Time.now
  begin
    response_headers = nil
    response_status_code = nil
    response_content_type = nil
    response_body = ''

    if body.is_a? MultipartFormDataObject
      multipart_request(method, uri, request_headers, body) do |status_code, headers, r_content_type, r_body|
        response_headers = headers
        response_status_code = status_code
        response_content_type = r_content_type
        unless binary_content_type? response_content_type
          response_body = r_body.read.force_encoding('UTF-8')
          r_body = StringIO.new(response_body)
        end

        yield status_code, headers, r_body
      end
    else
      raw_request(method, uri, request_headers, body) do |status_code, headers, r_content_type, r_body|
        response_headers = headers
        response_status_code = status_code
        response_content_type = r_content_type
        unless binary_content_type? response_content_type
          response_body = r_body.read.force_encoding('UTF-8')
          r_body = StringIO.new(response_body)
        end

        yield status_code, headers, r_body
      end
    end

    log_response(request_id, response_status_code, start_time,
                 headers: response_headers, body: response_body,
                 content_type: response_content_type)
  rescue HTTPClient::TimeoutError => e
    log_error(request_id, start_time, e)
    raise CommunicationException, e
  rescue HTTPClient::KeepAliveDisconnected, HTTPClient::RetryableResponse => e # retry these?
    log_error(request_id, start_time, e)
    raise CommunicationException, e
  rescue StandardError => e
    log_error(request_id, start_time, e)
    raise CommunicationException, e
  end
end

#session_countObject

Returns the number of open connections



121
122
123
# File 'lib/onlinepayments/sdk/communication/default_connection.rb', line 121

def session_count
  @http_client.session_count
end

#set_body_obfuscator(body_obfuscator) ⇒ Object

Sets the current body obfuscator to use.

Parameters:

Raises:

  • (ArgumentError)


242
243
244
245
246
# File 'lib/onlinepayments/sdk/communication/default_connection.rb', line 242

def set_body_obfuscator(body_obfuscator)
  raise ArgumentError, 'body_obfuscator is required' unless body_obfuscator

  @body_obfuscator = body_obfuscator
end

#set_header_obfuscator(header_obfuscator) ⇒ Object

Sets the current header obfuscator to use.

Parameters:

Raises:

  • (ArgumentError)


250
251
252
253
254
# File 'lib/onlinepayments/sdk/communication/default_connection.rb', line 250

def set_header_obfuscator(header_obfuscator)
  raise ArgumentError, 'header_obfuscator is required' unless header_obfuscator

  @header_obfuscator = header_obfuscator
end