123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
- module Import
- module OTRS
- # @!attribute [rw] retry_sleep
- # @return [Number] the sleep time between the request retries
- module Requester
- extend Import::Helper
- extend self
- attr_accessor :retry_sleep
- # Loads entries of the given object.
- #
- # @param object [String] the name of OTRS object
- # @param [Hash] opts the options to load entries.
- # @option opts [String] :limit the maximum amount of entries that should get loaded
- # @option opts [String] :offset the offset where the entry listing should start
- # @option opts [Boolean] :diff request only changed/added entries since the last import
- #
- # @example
- # Import::OTRS::Requester.load('Ticket', offset: '208', limit: '1')
- # #=> [{'TicketNumber':'1234', ...}, ...]
- #
- # Import::OTRS::Requester.load('State', offset: '0', limit: '50')
- # #=> [{'Name':'pending reminder', ...}, ...]
- #
- # @return [Array<Hash{String => String, Number, nil, Hash, Array}>]
- def load(object, opts = {})
- @cache ||= {}
- if opts.blank? && @cache[object]
- return @cache[object]
- end
- result = request_result(
- Subaction: 'Export',
- Object: object,
- Limit: opts[:limit] || '',
- Offset: opts[:offset] || '',
- Diff: opts[:diff] ? 1 : 0
- )
- return result if opts.present?
- @cache[object] = result
- @cache[object]
- end
- # Lists the OTRS objects and their amount of importable entries.
- #
- # @example
- # Import::OTRS::Requester.list #=> {'DynamicFields' => 5, ...}
- #
- # @return [Hash{String => Number}] key = OTRS object, value = amount
- def list
- request_result(Subaction: 'List')
- end
- # Checks if the connection to the OTRS export endpoint works.
- #
- # @todo Refactor to something like .connected?
- #
- # @example
- # Import::OTRS::Requester.connection_test #=> true
- #
- # @raise [RuntimeError] if the API key is not valid
- #
- # @return [true] always returns true
- def connection_test
- result = request_json({})
- raise 'API key not valid!' if !result['Success']
- true
- end
- private
- def request_result(params)
- tries ||= 1
- response = request_json(params)
- response['Result']
- rescue
- # stop after 3 tries
- raise if tries == 3
- # try again
- tries += 1
- sleep tries * (retry_sleep || 15)
- retry
- end
- def request_json(params)
- response = post(params)
- result = handle_response(response)
- raise 'Invalid response' if !result
- result
- end
- def handle_response(response)
- encoded_body = response.body.to_utf8(fallback: :read_as_sanitized_binary)
- # remove null bytes otherwise PostgreSQL will fail
- encoded_body.delete('\u0000')
- JSON.parse(encoded_body)
- end
- def post(params)
- url = Setting.get('import_otrs_endpoint')
- params[:Action] = 'ZammadMigrator'
- params[:Key] = Setting.get('import_otrs_endpoint_key')
- log "POST: #{url}"
- log "PARAMS: #{params.inspect}"
- response = UserAgent.post(
- url,
- params,
- {
- open_timeout: 10,
- read_timeout: 120,
- total_timeout: 360,
- user: Setting.get('import_otrs_user'),
- password: Setting.get('import_otrs_password'),
- },
- )
- if !response
- raise "Can't connect to Zammad Migrator"
- end
- if !response.success?
- log "ERROR: #{response.error}"
- raise 'Zammad Migrator returned an error'
- end
- response
- end
- end
- end
- end
|