2022-01-01 13:38:12 +00:00
|
|
|
# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
|
2021-06-01 12:20:20 +00:00
|
|
|
|
2016-11-25 16:10:37 +00:00
|
|
|
module Import
|
|
|
|
module OTRS
|
2017-03-28 14:19:37 +00:00
|
|
|
|
|
|
|
# @!attribute [rw] retry_sleep
|
|
|
|
# @return [Number] the sleep time between the request retries
|
2016-11-25 16:10:37 +00:00
|
|
|
module Requester
|
|
|
|
extend Import::Helper
|
|
|
|
extend self
|
|
|
|
|
2017-03-28 14:19:37 +00:00
|
|
|
attr_accessor :retry_sleep
|
|
|
|
|
2017-04-25 07:51:39 +00:00
|
|
|
# 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
|
2020-10-19 14:45:10 +00:00
|
|
|
# Import::OTRS::Requester.load('Ticket', offset: '208', limit: '1')
|
|
|
|
# #=> [{'TicketNumber':'1234', ...}, ...]
|
|
|
|
#
|
2017-04-25 07:51:39 +00:00
|
|
|
# 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 = {})
|
2016-11-25 16:10:37 +00:00
|
|
|
|
|
|
|
@cache ||= {}
|
2017-11-23 08:09:44 +00:00
|
|
|
if opts.blank? && @cache[object]
|
2016-11-25 16:10:37 +00:00
|
|
|
return @cache[object]
|
|
|
|
end
|
|
|
|
|
|
|
|
result = request_result(
|
|
|
|
Subaction: 'Export',
|
|
|
|
Object: object,
|
2018-12-19 17:31:51 +00:00
|
|
|
Limit: opts[:limit] || '',
|
2017-04-25 07:51:39 +00:00
|
|
|
Offset: opts[:offset] || '',
|
|
|
|
Diff: opts[:diff] ? 1 : 0
|
2016-11-25 16:10:37 +00:00
|
|
|
)
|
|
|
|
|
2017-11-23 08:09:44 +00:00
|
|
|
return result if opts.present?
|
2018-10-09 06:17:41 +00:00
|
|
|
|
2016-11-25 16:10:37 +00:00
|
|
|
@cache[object] = result
|
|
|
|
@cache[object]
|
|
|
|
end
|
|
|
|
|
2017-04-25 07:51:39 +00:00
|
|
|
# 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
|
2016-11-25 16:10:37 +00:00
|
|
|
def list
|
|
|
|
request_result(Subaction: 'List')
|
|
|
|
end
|
|
|
|
|
2017-04-25 07:51:39 +00:00
|
|
|
# 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
|
2016-11-25 16:10:37 +00:00
|
|
|
def connection_test
|
|
|
|
result = request_json({})
|
2017-04-25 07:51:39 +00:00
|
|
|
raise 'API key not valid!' if !result['Success']
|
2018-10-09 06:17:41 +00:00
|
|
|
|
2017-04-25 07:51:39 +00:00
|
|
|
true
|
2016-11-25 16:10:37 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def request_result(params)
|
2017-03-28 14:19:37 +00:00
|
|
|
tries ||= 1
|
2016-11-25 16:10:37 +00:00
|
|
|
response = request_json(params)
|
|
|
|
response['Result']
|
2017-03-28 14:19:37 +00:00
|
|
|
rescue
|
|
|
|
# stop after 3 tries
|
|
|
|
raise if tries == 3
|
|
|
|
|
|
|
|
# try again
|
|
|
|
tries += 1
|
|
|
|
sleep tries * (retry_sleep || 15)
|
|
|
|
retry
|
2016-11-25 16:10:37 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def request_json(params)
|
|
|
|
response = post(params)
|
|
|
|
result = handle_response(response)
|
2017-04-25 07:51:39 +00:00
|
|
|
raise 'Invalid response' if !result
|
2018-10-09 06:17:41 +00:00
|
|
|
|
2017-04-25 07:51:39 +00:00
|
|
|
result
|
2016-11-25 16:10:37 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def handle_response(response)
|
2020-10-19 14:45:10 +00:00
|
|
|
encoded_body = response.body.to_utf8(fallback: :read_as_sanitized_binary)
|
2017-06-28 12:47:58 +00:00
|
|
|
# remove null bytes otherwise PostgreSQL will fail
|
2018-06-01 11:32:59 +00:00
|
|
|
encoded_body.delete('\u0000')
|
2016-11-25 16:10:37 +00:00
|
|
|
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')
|
|
|
|
|
2020-09-30 09:07:01 +00:00
|
|
|
log "POST: #{url}"
|
|
|
|
log "PARAMS: #{params.inspect}"
|
2016-11-25 16:10:37 +00:00
|
|
|
|
|
|
|
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
|