otrs.rb 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. # Rails autoload has some issues with same namend sub-classes
  2. # in the importer folder require AND simultaniuos requiring
  3. # of the same file in different threads so we need to
  4. # require them ourself
  5. require 'import/otrs/ticket'
  6. require 'import/otrs/ticket_factory'
  7. require 'import/otrs/article_customer'
  8. require 'import/otrs/article_customer_factory'
  9. require 'import/otrs/article'
  10. require 'import/otrs/article_factory'
  11. require 'import/otrs/article/attachment_factory'
  12. require 'import/otrs/history'
  13. require 'import/otrs/history_factory'
  14. require 'import/otrs/history/article'
  15. require 'import/otrs/history/move'
  16. require 'import/otrs/history/new_ticket'
  17. require 'import/otrs/history/priority_update'
  18. require 'import/otrs/history/state_update'
  19. require 'store'
  20. require 'store/object'
  21. require 'store/provider/db'
  22. require 'store/provider/file'
  23. module Import
  24. module OTRS
  25. extend Import::Helper
  26. extend Import::OTRS::ImportStats
  27. extend Import::OTRS::Async
  28. extend Import::OTRS::Diff
  29. # rubocop:disable Style/ModuleFunction
  30. extend self
  31. def start
  32. log 'Start import...'
  33. checks
  34. prerequisites
  35. base_objects
  36. updateable_objects
  37. customer_user
  38. threaded_import('Ticket')
  39. true
  40. end
  41. def connection_test
  42. Import::OTRS::Requester.connection_test
  43. end
  44. private
  45. def checks
  46. check_import_mode
  47. connection_test
  48. end
  49. def prerequisites
  50. # make sure to create store type otherwise
  51. # it might lead to race conditions while
  52. # creating it in different import threads
  53. Store::Object.create_if_not_exists(name: 'Ticket::Article')
  54. end
  55. def import(remote_object, args = {})
  56. log "loading #{remote_object}..."
  57. import_action(remote_object, args)
  58. end
  59. def threaded_import(remote_object, args = {})
  60. thread_count = args[:threads] || 8
  61. limit = args[:limit] || 20
  62. Thread.abort_on_exception = true
  63. threads = {}
  64. (1..thread_count).each { |thread|
  65. threads[thread] = Thread.new {
  66. Thread.current[:thread_no] = thread
  67. Thread.current[:loop_count] = 0
  68. log "Importing #{remote_object} in steps of #{limit}"
  69. loop do
  70. # get the offset for the current thread and loop count
  71. thread_offset_base = (Thread.current[:thread_no] - 1) * limit
  72. thread_step = thread_count * limit
  73. offset = Thread.current[:loop_count] * thread_step + thread_offset_base
  74. break if !imported?(
  75. remote_object: remote_object,
  76. limit: limit,
  77. offset: offset,
  78. diff: args[:diff]
  79. )
  80. Thread.current[:loop_count] += 1
  81. end
  82. ActiveRecord::Base.connection.close
  83. }
  84. }
  85. (1..thread_count).each { |thread|
  86. threads[thread].join
  87. }
  88. end
  89. def limit_import(remote_object, args = {})
  90. offset = 0
  91. limit = args[:limit] || 20
  92. log "Importing #{remote_object} in steps of #{limit}"
  93. loop do
  94. break if !imported?(
  95. remote_object: remote_object,
  96. limit: limit,
  97. offset: offset,
  98. diff: args[:diff]
  99. )
  100. offset += limit
  101. end
  102. end
  103. def imported?(args)
  104. log "loading #{args[:limit]} #{args[:remote_object]} starting at #{args[:offset]}..."
  105. return false if !import_action(args[:remote_object], limit: args[:limit], offset: args[:offset], diff: args[:diff])
  106. true
  107. end
  108. def import_action(remote_object, args = {})
  109. records = Import::OTRS::Requester.load(remote_object, limit: args[:limit], offset: args[:offset], diff: args[:diff])
  110. if !records || records.empty?
  111. log '... no more work.'
  112. return false
  113. end
  114. factory_class(remote_object).import(records)
  115. end
  116. def factory_class(object)
  117. "Import::OTRS::#{object}Factory".constantize
  118. end
  119. # sync settings
  120. def base_objects
  121. import('SysConfig')
  122. import('DynamicField')
  123. end
  124. def updateable_objects
  125. import('State')
  126. import('Priority')
  127. import('Queue')
  128. import('User')
  129. import('Customer')
  130. end
  131. def customer_user
  132. limit_import('CustomerUser', limit: 50)
  133. end
  134. end
  135. end