From 7773efc8f7d4b96269d6d726277e9811dcd5b36a Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Wed, 23 Mar 2022 07:12:41 +0100 Subject: [PATCH 05/11] wip: on soaperror set availability of connector to down when retrieving the WSDL schema --- passerelle/apps/soap/models.py | 21 +++++++++++++++++++-- tests/test_soap.py | 10 ++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/passerelle/apps/soap/models.py b/passerelle/apps/soap/models.py index 0965fe5c..ad713ad6 100644 --- a/passerelle/apps/soap/models.py +++ b/passerelle/apps/soap/models.py @@ -21,11 +21,13 @@ import zeep.exceptions import zeep.helpers import zeep.xsd from django.db import models +from django.forms import ValidationError from django.utils.functional import cached_property from django.utils.translation import ugettext_lazy as _ from passerelle.base.models import BaseResource, HTTPResource from passerelle.utils.api import endpoint +from passerelle.utils.conversion import exception_to_text from passerelle.utils.json import unflatten @@ -42,6 +44,12 @@ class SOAPConnector(BaseResource, HTTPResource): class Meta: verbose_name = _('SOAP connector') + def clean(self): + try: + self.operations_and_schemas + except Exception as e: + raise ValidationError(e) + @classmethod def get_manager_form_class(cls, **kwargs): form_class = super().get_manager_form_class(**kwargs) @@ -107,7 +115,14 @@ class SOAPConnector(BaseResource, HTTPResource): def get_endpoints_infos(self): endpoints = super().get_endpoints_infos() - for name, input_schema, output_schema in self.operations_and_schemas: + + try: + operations_and_schemas = self.operations_and_schemas + except Exception as e: + self.set_availability_status('down', message=exception_to_text(e)[:500]) + return endpoints + + for name, input_schema, output_schema in operations_and_schemas: kwargs = dict( name='method', pattern=f'{name}/', @@ -137,13 +152,15 @@ class SOAPConnector(BaseResource, HTTPResource): @property def operations_and_schemas(self): operations = self.client.service._binding._operations + operations_and_schemas = [] for name in operations: operation = operations[name] input_type = operation.input.body.type output_type = operation.output.body.type input_schema = self.type2schema(input_type, keep_root=True) output_schema = self.type2schema(output_type, compress=True) - yield name, input_schema, output_schema + operations_and_schemas.append((name, input_schema, output_schema)) + return operations_and_schemas def type2schema(self, xsd_type, keep_root=False, compress=False): # simplify schema: when a type contains a unique element, it will try diff --git a/tests/test_soap.py b/tests/test_soap.py index b50063f3..ebcb2592 100644 --- a/tests/test_soap.py +++ b/tests/test_soap.py @@ -251,6 +251,10 @@ class SOAP12(SOAP11): } +class BrokenSOAP12(SOAP12): + WSDL_CONTENT = SOAP12.WSDL_CONTENT[-100:] # truncate the WSDL to break it + + @pytest.fixture(params=[SOAP11, SOAP12]) def soap(request): p = request.param() @@ -272,6 +276,12 @@ class TestManage: response = app.get(f'/soap/{connector.slug}/') assert 'Method sayHello' in response + @pytest.mark.parametrize('soap', [BrokenSOAP12], indirect=True) + def test_homepage_broken_wsdl(self, app, connector, soap): + response = app.get(f'/soap/{connector.slug}/') + response = app.get(f'/soap/{connector.slug}/') + assert response.pyquery('.down') + @pytest.fixture def connector(db, soap): -- 2.35.1