Welcome to mirror list, hosted at ThFree Co, Russian Federation.

export_request_worker.rb « bulk_imports « workers « app - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 44759916f99cc1a24bc3f3fb38cb3cb4448f821c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# frozen_string_literal: true

module BulkImports
  class ExportRequestWorker
    include ApplicationWorker

    idempotent!
    data_consistency :always
    feature_category :importers
    sidekiq_options dead: false, retry: 5
    worker_has_external_dependencies!

    sidekiq_retries_exhausted do |msg, exception|
      new.perform_failure(exception, msg['args'].first)
    end

    def perform(entity_id)
      @entity = BulkImports::Entity.find(entity_id)

      set_source_xid
      request_export

      BulkImports::EntityWorker.perform_async(entity_id)
    end

    def perform_failure(exception, entity_id)
      @entity = BulkImports::Entity.find(entity_id)

      log_and_fail(exception)
    end

    private

    attr_reader :entity

    def set_source_xid
      entity.update!(source_xid: entity_source_xid) if entity.source_xid.nil?
    end

    def request_export
      http_client.post(export_url)
    end

    def http_client
      @client ||= Clients::HTTP.new(
        url: entity.bulk_import.configuration.url,
        token: entity.bulk_import.configuration.access_token
      )
    end

    def failure_attributes(exception)
      {
        bulk_import_entity_id: entity.id,
        pipeline_class: 'ExportRequestWorker',
        exception_class: exception.class.to_s,
        exception_message: exception.message.truncate(255),
        correlation_id_value: Labkit::Correlation::CorrelationId.current_or_new_id
      }
    end

    def graphql_client
      @graphql_client ||= BulkImports::Clients::Graphql.new(
        url: entity.bulk_import.configuration.url,
        token: entity.bulk_import.configuration.access_token
      )
    end

    def entity_source_xid
      response = graphql_client.execute(
        graphql_client.parse(entity_query.to_s),
        { full_path: entity.source_full_path }
      ).original_hash

      ::GlobalID.parse(response.dig(*entity_query.data_path, 'id')).model_id
    rescue StandardError => e
      log_exception(e,
        {
          message: 'Failed to fetch source entity id',
          bulk_import_entity_id: entity.id,
          bulk_import_id: entity.bulk_import_id,
          bulk_import_entity_type: entity.source_type,
          source_full_path: entity.source_full_path,
          source_version: entity.bulk_import.source_version_info.to_s,
          importer: 'gitlab_migration'
        }
      )

      nil
    end

    def entity_query
      @entity_query ||= if entity.group?
                          BulkImports::Groups::Graphql::GetGroupQuery.new(context: nil)
                        else
                          BulkImports::Projects::Graphql::GetProjectQuery.new(context: nil)
                        end
    end

    def logger
      @logger ||= Gitlab::Import::Logger.build
    end

    def log_exception(exception, payload)
      Gitlab::ExceptionLogFormatter.format!(exception, payload)

      logger.error(structured_payload(payload))
    end

    def log_and_fail(exception)
      log_exception(exception,
        {
          bulk_import_entity_id: entity.id,
          bulk_import_id: entity.bulk_import_id,
          bulk_import_entity_type: entity.source_type,
          source_full_path: entity.source_full_path,
          message: "Request to export #{entity.source_type} failed",
          source_version: entity.bulk_import.source_version_info.to_s,
          importer: 'gitlab_migration'
        }
      )

      BulkImports::Failure.create(failure_attributes(exception))

      entity.fail_op!
    end

    def export_url
      entity.export_relations_url_path(batched: Feature.enabled?(:bulk_imports_batched_import_export))
    end
  end
end