From e994738a2e32b2e1ae52b0cc48b4a0cad500aea1 Mon Sep 17 00:00:00 2001 From: simon lehericey Date: Fri, 5 Apr 2024 12:07:40 +0200 Subject: [PATCH 1/4] add and use api_insee_up? --- app/controllers/users/dossiers_controller.rb | 2 +- ...t_champ_etablissement_fetchable_concern.rb | 2 +- app/services/api_entreprise_service.rb | 10 ++++++ .../champs/siret_controller_spec.rb | 4 +-- .../users/dossiers_controller_spec.rb | 16 +++++----- spec/fixtures/files/api_entreprise/ping.json | 5 +++ ...mp_etablissement_fetchable_concern_spec.rb | 4 +-- spec/services/api_entreprise_service_spec.rb | 32 +++++++++++++++++++ 8 files changed, 61 insertions(+), 14 deletions(-) create mode 100644 spec/fixtures/files/api_entreprise/ping.json diff --git a/app/controllers/users/dossiers_controller.rb b/app/controllers/users/dossiers_controller.rb index e7e47374d..d00d049dd 100644 --- a/app/controllers/users/dossiers_controller.rb +++ b/app/controllers/users/dossiers_controller.rb @@ -175,7 +175,7 @@ module Users etablissement = begin APIEntrepriseService.create_etablissement(@dossier, sanitized_siret, current_user.id) rescue => error - if error.try(:network_error?) && !APIEntrepriseService.api_up? + if error.try(:network_error?) && !APIEntrepriseService.api_insee_up? # TODO: notify ops APIEntrepriseService.create_etablissement_as_degraded_mode(@dossier, sanitized_siret, current_user.id) else diff --git a/app/models/concerns/siret_champ_etablissement_fetchable_concern.rb b/app/models/concerns/siret_champ_etablissement_fetchable_concern.rb index ccfe17e37..333d58ad8 100644 --- a/app/models/concerns/siret_champ_etablissement_fetchable_concern.rb +++ b/app/models/concerns/siret_champ_etablissement_fetchable_concern.rb @@ -11,7 +11,7 @@ module SiretChampEtablissementFetchableConcern update!(etablissement: etablissement) rescue => error - if error.try(:network_error?) && !APIEntrepriseService.api_up? + if error.try(:network_error?) && !APIEntrepriseService.api_insee_up? # TODO: notify ops update!( etablissement: APIEntrepriseService.create_etablissement_as_degraded_mode(self, siret, user.id) diff --git a/app/services/api_entreprise_service.rb b/app/services/api_entreprise_service.rb index 585c4f8db..82f77921f 100644 --- a/app/services/api_entreprise_service.rb +++ b/app/services/api_entreprise_service.rb @@ -64,5 +64,15 @@ class APIEntrepriseService Sentry.capture_exception(e) false end + + # See: https://entreprise.api.gouv.fr/developpeurs#surveillance-etat-fournisseurs + def api_insee_up? + response = Typhoeus.get("https://entreprise.api.gouv.fr/ping/insee/sirene", timeout: 1) + if response.success? + JSON.parse(response.body).fetch('status') == 'ok' + else + false + end + end end end diff --git a/spec/controllers/champs/siret_controller_spec.rb b/spec/controllers/champs/siret_controller_spec.rb index 6a1dedf18..67a1ac8de 100644 --- a/spec/controllers/champs/siret_controller_spec.rb +++ b/spec/controllers/champs/siret_controller_spec.rb @@ -83,7 +83,7 @@ describe Champs::SiretController, type: :controller do let(:api_etablissement_status) { 503 } before do - expect(APIEntrepriseService).to receive(:api_up?).and_return(true) + expect(APIEntrepriseService).to receive(:api_insee_up?).and_return(true) end subject! { get :show, params: params, format: :turbo_stream } @@ -102,7 +102,7 @@ describe Champs::SiretController, type: :controller do let(:api_etablissement_status) { 502 } before do - expect(APIEntrepriseService).to receive(:api_up?).and_return(false) + expect(APIEntrepriseService).to receive(:api_insee_up?).and_return(false) end subject! { get :show, params: params, format: :turbo_stream } diff --git a/spec/controllers/users/dossiers_controller_spec.rb b/spec/controllers/users/dossiers_controller_spec.rb index b5ca8f810..5253ba54c 100644 --- a/spec/controllers/users/dossiers_controller_spec.rb +++ b/spec/controllers/users/dossiers_controller_spec.rb @@ -245,21 +245,21 @@ describe Users::DossiersController, type: :controller do let(:api_etablissement_status) { 200 } let(:api_etablissement_body) { Rails.root.join('spec/fixtures/files/api_entreprise/etablissements.json').read } let(:token_expired) { false } - let(:api_current_status_response) { nil } + let(:api_insee_status_response) { nil } before do sign_in(user) stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v3\/insee\/sirene\/etablissements\/#{siret}/) .to_return(status: api_etablissement_status, body: api_etablissement_body) stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v3\/insee\/sirene\/unites_legales\/#{siren}/) - .to_return(body: Rails.root.join('spec/fixtures/files/api_entreprise/status.json').read, status: 200) + .to_return(body: Rails.root.join('spec/fixtures/files/api_entreprise/ping.json').read, status: 200) allow_any_instance_of(APIEntrepriseToken).to receive(:roles) .and_return(["attestations_fiscales", "attestations_sociales", "bilans_entreprise_bdf"]) allow_any_instance_of(APIEntrepriseToken).to receive(:expired?).and_return(token_expired) - if api_current_status_response - stub_request(:get, "https://status.entreprise.api.gouv.fr/summary.json") - .to_return(body: api_current_status_response) + if api_insee_status_response + stub_request(:get, "https://entreprise.api.gouv.fr/ping/insee/sirene") + .to_return(body: api_insee_status_response) end end @@ -304,14 +304,14 @@ describe Users::DossiersController, type: :controller do context 'When API-Entreprise is ponctually down' do let(:api_etablissement_status) { 502 } - let(:api_current_status_response) { Rails.root.join('spec/fixtures/files/api_entreprise/status.json').read } + let(:api_insee_status_response) { Rails.root.join('spec/fixtures/files/api_entreprise/ping.json').read } it_behaves_like 'the request fails with an error', I18n.t('errors.messages.siret_network_error') end context 'When API-Entreprise is globally down' do let(:api_etablissement_status) { 502 } - let(:api_current_status_response) { Rails.root.join('spec/fixtures/files/api_entreprise/status.json').read.gsub('UP', 'HASISSUES') } + let(:api_insee_status_response) { Rails.root.join('spec/fixtures/files/api_entreprise/ping.json').read.gsub('ok', 'HASISSUES') } it "create an etablissement only with SIRET as degraded mode" do dossier.reload @@ -328,7 +328,7 @@ describe Users::DossiersController, type: :controller do context 'when default token has expired' do let(:api_etablissement_status) { 200 } - let(:api_current_status_response) { Rails.root.join('spec/fixtures/files/api_entreprise/status.json').read } + let(:api_insee_status_response) { Rails.root.join('spec/fixtures/files/api_entreprise/ping.json').read } let(:token_expired) { true } it_behaves_like 'the request fails with an error', I18n.t('errors.messages.siret_network_error') diff --git a/spec/fixtures/files/api_entreprise/ping.json b/spec/fixtures/files/api_entreprise/ping.json new file mode 100644 index 000000000..9d4af72b3 --- /dev/null +++ b/spec/fixtures/files/api_entreprise/ping.json @@ -0,0 +1,5 @@ +{ + "status": "ok", + "last_update": "2024-04-05T11:15:25.483+02:00", + "last_ok_status": "2024-04-05T11:15:25.483+02:00" +} diff --git a/spec/models/concern/siret_champ_etablissement_fetchable_concern_spec.rb b/spec/models/concern/siret_champ_etablissement_fetchable_concern_spec.rb index dc803ad90..089099cb9 100644 --- a/spec/models/concern/siret_champ_etablissement_fetchable_concern_spec.rb +++ b/spec/models/concern/siret_champ_etablissement_fetchable_concern_spec.rb @@ -52,7 +52,7 @@ RSpec.describe SiretChampEtablissementFetchableConcern do let(:siret) { '82161143100015' } let(:api_etablissement_status) { 503 } - before { expect(APIEntrepriseService).to receive(:api_up?).and_return(true) } + before { expect(APIEntrepriseService).to receive(:api_insee_up?).and_return(true) } it_behaves_like 'an error occured', :network_error @@ -66,7 +66,7 @@ RSpec.describe SiretChampEtablissementFetchableConcern do let(:siret) { '82161143100015' } let(:api_etablissement_status) { 502 } - before { expect(APIEntrepriseService).to receive(:api_up?).and_return(false) } + before { expect(APIEntrepriseService).to receive(:api_insee_up?).and_return(false) } it { expect { fetch_etablissement! }.to change { champ.reload.etablissement } } diff --git a/spec/services/api_entreprise_service_spec.rb b/spec/services/api_entreprise_service_spec.rb index c35b7acd4..35d292ae8 100644 --- a/spec/services/api_entreprise_service_spec.rb +++ b/spec/services/api_entreprise_service_spec.rb @@ -116,4 +116,36 @@ describe APIEntrepriseService do end end end + + describe "#api_insee_up?" do + subject { described_class.api_insee_up? } + let(:body) { Rails.root.join('spec/fixtures/files/api_entreprise/ping.json').read } + let(:status) { 200 } + + before do + stub_request(:get, "https://entreprise.api.gouv.fr/ping/insee/sirene") + .to_return(body: body, status: status) + end + + it "returns true when api etablissement is up" do + expect(subject).to be_truthy + end + + context "when api entreprise is down" do + let(:body) { Rails.root.join('spec/fixtures/files/api_entreprise/ping.json').read.gsub('ok', 'HASISSUES') } + + it "returns false" do + expect(subject).to be_falsey + end + end + + context "when api entreprise status is unknown" do + let(:body) { "" } + let(:status) { 0 } + + it "returns nil" do + expect(subject).to be_falsey + end + end + end end From 7b33963a6778e4b05f6712fbab4ad397d28c01f0 Mon Sep 17 00:00:00 2001 From: simon lehericey Date: Fri, 5 Apr 2024 12:08:40 +0200 Subject: [PATCH 2/4] add and use api_djepva_up? --- .../concerns/rna_champ_association_fetchable_concern.rb | 2 +- app/services/api_entreprise_service.rb | 9 +++++++++ spec/controllers/champs/rna_controller_spec.rb | 2 +- .../rna_champ_association_fetchable_concern_spec.rb | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/app/models/concerns/rna_champ_association_fetchable_concern.rb b/app/models/concerns/rna_champ_association_fetchable_concern.rb index 1d2483891..bab2cb168 100644 --- a/app/models/concerns/rna_champ_association_fetchable_concern.rb +++ b/app/models/concerns/rna_champ_association_fetchable_concern.rb @@ -12,7 +12,7 @@ module RNAChampAssociationFetchableConcern update!(data: data) rescue APIEntreprise::API::Error => error - error_key = :network_error if error.try(:network_error?) && !APIEntrepriseService.api_up? + error_key = :network_error if error.try(:network_error?) && !APIEntrepriseService.api_djepva_up? clear_association!(error_key) end diff --git a/app/services/api_entreprise_service.rb b/app/services/api_entreprise_service.rb index 82f77921f..3a8dcb0e6 100644 --- a/app/services/api_entreprise_service.rb +++ b/app/services/api_entreprise_service.rb @@ -74,5 +74,14 @@ class APIEntrepriseService false end end + + def api_djepva_up? + response = Typhoeus.get("https://entreprise.api.gouv.fr/ping/djepva/api-association", timeout: 1) + if response.success? + JSON.parse(response.body).fetch('status') == 'ok' + else + false + end + end end end diff --git a/spec/controllers/champs/rna_controller_spec.rb b/spec/controllers/champs/rna_controller_spec.rb index 89922e924..c85d49685 100644 --- a/spec/controllers/champs/rna_controller_spec.rb +++ b/spec/controllers/champs/rna_controller_spec.rb @@ -85,7 +85,7 @@ describe Champs::RNAController, type: :controller do let(:body) { File.read('spec/fixtures/files/api_entreprise/associations.json') } before do - expect(APIEntrepriseService).to receive(:api_up?).and_return(false) + expect(APIEntrepriseService).to receive(:api_djepva_up?).and_return(false) end subject! { get :show, params: params, format: :turbo_stream } diff --git a/spec/models/concern/rna_champ_association_fetchable_concern_spec.rb b/spec/models/concern/rna_champ_association_fetchable_concern_spec.rb index 4d8692786..cc200d357 100644 --- a/spec/models/concern/rna_champ_association_fetchable_concern_spec.rb +++ b/spec/models/concern/rna_champ_association_fetchable_concern_spec.rb @@ -52,7 +52,7 @@ RSpec.describe RNAChampAssociationFetchableConcern do let(:status) { 503 } let(:body) { File.read('spec/fixtures/files/api_entreprise/associations.json') } - before { expect(APIEntrepriseService).to receive(:api_up?).and_return(false) } + before { expect(APIEntrepriseService).to receive(:api_djepva_up?).and_return(false) } it_behaves_like "an association fetcher", false, :network_error, 'W595001988', nil end From 42f0b87c395858cf3a840c431a2acf2a4f561a82 Mon Sep 17 00:00:00 2001 From: simon lehericey Date: Fri, 5 Apr 2024 12:26:25 +0200 Subject: [PATCH 3/4] remove api_up? --- app/lib/api_entreprise/api.rb | 7 ---- app/services/api_entreprise_service.rb | 7 ---- .../fixtures/files/api_entreprise/status.json | 7 ---- spec/lib/api_entreprise/api_spec.rb | 14 -------- spec/services/api_entreprise_service_spec.rb | 32 ------------------- 5 files changed, 67 deletions(-) delete mode 100644 spec/fixtures/files/api_entreprise/status.json diff --git a/app/lib/api_entreprise/api.rb b/app/lib/api_entreprise/api.rb index db53afc5a..90f71b14e 100644 --- a/app/lib/api_entreprise/api.rb +++ b/app/lib/api_entreprise/api.rb @@ -83,13 +83,6 @@ class APIEntreprise::API call(url) end - def current_status - status_url = "https://status.entreprise.api.gouv.fr/summary.json" - response = Typhoeus.get(status_url, timeout: 1) - - handle_response(response) - end - private def recipient_for(siret_or_siren) diff --git a/app/services/api_entreprise_service.rb b/app/services/api_entreprise_service.rb index 3a8dcb0e6..5b0136c1d 100644 --- a/app/services/api_entreprise_service.rb +++ b/app/services/api_entreprise_service.rb @@ -58,13 +58,6 @@ class APIEntrepriseService APIEntreprise::AttestationFiscaleJob.set(wait:).perform_later(etablissement.id, procedure_id, user_id) end - def api_up? - APIEntreprise::API.new.current_status.fetch(:page).fetch(:status) == 'UP' - rescue => e - Sentry.capture_exception(e) - false - end - # See: https://entreprise.api.gouv.fr/developpeurs#surveillance-etat-fournisseurs def api_insee_up? response = Typhoeus.get("https://entreprise.api.gouv.fr/ping/insee/sirene", timeout: 1) diff --git a/spec/fixtures/files/api_entreprise/status.json b/spec/fixtures/files/api_entreprise/status.json deleted file mode 100644 index 7da318e25..000000000 --- a/spec/fixtures/files/api_entreprise/status.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "page": { - "name": "API Entreprise", - "url": "https://status.entreprise.api.gouv.fr", - "status": "UP" - } -} diff --git a/spec/lib/api_entreprise/api_spec.rb b/spec/lib/api_entreprise/api_spec.rb index 12110930f..89bc5297c 100644 --- a/spec/lib/api_entreprise/api_spec.rb +++ b/spec/lib/api_entreprise/api_spec.rb @@ -323,18 +323,4 @@ describe APIEntreprise::API do expect(WebMock).not_to have_requested(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/entreprises\/#{siren}/) end end - - describe 'current_status' do - subject { described_class.new.current_status } - let(:body) { Rails.root.join('spec/fixtures/files/api_entreprise/status.json').read } - - before do - stub_request(:get, "https://status.entreprise.api.gouv.fr/summary.json") - .to_return(body: body) - end - - it "returns the current status response" do - expect(subject).to eq(JSON.parse(body, symbolize_names: true)) - end - end end diff --git a/spec/services/api_entreprise_service_spec.rb b/spec/services/api_entreprise_service_spec.rb index 35d292ae8..5487e7e95 100644 --- a/spec/services/api_entreprise_service_spec.rb +++ b/spec/services/api_entreprise_service_spec.rb @@ -85,38 +85,6 @@ describe APIEntrepriseService do it_behaves_like 'schedule fetch of all etablissement params' end - describe "#api_up?" do - subject { described_class.api_up? } - let(:body) { Rails.root.join('spec/fixtures/files/api_entreprise/status.json').read } - let(:status) { 200 } - - before do - stub_request(:get, "https://status.entreprise.api.gouv.fr/summary.json") - .to_return(body: body, status: status) - end - - it "returns true when api etablissement is up" do - expect(subject).to be_truthy - end - - context "when api entreprise is down" do - let(:body) { Rails.root.join('spec/fixtures/files/api_entreprise/status.json').read.gsub('UP', 'HASISSUES') } - - it "returns false" do - expect(subject).to be_falsey - end - end - - context "when api entreprise status is unknown" do - let(:body) { "" } - let(:status) { 0 } - - it "returns nil" do - expect(subject).to be_falsey - end - end - end - describe "#api_insee_up?" do subject { described_class.api_insee_up? } let(:body) { Rails.root.join('spec/fixtures/files/api_entreprise/ping.json').read } From 2e2f4706c51a9521a4d06f2b1930e95a1831875d Mon Sep 17 00:00:00 2001 From: simon lehericey Date: Fri, 5 Apr 2024 12:26:32 +0200 Subject: [PATCH 4/4] deduplicate and add error management --- app/services/api_entreprise_service.rb | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/app/services/api_entreprise_service.rb b/app/services/api_entreprise_service.rb index 5b0136c1d..188f6d23d 100644 --- a/app/services/api_entreprise_service.rb +++ b/app/services/api_entreprise_service.rb @@ -60,21 +60,25 @@ class APIEntrepriseService # See: https://entreprise.api.gouv.fr/developpeurs#surveillance-etat-fournisseurs def api_insee_up? - response = Typhoeus.get("https://entreprise.api.gouv.fr/ping/insee/sirene", timeout: 1) - if response.success? - JSON.parse(response.body).fetch('status') == 'ok' - else - false - end + api_up?("https://entreprise.api.gouv.fr/ping/insee/sirene") end def api_djepva_up? - response = Typhoeus.get("https://entreprise.api.gouv.fr/ping/djepva/api-association", timeout: 1) + api_up?("https://entreprise.api.gouv.fr/ping/djepva/api-association") + end + + private + + def api_up?(url) + response = Typhoeus.get(url, timeout: 1) if response.success? JSON.parse(response.body).fetch('status') == 'ok' else false end + rescue => e + Sentry.capture_exception(e) + false end end end