diff --git a/app/controllers/internal/staging_completion_controller.rb b/app/controllers/internal/staging_completion_controller.rb index 06e9546f088..cee2f7ef738 100644 --- a/app/controllers/internal/staging_completion_controller.rb +++ b/app/controllers/internal/staging_completion_controller.rb @@ -16,39 +16,6 @@ def inject_dependencies(dependencies) @stagers = dependencies.fetch(:stagers) end - post '/internal/v3/staging/:staging_guid/droplet_completed', :droplet_completed # NOT USED, only for rolling deploys - def droplet_completed(staging_guid) - staging_response = read_body - droplet = DropletModel.find(guid: staging_guid) - raise CloudController::Errors::ApiError.new_from_details('ResourceNotFound', 'Droplet not found') if droplet.nil? - - build = BuildModel.create(package: droplet.package, app: droplet.app, state: DropletModel::STAGING_STATE) - - BuildModel.db.transaction do - build.lock! - build.update( - droplet: droplet, - buildpack_lifecycle_data: droplet.buildpack_lifecycle_data - ) - end - - if staging_response.key?(:failed) - report_metrics(staging_response) - staging_response = parse_bbs_task_callback(staging_response) - end - - begin - stagers.stager_for_build(build).staging_complete(build, staging_response, params['start'] == 'true') - rescue CloudController::Errors::ApiError => e - raise e - rescue StandardError => e - logger.error('diego.staging.completion-controller-error', error: e) - raise CloudController::Errors::ApiError.new_from_details('ServerError') - end - - [200, '{}'] - end - post '/internal/v3/staging/:staging_guid/build_completed', :build_completed def build_completed(staging_guid) staging_response = read_body diff --git a/spec/unit/controllers/internal/staging_completion_controller_spec.rb b/spec/unit/controllers/internal/staging_completion_controller_spec.rb index 92e20725d79..92d02d26a2a 100644 --- a/spec/unit/controllers/internal/staging_completion_controller_spec.rb +++ b/spec/unit/controllers/internal/staging_completion_controller_spec.rb @@ -52,157 +52,6 @@ module VCAP::CloudController allow(VCAP::CloudController::Metrics::PrometheusUpdater).to receive(:new).and_return(prometheus_updater) end - context 'staging a package through /droplet_completed (legacy for rolling deploy)' do - let(:url) { "/internal/v3/staging/#{staging_guid}/droplet_completed" } - let(:staged_app) { create(:app_model) } - let(:package) { create(:package_model, state: 'READY', app_guid: staged_app.guid) } - let(:droplet) { create(:droplet_model, package_guid: package.guid, app_guid: staged_app.guid, state: DropletModel::STAGING_STATE) } - let(:staging_guid) { droplet.guid } - - context 'when it is a docker app' do - let(:staged_app) { create(:app_model, :docker) } - let(:package) { create(:package_model, :docker, state: 'READY', app_guid: staged_app.guid) } - let(:droplet) { create(:droplet_model, :docker, package_guid: package.guid, app_guid: staged_app.guid, state: DropletModel::STAGING_STATE) } - - it 'calls the stager with a build created from the droplet and the response' do - expect_any_instance_of(Diego::Stager).to receive(:staging_complete).with(instance_of(BuildModel), staging_response, false) - - post url, Oj.dump(staging_response) - - build = BuildModel.last - expect(build).not_to be_nil - expect(build.lifecycle_type).to eq('docker') - - expect(last_response.status).to eq(200) - end - end - - context 'when it is a buildpack app' do - it 'calls the stager with a build created from the droplet and the response' do - expect_any_instance_of(Diego::Stager).to receive(:staging_complete).with(instance_of(BuildModel), staging_response, false) - - post url, Oj.dump(staging_response) - - build = BuildModel.last - expect(build).not_to be_nil - expect(build.lifecycle_type).to eq('buildpack') - - expect(last_response.status).to eq(200) - end - end - - it 'propagates api errors from staging_response' do - expect_any_instance_of(Diego::Stager).to receive(:staging_complete).and_raise(CloudController::Errors::ApiError.new_from_details('JobTimeout')) - - post url, Oj.dump(staging_response) - expect(last_response.status).to eq(524) - expect(last_response.body).to match(/JobTimeout/) - end - - context 'when receiving the callback directly from BBS' do - let(:staging_result) do - { - lifecycle_type: 'buildpack', - lifecycle_metadata: { - buildpack_key:, - detected_buildpack: - }, - execution_metadata: execution_metadata, - process_types: { web: 'start me' } - } - end - let(:failure_reason) { '' } - let(:sanitized_failure_reason) { double(:sanitized_failure_reason) } - let(:staging_result_json) { Oj.dump(staging_result) } - let(:staging_response) do - { - failed: failure_reason.present?, - failure_reason: failure_reason, - result: staging_result_json, - created_at: (Time.now.utc.to_i - one_hour) * 1e9 - } - end - - before do - allow(Diego::FailureReasonSanitizer).to receive(:sanitize).with(failure_reason).and_return(sanitized_failure_reason) - end - - it 'calls the stager with a build for the droplet and response' do - expect_any_instance_of(Diego::Stager).to receive(:staging_complete).with(instance_of(BuildModel), { result: staging_result }, false) - - post url, Oj.dump(staging_response) - expect(last_response.status).to eq(200) - end - - it 'propagates api errors from staging_response' do - expect_any_instance_of(Diego::Stager).to receive(:staging_complete).and_raise(CloudController::Errors::ApiError.new_from_details('JobTimeout')) - - post url, Oj.dump(staging_response) - expect(last_response.status).to eq(524) - expect(last_response.body).to match(/JobTimeout/) - end - - it 'emits metrics for staging success' do - one_hour_in_nanoseconds = (1.hour.to_i * 1e9).to_i - expect(statsd_updater).to receive(:report_staging_success_metrics).with(one_hour_in_nanoseconds) - expect(prometheus_updater).to receive(:report_staging_success_metrics).with(one_hour_in_nanoseconds) - Timecop.freeze(Time.now) do - post url, Oj.dump(staging_response) - end - end - - context 'when staging failed' do - let(:failure_reason) { 'something went wrong' } - let(:staging_result_json) { nil } - - it 'passes down the sanitized version of the error to the diego stager' do - expect_any_instance_of(Diego::Stager).to receive(:staging_complete).with(instance_of(BuildModel), { error: sanitized_failure_reason }, false) - - post url, Oj.dump(staging_response) - end - - it 'emits metrics for staging failure' do - one_hour_in_nanoseconds = (1.hour.to_i * 1e9).to_i - expect(statsd_updater).to receive(:report_staging_failure_metrics).with(one_hour_in_nanoseconds) - expect(prometheus_updater).to receive(:report_staging_failure_metrics).with(one_hour_in_nanoseconds) - Timecop.freeze(Time.now) do - post url, Oj.dump(staging_response) - end - end - end - end - - context 'when the droplet does not exist' do - let(:staging_guid) { 'asdf' } - - it 'returns 404' do - post url, Oj.dump(staging_response) - expect(last_response.status).to eq(404) - expect(last_response.body).to match(/Droplet not found/) - end - end - - context 'when the start query param has a true value' do - it 'requests staging_complete with start' do - expect_any_instance_of(Diego::Stager).to receive(:staging_complete).with(instance_of(BuildModel), staging_response, true) - - post "#{url}?start=true", Oj.dump(staging_response) - expect(last_response.status).to eq(200) - end - end - - describe 'validation' do - context 'when sending invalid json' do - it 'fails with a 400' do - post url, 'this is not json' - - expect(last_response.status).to eq(400) - expect(last_response.body).to match(/MessageParseError/) - end - end - end - end - describe '/build_completed' do let(:url) { "/internal/v3/staging/#{staging_guid}/build_completed" } let(:staged_app) { create(:app_model) }