Commit 0845b8a9 authored by Jan Provaznik's avatar Jan Provaznik

Merge branch 'georgekoltsov/fix-wiki-pipeline' into 'master'

Fix Wiki Pipeline network error if group wiki does not exist

See merge request gitlab-org/gitlab!74731
parents 87c504e5 c3d0947e
...@@ -20,8 +20,6 @@ ...@@ -20,8 +20,6 @@
class BulkImports::Entity < ApplicationRecord class BulkImports::Entity < ApplicationRecord
self.table_name = 'bulk_import_entities' self.table_name = 'bulk_import_entities'
EXPORT_RELATIONS_URL = '/%{resource}/%{full_path}/export_relations'
belongs_to :bulk_import, optional: false belongs_to :bulk_import, optional: false
belongs_to :parent, class_name: 'BulkImports::Entity', optional: true belongs_to :parent, class_name: 'BulkImports::Entity', optional: true
...@@ -112,14 +110,22 @@ class BulkImports::Entity < ApplicationRecord ...@@ -112,14 +110,22 @@ class BulkImports::Entity < ApplicationRecord
entity_type.pluralize entity_type.pluralize
end end
def base_resource_url_path
"/#{pluralized_name}/#{encoded_source_full_path}"
end
def export_relations_url_path def export_relations_url_path
@export_relations_url_path ||= EXPORT_RELATIONS_URL % { resource: pluralized_name, full_path: encoded_source_full_path } "#{base_resource_url_path}/export_relations"
end end
def relation_download_url_path(relation) def relation_download_url_path(relation)
"#{export_relations_url_path}/download?relation=#{relation}" "#{export_relations_url_path}/download?relation=#{relation}"
end end
def wikis_url_path
"#{base_resource_url_path}/wikis"
end
def project? def project?
source_type == 'project_entity' source_type == 'project_entity'
end end
......
...@@ -123,7 +123,7 @@ module BulkImports ...@@ -123,7 +123,7 @@ module BulkImports
def with_error_handling def with_error_handling
response = yield response = yield
raise ::BulkImports::NetworkError.new(response: response) unless response.success? raise ::BulkImports::NetworkError.new("Unsuccessful response #{response.code} from #{response.request.path.path}", response: response) unless response.success?
response response
rescue *Gitlab::HTTP::HTTP_ERRORS => e rescue *Gitlab::HTTP::HTTP_ERRORS => e
......
...@@ -7,7 +7,9 @@ module BulkImports ...@@ -7,7 +7,9 @@ module BulkImports
include Pipeline include Pipeline
def extract(*) def extract(*)
BulkImports::Pipeline::ExtractedData.new(data: { url: url_from_parent_path(context.entity.source_full_path) }) url = url_from_parent_path(context.entity.source_full_path) if source_wiki_exists?
BulkImports::Pipeline::ExtractedData.new(data: { url: url })
end end
def transform(_, data) def transform(_, data)
...@@ -15,14 +17,15 @@ module BulkImports ...@@ -15,14 +17,15 @@ module BulkImports
end end
def load(context, data) def load(context, data)
return unless context.portable.wiki return unless data&.dig(:url)
wiki = context.portable.wiki
url = data[:url].sub("://", "://oauth2:#{context.configuration.access_token}@") url = data[:url].sub("://", "://oauth2:#{context.configuration.access_token}@")
Gitlab::UrlBlocker.validate!(url, allow_local_network: allow_local_requests?, allow_localhost: allow_local_requests?) Gitlab::UrlBlocker.validate!(url, allow_local_network: allow_local_requests?, allow_localhost: allow_local_requests?)
context.portable.wiki.ensure_repository wiki.ensure_repository
context.portable.wiki.repository.fetch_as_mirror(url) wiki.repository.fetch_as_mirror(url)
end end
private private
...@@ -36,6 +39,16 @@ module BulkImports ...@@ -36,6 +39,16 @@ module BulkImports
def allow_local_requests? def allow_local_requests?
Gitlab::CurrentSettings.allow_local_requests_from_web_hooks_and_services? Gitlab::CurrentSettings.allow_local_requests_from_web_hooks_and_services?
end end
def source_wiki_exists?
wikis = client.get(context.entity.wikis_url_path).parsed_response
wikis.any?
end
def client
BulkImports::Clients::HTTP.new(url: context.configuration.url, token: context.configuration.access_token)
end
end end
end end
end end
......
...@@ -38,11 +38,11 @@ RSpec.describe BulkImports::Clients::HTTP do ...@@ -38,11 +38,11 @@ RSpec.describe BulkImports::Clients::HTTP do
context 'when response is not success' do context 'when response is not success' do
it 'raises BulkImports::Error' do it 'raises BulkImports::Error' do
response_double = double(code: 503, success?: false) response_double = double(code: 503, success?: false, request: double(path: double(path: '/test')))
allow(Gitlab::HTTP).to receive(method).and_return(response_double) allow(Gitlab::HTTP).to receive(method).and_return(response_double)
expect { subject.public_send(method, resource) }.to raise_exception(BulkImports::NetworkError) expect { subject.public_send(method, resource) }.to raise_exception(BulkImports::NetworkError, 'Unsuccessful response 503 from /test')
end end
end end
end end
......
...@@ -282,4 +282,20 @@ RSpec.describe BulkImports::Entity, type: :model do ...@@ -282,4 +282,20 @@ RSpec.describe BulkImports::Entity, type: :model do
expect(project_entity.group?).to eq(false) expect(project_entity.group?).to eq(false)
end end
end end
describe '#base_resource_url_path' do
it 'returns base entity url path' do
entity = build(:bulk_import_entity)
expect(entity.base_resource_url_path).to eq("/groups/#{entity.encoded_source_full_path}")
end
end
describe '#wiki_url_path' do
it 'returns entity wiki url path' do
entity = build(:bulk_import_entity)
expect(entity.wikis_url_path).to eq("/groups/#{entity.encoded_source_full_path}/wikis")
end
end
end end
...@@ -9,16 +9,18 @@ RSpec.shared_examples 'wiki pipeline imports a wiki for an entity' do ...@@ -9,16 +9,18 @@ RSpec.shared_examples 'wiki pipeline imports a wiki for an entity' do
let(:extracted_data) { BulkImports::Pipeline::ExtractedData.new(data: {}) } let(:extracted_data) { BulkImports::Pipeline::ExtractedData.new(data: {}) }
context 'successfully imports wiki for an entity' do subject { described_class.new(context) }
subject { described_class.new(context) }
before do before do
allow_next_instance_of(BulkImports::Common::Extractors::GraphqlExtractor) do |extractor| allow_next_instance_of(BulkImports::Common::Extractors::GraphqlExtractor) do |extractor|
allow(extractor).to receive(:extract).and_return(extracted_data) allow(extractor).to receive(:extract).and_return(extracted_data)
end
end end
end
context 'when wiki exists' do
it 'imports new wiki into destination project' do it 'imports new wiki into destination project' do
expect(subject).to receive(:source_wiki_exists?).and_return(true)
expect_next_instance_of(Gitlab::GitalyClient::RepositoryService) do |repository_service| expect_next_instance_of(Gitlab::GitalyClient::RepositoryService) do |repository_service|
url = "https://oauth2:token@gitlab.example/#{entity.source_full_path}.wiki.git" url = "https://oauth2:token@gitlab.example/#{entity.source_full_path}.wiki.git"
expect(repository_service).to receive(:fetch_remote).with(url, any_args).and_return 0 expect(repository_service).to receive(:fetch_remote).with(url, any_args).and_return 0
...@@ -27,5 +29,16 @@ RSpec.shared_examples 'wiki pipeline imports a wiki for an entity' do ...@@ -27,5 +29,16 @@ RSpec.shared_examples 'wiki pipeline imports a wiki for an entity' do
subject.run subject.run
end end
end end
context 'when wiki does not exist' do
it 'does not import wiki' do
expect(subject).to receive(:source_wiki_exists?).and_return(false)
expect(parent.wiki).not_to receive(:ensure_repository)
expect(parent.wiki.repository).not_to receive(:ensure_repository)
expect { subject.run }.not_to raise_error
end
end
end end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment