From b75cff2fc36547011f1357cdda9177cba4aac1e0 Mon Sep 17 00:00:00 2001 From: Colin Darie Date: Wed, 20 Jul 2022 14:52:17 +0200 Subject: [PATCH] refactor: API Entreprise instancified, more flexible for various input params MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit En fonction des resources, l'API est appelée : - dans le contexte d'une Procedure ou non - avec ou sans token injecté - avec ou sans siret/siren - avec ou sans user --- app/lib/api_entreprise/adapter.rb | 4 + app/lib/api_entreprise/api.rb | 136 ++++++++++-------- .../attestation_fiscale_adapter.rb | 2 +- .../attestation_sociale_adapter.rb | 2 +- app/lib/api_entreprise/bilans_bdf_adapter.rb | 2 +- app/lib/api_entreprise/effectifs_adapter.rb | 2 +- .../effectifs_annuels_adapter.rb | 2 +- app/lib/api_entreprise/entreprise_adapter.rb | 2 +- .../api_entreprise/etablissement_adapter.rb | 2 +- app/lib/api_entreprise/exercices_adapter.rb | 2 +- app/lib/api_entreprise/privileges_adapter.rb | 4 +- app/lib/api_entreprise/rna_adapter.rb | 2 +- spec/lib/api_entreprise/api_spec.rb | 18 +-- 13 files changed, 98 insertions(+), 82 deletions(-) diff --git a/app/lib/api_entreprise/adapter.rb b/app/lib/api_entreprise/adapter.rb index 84655a9b2..6cb4411c2 100644 --- a/app/lib/api_entreprise/adapter.rb +++ b/app/lib/api_entreprise/adapter.rb @@ -6,6 +6,10 @@ class APIEntreprise::Adapter @procedure_id = procedure_id end + def api(procedure_id = nil) + APIEntreprise::API.new(procedure_id) + end + def data_source begin @data_source ||= get_resource diff --git a/app/lib/api_entreprise/api.rb b/app/lib/api_entreprise/api.rb index 9f92f5cad..8cf3de86b 100644 --- a/app/lib/api_entreprise/api.rb +++ b/app/lib/api_entreprise/api.rb @@ -13,54 +13,76 @@ class APIEntreprise::API TIMEOUT = 20 DEFAULT_API_ENTREPRISE_DELAY = 0.0 - def self.entreprise(siren, procedure_id) - call_with_siret(ENTREPRISE_RESOURCE_NAME, siren, procedure_id) + attr_reader :procedure + attr_accessor :token + + def initialize(procedure_id = nil) + return if procedure_id.blank? + + @procedure = Procedure.find(procedure_id) + @token = @procedure.api_entreprise_token end - def self.etablissement(siret, procedure_id) - call_with_siret(ETABLISSEMENT_RESOURCE_NAME, siret, procedure_id) + def entreprise(siren) + call_with_siret(ENTREPRISE_RESOURCE_NAME, siren) end - def self.exercices(siret, procedure_id) - call_with_siret(EXERCICES_RESOURCE_NAME, siret, procedure_id) + def etablissement(siret) + call_with_siret(ETABLISSEMENT_RESOURCE_NAME, siret) end - def self.rna(siret, procedure_id) - call_with_siret(RNA_RESOURCE_NAME, siret, procedure_id) + def exercices(siret) + call_with_siret(EXERCICES_RESOURCE_NAME, siret) end - def self.effectifs(siren, procedure_id, annee, mois) + def rna(siret) + call_with_siret(RNA_RESOURCE_NAME, siret) + end + + def effectifs(siren, annee, mois) endpoint = [EFFECTIFS_RESOURCE_NAME, annee, mois, "entreprise"].join('/') - call_with_siret(endpoint, siren, procedure_id) + call_with_siret(endpoint, siren) end - def self.effectifs_annuels(siren, procedure_id) - call_with_siret(EFFECTIFS_ANNUELS_RESOURCE_NAME, siren, procedure_id) + def effectifs_annuels(siren) + call_with_siret(EFFECTIFS_ANNUELS_RESOURCE_NAME, siren) end - def self.attestation_sociale(siren, procedure_id) - procedure = Procedure.find(procedure_id) - call_with_siret(ATTESTATION_SOCIALE_RESOURCE_NAME, siren, procedure_id) if procedure.api_entreprise_role?("attestations_sociales") + def attestation_sociale(siren) + return unless procedure.api_entreprise_role?("attestations_sociales") + + call_with_siret(ATTESTATION_SOCIALE_RESOURCE_NAME, siren) end - def self.attestation_fiscale(siren, procedure_id, user_id) - procedure = Procedure.find(procedure_id) - call_with_siret(ATTESTATION_FISCALE_RESOURCE_NAME, siren, procedure_id, user_id) if procedure.api_entreprise_role?("attestations_fiscales") + def attestation_fiscale(siren, user_id) + return unless procedure.api_entreprise_role?("attestations_fiscales") + + call_with_siret(ATTESTATION_FISCALE_RESOURCE_NAME, siren, user_id: user_id) end - def self.bilans_bdf(siren, procedure_id) - procedure = Procedure.find(procedure_id) - call_with_siret(BILANS_BDF_RESOURCE_NAME, siren, procedure_id) if procedure.api_entreprise_role?("bilans_entreprise_bdf") + def bilans_bdf(siren) + return unless procedure.api_entreprise_role?("bilans_entreprise_bdf") + + call_with_siret(BILANS_BDF_RESOURCE_NAME, siren) end - def self.privileges(token) - call_with_token(PRIVILEGES_RESOURCE_NAME, token) + def privileges + url = make_url(PRIVILEGES_RESOURCE_NAME) + call(url) end private - def self.call_with_token(resource_name, token) - url = "#{API_ENTREPRISE_URL}/#{resource_name}" + def call_with_siret(resource_name, siret_or_siren, user_id: nil) + url = make_url(resource_name, siret_or_siren) + + params = build_params(user_id) + + call(url, params) + end + + def call(url, params = nil) + verify_token! # this is a poor man throttling # the idea is to queue api entreprise job on 1 worker @@ -72,32 +94,13 @@ class APIEntreprise::API response = Typhoeus.get(url, headers: { Authorization: "Bearer #{token}" }, - timeout: TIMEOUT) - - if response.success? - JSON.parse(response.body, symbolize_names: true) - else - raise RequestFailed.new(response) - end - end - - def self.call_with_siret(resource_name, siret_or_siren, procedure_id, user_id = nil) - if APIEntrepriseToken.new(token_for_procedure(procedure_id)).expired? - raise APIEntrepriseToken::TokenError, I18n.t("api_entreprise.errors.token_expired") - end - - url = url(resource_name, siret_or_siren) - params = params(siret_or_siren, procedure_id, user_id) - - if api_entreprise_delay != 0.0 - sleep api_entreprise_delay - end - - response = Typhoeus.get(url, - headers: { Authorization: "Bearer #{token_for_procedure(procedure_id)}" }, params: params, timeout: TIMEOUT) + handle_response(response) + end + + def handle_response(response) if response.success? JSON.parse(response.body, symbolize_names: true) elsif response.code&.between?(401, 499) @@ -115,29 +118,36 @@ class APIEntreprise::API end end - def self.url(resource_name, siret_or_siren) - [API_ENTREPRISE_URL, resource_name, siret_or_siren].join("/") + def make_url(resource_name, siret_or_siren = nil) + [API_ENTREPRISE_URL, resource_name, siret_or_siren].compact.join("/") end - def self.params(siret_or_siren, procedure_id, user_id) - # rubocop:disable DS/ApplicationName - params = { - context: "demarches-simplifiees.fr", - recipient: ENV.fetch('API_ENTREPRISE_DEFAULT_SIRET'), - object: "procedure_id: #{procedure_id}", - non_diffusables: true - } - # rubocop:enable DS/ApplicationName + def build_params(user_id) + params = base_params + + params[:object] = "procedure_id: #{procedure.id}" if procedure.present? params[:user_id] = user_id if user_id.present? + params end - def self.token_for_procedure(procedure_id) - procedure = Procedure.find(procedure_id) - procedure.api_entreprise_token + def base_params + # rubocop:disable DS/ApplicationName + { + context: "demarches-simplifiees.fr", + recipient: ENV.fetch('API_ENTREPRISE_DEFAULT_SIRET'), + non_diffusables: true + } + # rubocop:enable DS/ApplicationName end - def self.api_entreprise_delay + def api_entreprise_delay ENV.fetch("API_ENTREPRISE_DELAY", DEFAULT_API_ENTREPRISE_DELAY).to_f end + + def verify_token! + return unless APIEntrepriseToken.new(token).expired? + + raise APIEntrepriseToken::TokenError, I18n.t("api_entreprise.errors.token_expired") + end end diff --git a/app/lib/api_entreprise/attestation_fiscale_adapter.rb b/app/lib/api_entreprise/attestation_fiscale_adapter.rb index e776dc48d..885e74956 100644 --- a/app/lib/api_entreprise/attestation_fiscale_adapter.rb +++ b/app/lib/api_entreprise/attestation_fiscale_adapter.rb @@ -8,7 +8,7 @@ class APIEntreprise::AttestationFiscaleAdapter < APIEntreprise::Adapter private def get_resource - APIEntreprise::API.attestation_fiscale(siren, @procedure_id, @user_id) + api(@procedure_id).attestation_fiscale(siren, @user_id) end def process_params diff --git a/app/lib/api_entreprise/attestation_sociale_adapter.rb b/app/lib/api_entreprise/attestation_sociale_adapter.rb index 551b042b2..0aad5b18d 100644 --- a/app/lib/api_entreprise/attestation_sociale_adapter.rb +++ b/app/lib/api_entreprise/attestation_sociale_adapter.rb @@ -7,7 +7,7 @@ class APIEntreprise::AttestationSocialeAdapter < APIEntreprise::Adapter private def get_resource - APIEntreprise::API.attestation_sociale(siren, @procedure_id) + api(@procedure_id).attestation_sociale(siren) end def process_params diff --git a/app/lib/api_entreprise/bilans_bdf_adapter.rb b/app/lib/api_entreprise/bilans_bdf_adapter.rb index 7e8de8932..c50d689b6 100644 --- a/app/lib/api_entreprise/bilans_bdf_adapter.rb +++ b/app/lib/api_entreprise/bilans_bdf_adapter.rb @@ -7,7 +7,7 @@ class APIEntreprise::BilansBdfAdapter < APIEntreprise::Adapter private def get_resource - APIEntreprise::API.bilans_bdf(siren, @procedure_id) + api(@procedure_id).bilans_bdf(siren) end def process_params diff --git a/app/lib/api_entreprise/effectifs_adapter.rb b/app/lib/api_entreprise/effectifs_adapter.rb index 55c31e853..55011d6ac 100644 --- a/app/lib/api_entreprise/effectifs_adapter.rb +++ b/app/lib/api_entreprise/effectifs_adapter.rb @@ -9,7 +9,7 @@ class APIEntreprise::EffectifsAdapter < APIEntreprise::Adapter private def get_resource - APIEntreprise::API.effectifs(siren, @procedure_id, @annee, @mois) + api(@procedure_id).effectifs(siren, @annee, @mois) end def process_params diff --git a/app/lib/api_entreprise/effectifs_annuels_adapter.rb b/app/lib/api_entreprise/effectifs_annuels_adapter.rb index 0dba6ae4b..62df2607e 100644 --- a/app/lib/api_entreprise/effectifs_annuels_adapter.rb +++ b/app/lib/api_entreprise/effectifs_annuels_adapter.rb @@ -7,7 +7,7 @@ class APIEntreprise::EffectifsAnnuelsAdapter < APIEntreprise::Adapter private def get_resource - APIEntreprise::API.effectifs_annuels(siren, @procedure_id) + api(@procedure_id).effectifs_annuels(siren) end def process_params diff --git a/app/lib/api_entreprise/entreprise_adapter.rb b/app/lib/api_entreprise/entreprise_adapter.rb index 90176e21d..2c1ed0cb1 100644 --- a/app/lib/api_entreprise/entreprise_adapter.rb +++ b/app/lib/api_entreprise/entreprise_adapter.rb @@ -2,7 +2,7 @@ class APIEntreprise::EntrepriseAdapter < APIEntreprise::Adapter private def get_resource - APIEntreprise::API.entreprise(siren, @procedure_id) + api(@procedure_id).entreprise(siren) end def process_params diff --git a/app/lib/api_entreprise/etablissement_adapter.rb b/app/lib/api_entreprise/etablissement_adapter.rb index eb8312d59..95eb20425 100644 --- a/app/lib/api_entreprise/etablissement_adapter.rb +++ b/app/lib/api_entreprise/etablissement_adapter.rb @@ -2,7 +2,7 @@ class APIEntreprise::EtablissementAdapter < APIEntreprise::Adapter private def get_resource - APIEntreprise::API.etablissement(@siret, @procedure_id) + api(@procedure_id).etablissement(@siret) end def process_params diff --git a/app/lib/api_entreprise/exercices_adapter.rb b/app/lib/api_entreprise/exercices_adapter.rb index dc2cbd45f..f983e069d 100644 --- a/app/lib/api_entreprise/exercices_adapter.rb +++ b/app/lib/api_entreprise/exercices_adapter.rb @@ -2,7 +2,7 @@ class APIEntreprise::ExercicesAdapter < APIEntreprise::Adapter private def get_resource - APIEntreprise::API.exercices(@siret, @procedure_id) + api(@procedure_id).exercices(@siret) end def process_params diff --git a/app/lib/api_entreprise/privileges_adapter.rb b/app/lib/api_entreprise/privileges_adapter.rb index 745102b9d..7c4d9ad76 100644 --- a/app/lib/api_entreprise/privileges_adapter.rb +++ b/app/lib/api_entreprise/privileges_adapter.rb @@ -15,6 +15,8 @@ class APIEntreprise::PrivilegesAdapter < APIEntreprise::Adapter private def get_resource - APIEntreprise::API.privileges(@token) + api.tap do + _1.token = @token + end.privileges end end diff --git a/app/lib/api_entreprise/rna_adapter.rb b/app/lib/api_entreprise/rna_adapter.rb index a616cb19a..3aa7385fb 100644 --- a/app/lib/api_entreprise/rna_adapter.rb +++ b/app/lib/api_entreprise/rna_adapter.rb @@ -2,7 +2,7 @@ class APIEntreprise::RNAAdapter < APIEntreprise::Adapter private def get_resource - APIEntreprise::API.rna(@siret, @procedure_id) + api(@procedure_id).rna(@siret) end def process_params diff --git a/spec/lib/api_entreprise/api_spec.rb b/spec/lib/api_entreprise/api_spec.rb index 03021f6f0..67fd41f58 100644 --- a/spec/lib/api_entreprise/api_spec.rb +++ b/spec/lib/api_entreprise/api_spec.rb @@ -4,7 +4,7 @@ describe APIEntreprise::API do let(:token) { Rails.application.secrets.api_entreprise[:key] } describe '.entreprise' do - subject { described_class.entreprise(siren, procedure_id) } + subject { described_class.new(procedure_id).entreprise(siren) } before do stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/entreprises\/#{siren}/) @@ -85,7 +85,7 @@ describe APIEntreprise::API do end describe '.etablissement' do - subject { described_class.etablissement(siret, procedure_id) } + subject { described_class.new(procedure_id).etablissement(siret) } before do stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret}?.*non_diffusables=true/) .to_return(status: status, body: body) @@ -121,7 +121,7 @@ describe APIEntreprise::API do end context 'when siret does not exist' do - subject { described_class.exercices(siret, procedure_id) } + subject { described_class.new(procedure_id).exercices(siret) } let(:siret) { '11111111111111' } let(:status) { 404 } @@ -133,7 +133,7 @@ describe APIEntreprise::API do end context 'when siret exists' do - subject { described_class.exercices(siret, procedure_id) } + subject { described_class.new(procedure_id).exercices(siret) } let(:siret) { '41816609600051' } let(:status) { 200 } @@ -152,7 +152,7 @@ describe APIEntreprise::API do allow_any_instance_of(APIEntrepriseToken).to receive(:expired?).and_return(false) end - subject { described_class.rna(siren, procedure_id) } + subject { described_class.new(procedure_id).rna(siren) } context 'when siren does not exist' do let(:siren) { '111111111' } @@ -186,7 +186,7 @@ describe APIEntreprise::API do .to_return(body: body, status: status) end - subject { described_class.attestation_sociale(siren, procedure.id) } + subject { described_class.new(procedure.id).attestation_sociale(siren) } context 'when token not authorized' do let(:roles) { ["entreprises"] } @@ -215,7 +215,7 @@ describe APIEntreprise::API do .to_return(body: body, status: status) end - subject { described_class.attestation_fiscale(siren, procedure.id, user_id) } + subject { described_class.new(procedure.id).attestation_fiscale(siren, user_id) } context 'when token not authorized' do let(:roles) { ["entreprises"] } @@ -243,7 +243,7 @@ describe APIEntreprise::API do .to_return(body: body, status: status) end - subject { described_class.bilans_bdf(siren, procedure.id) } + subject { described_class.new(procedure.id).bilans_bdf(siren) } context 'when token not authorized' do let(:roles) { ["entreprises"] } @@ -260,7 +260,7 @@ describe APIEntreprise::API do describe 'with expired token' do let(:siren) { '111111111' } - subject { described_class.entreprise(siren, procedure_id) } + subject { described_class.new(procedure_id).entreprise(siren) } before do allow_any_instance_of(APIEntrepriseToken).to receive(:expired?).and_return(true)