requester.rb 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. module Import
  3. module OTRS
  4. # @!attribute [rw] retry_sleep
  5. # @return [Number] the sleep time between the request retries
  6. module Requester
  7. extend Import::Helper
  8. extend self
  9. attr_accessor :retry_sleep
  10. # Loads entries of the given object.
  11. #
  12. # @param object [String] the name of OTRS object
  13. # @param [Hash] opts the options to load entries.
  14. # @option opts [String] :limit the maximum amount of entries that should get loaded
  15. # @option opts [String] :offset the offset where the entry listing should start
  16. # @option opts [Boolean] :diff request only changed/added entries since the last import
  17. #
  18. # @example
  19. # Import::OTRS::Requester.load('Ticket', offset: '208', limit: '1')
  20. # #=> [{'TicketNumber':'1234', ...}, ...]
  21. #
  22. # Import::OTRS::Requester.load('State', offset: '0', limit: '50')
  23. # #=> [{'Name':'pending reminder', ...}, ...]
  24. #
  25. # @return [Array<Hash{String => String, Number, nil, Hash, Array}>]
  26. def load(object, opts = {})
  27. @cache ||= {}
  28. if opts.blank? && @cache[object]
  29. return @cache[object]
  30. end
  31. result = request_result(
  32. Subaction: 'Export',
  33. Object: object,
  34. Limit: opts[:limit] || '',
  35. Offset: opts[:offset] || '',
  36. Diff: opts[:diff] ? 1 : 0
  37. )
  38. return result if opts.present?
  39. @cache[object] = result
  40. @cache[object]
  41. end
  42. # Lists the OTRS objects and their amount of importable entries.
  43. #
  44. # @example
  45. # Import::OTRS::Requester.list #=> {'DynamicFields' => 5, ...}
  46. #
  47. # @return [Hash{String => Number}] key = OTRS object, value = amount
  48. def list
  49. request_result(Subaction: 'List')
  50. end
  51. # Checks if the connection to the OTRS export endpoint works.
  52. #
  53. # @todo Refactor to something like .connected?
  54. #
  55. # @example
  56. # Import::OTRS::Requester.connection_test #=> true
  57. #
  58. # @raise [RuntimeError] if the API key is not valid
  59. #
  60. # @return [true] always returns true
  61. def connection_test
  62. result = request_json({})
  63. raise 'API key not valid!' if !result['Success']
  64. true
  65. end
  66. private
  67. def request_result(params)
  68. tries ||= 1
  69. response = request_json(params)
  70. response['Result']
  71. rescue
  72. # stop after 3 tries
  73. raise if tries == 3
  74. # try again
  75. tries += 1
  76. sleep tries * (retry_sleep || 15)
  77. retry
  78. end
  79. def request_json(params)
  80. response = post(params)
  81. result = handle_response(response)
  82. raise 'Invalid response' if !result
  83. result
  84. end
  85. def handle_response(response)
  86. encoded_body = response.body.to_utf8(fallback: :read_as_sanitized_binary)
  87. # remove null bytes otherwise PostgreSQL will fail
  88. encoded_body.delete('\u0000')
  89. JSON.parse(encoded_body)
  90. end
  91. def post(params)
  92. url = Setting.get('import_otrs_endpoint')
  93. params[:Action] = 'ZammadMigrator'
  94. params[:Key] = Setting.get('import_otrs_endpoint_key')
  95. log "POST: #{url}"
  96. log "PARAMS: #{params.inspect}"
  97. response = UserAgent.post(
  98. url,
  99. params,
  100. {
  101. open_timeout: 10,
  102. read_timeout: 120,
  103. total_timeout: 360,
  104. user: Setting.get('import_otrs_user'),
  105. password: Setting.get('import_otrs_password'),
  106. },
  107. )
  108. if !response
  109. raise "Can't connect to Zammad Migrator"
  110. end
  111. if !response.success?
  112. log "ERROR: #{response.error}"
  113. raise 'Zammad Migrator returned an error'
  114. end
  115. response
  116. end
  117. end
  118. end
  119. end