Class: OrangeData::Transport

Inherits:
Object
  • Object
show all
Defined in:
lib/orange_data/transport.rb

Overview

handles low-level http requests to orangedata, including auth

Defined Under Namespace

Classes: CorrectionIntermediateResult, IntermediateResult, ReceiptIntermediateResult, RequestSignatureMiddleware

Constant Summary collapse

DEFAULT_TEST_API_URL =
"https://apip.orangedata.ru:2443/api/v2/"
DEFAULT_PRODUCTION_API_URL =
"https://api.orangedata.ru:12003/api/v2/"

Instance Method Summary collapse

Constructor Details

#initialize(api_url = DEFAULT_TEST_API_URL, credentials = Credentials.default_test) ⇒ Transport

Returns a new instance of Transport.

Raises:

  • (ArgumentError)


15
16
17
18
19
# File 'lib/orange_data/transport.rb', line 15

def initialize(api_url=DEFAULT_TEST_API_URL, credentials=Credentials.default_test)
  raise ArgumentError, "Need full credentials for connection" unless credentials.valid?
  @credentials = credentials
  @api_url = api_url
end

Instance Method Details

#get_correction(inn, document_id) ⇒ Object



189
190
191
# File 'lib/orange_data/transport.rb', line 189

def get_correction(inn, document_id)
  CorrectionResult.from_hash(get_entity("corrections/#{inn}/status/#{document_id}"))
end

#get_document(inn, document_id) ⇒ Object



181
182
183
# File 'lib/orange_data/transport.rb', line 181

def get_document(inn, document_id)
  ReceiptResult.from_hash(get_entity("documents/#{inn}/status/#{document_id}"))
end

#get_entity(sub_url) ⇒ Object



142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/orange_data/transport.rb', line 142

def get_entity(sub_url)
  res = transport.get(sub_url)

  case res.status
  when 200
    return res.body
  when 400
    raise "Cannot get doc: #{res.body['errors'] || res.body}"
  when 401
    raise 'Unauthorized'
  end
end

#pingObject

Below actual methods from api



157
158
159
160
161
162
# File 'lib/orange_data/transport.rb', line 157

def ping
  res = transport.get(''){|r| r.headers['Accept'] = 'text/plain' }
  res.status == 200 && res.body == "Nebula.Api v2"
rescue StandardError => _e
  return false
end

#post_correction(data, raise_errors: true) ⇒ Object



185
186
187
# File 'lib/orange_data/transport.rb', line 185

def post_correction(data, raise_errors:true)
  post_entity 'corrections', data, raise_errors:raise_errors, result_class:CorrectionIntermediateResult
end

#post_document(data, raise_errors: true) ⇒ Object



177
178
179
# File 'lib/orange_data/transport.rb', line 177

def post_document(data, raise_errors:true)
  post_entity 'documents', data, raise_errors:raise_errors, result_class:ReceiptIntermediateResult
end

#post_document_validate(data) ⇒ Object



164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/orange_data/transport.rb', line 164

def post_document_validate(data)
  res = post_request 'validateDocument', data

  case res.status
  when 200
    return true
  when 400
    return res.body["errors"]
  else
    raise "Unexpected response: #{res.status} #{res.reason_phrase}"
  end
end

#post_entity(sub_url, data, raise_errors: true, result_class: IntermediateResult, retry_count: 0) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/orange_data/transport.rb', line 120

def post_entity(sub_url, data, raise_errors:true, result_class:IntermediateResult, retry_count:0)
  res = post_request(sub_url, data)

  case res.status
  when 201
    return result_class.new(success: true, data:data, sub_url:sub_url, retry_count:0, transport:self)
  when 409
    raise "Conflict" if raise_errors
    return result_class.new(data:data, sub_url:sub_url, errors:["Duplicate id"], retry_count:0)
  when 400
    raise "Invalid doc: #{res.body['errors'] || res.body}" if raise_errors
    return result_class.new(data:data, sub_url:sub_url, errors:res.body['errors'], retry_count:0)
  when 503
    if res.headers['Retry-After']
      raise "Document queue full, retry in #{res.headers['Retry-After']}" if raise_errors
      return result_class.new(attempt_retry:true, retry_in:res.headers['Retry-After'].to_i, data:data, sub_url:sub_url, retry_count:0, transport:self)
    end
  end
  raise "Unknown code from OD: #{res.status} #{res.reason_phrase} #{res.body}" if raise_errors
  result_class.new(attempt_retry:true, data:data, sub_url:sub_url, retry_count:0, transport:self)
end

#post_request(method, data) ⇒ Object



58
59
60
61
62
63
64
65
# File 'lib/orange_data/transport.rb', line 58

def post_request(method, data)
  raw_post(method, data).tap{|resp|
    if resp.status == 401
      # TODO: better exceptions
      raise 'Unauthorized'
    end
  }
end

#raw_post(method, data) ⇒ Object



54
55
56
# File 'lib/orange_data/transport.rb', line 54

def raw_post(method, data)
  transport.post(method, data)
end

#transportObject



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/orange_data/transport.rb', line 37

def transport
  @transport ||= Faraday.new(
    url: @api_url,
    ssl: {
      client_cert: @credentials.certificate,
      client_key: @credentials.certificate_key,
    }
  ) do |conn|
    conn.headers['User-Agent'] = "OrangeDataRuby/#{OrangeData::VERSION}"
    conn.headers['Accept'] = "application/json"
    conn.request(:json)
    conn.use(RequestSignatureMiddleware, @credentials.signature_key)
    conn.response :json, content_type: /\bjson$/
    conn.adapter(Faraday.default_adapter)
  end
end