requester.rb 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. module Sequencer::Unit::Import::Kayako::Requester
  3. mattr_accessor :session_id
  4. def request(api_path:, params: nil, attachment: false)
  5. 10.times do |iteration|
  6. response = perform_request(
  7. api_path: api_path,
  8. params: params,
  9. )
  10. if response.is_a? Net::HTTPOK
  11. refresh_session_id(response) if !attachment
  12. return response
  13. end
  14. handle_error response, iteration
  15. rescue => e
  16. handle_exception e, iteration
  17. end
  18. nil
  19. end
  20. def handle_error(response, iteration)
  21. reset_session_id if response.is_a? Net::HTTPUnauthorized
  22. sleep_for = 10
  23. case response
  24. when Net::HTTPTooManyRequests
  25. sleep_for = response.header['retry-after'].to_i + 10
  26. logger.info "Rate limit: #{response.header.to_hash} (429 Too Many Requests). Sleeping #{sleep_for} seconds and retry (##{iteration + 1}/10)."
  27. else
  28. logger.info "Unknown response: #{response.inspect}. Sleeping 10 seconds and retry (##{iteration + 1}/10)."
  29. end
  30. sleep sleep_for
  31. end
  32. def handle_exception(e, iteration)
  33. logger.error e
  34. logger.info "Sleeping 10 seconds after #{e.class.name} and retry (##{iteration + 1}/10)."
  35. sleep 10
  36. end
  37. def refresh_session_id(response)
  38. return if response.header['content-type'] != 'application/json'
  39. body = JSON.parse(response.body)
  40. return if body['session_id'].blank?
  41. self.session_id = body['session_id']
  42. end
  43. def reset_session_id
  44. self.session_id = nil
  45. end
  46. def perform_request(api_path:, params: nil)
  47. uri = URI("#{Setting.get('import_kayako_endpoint')}/#{api_path}")
  48. uri.query = URI.encode_www_form(params) if params.present?
  49. headers = {
  50. 'Content-Type' => 'application/json',
  51. 'X-Session-ID' => session_id
  52. }
  53. Net::HTTP.start(uri.host, uri.port, use_ssl: true, read_timeout: 600) do |http|
  54. # for those special moments...
  55. # http.set_debug_output($stdout)
  56. request = Net::HTTP::Get.new(uri, headers)
  57. if session_id.blank?
  58. request.basic_auth(Setting.get('import_kayako_endpoint_username'), Setting.get('import_kayako_endpoint_password'))
  59. end
  60. return http.request(request)
  61. end
  62. end
  63. end