From 9cba7f23f30578abb9493e5a792832f8f03a7ddf Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Wed, 23 Mar 2022 07:12:41 +0100 Subject: [PATCH 5/9] wip: on soaperror set availability of connector to down when retrieving the WSDL schema --- passerelle/apps/soap/models.py | 21 +++++++++++++++++++-- passerelle/base/models.py | 4 ++-- tests/test_soap.py | 10 ++++++++++ 3 files changed, 31 insertions(+), 4 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/passerelle/base/models.py b/passerelle/base/models.py index 76c9f656..9215870f 100644 --- a/passerelle/base/models.py +++ b/passerelle/base/models.py @@ -280,7 +280,7 @@ class BaseResource(models.Model): def get_endpoints_infos(self): endpoints = [] - for name, method in inspect.getmembers(self, predicate=inspect.ismethod): + for name, method in inspect.getmembers(type(self), predicate=inspect.isfunction): if hasattr(method, 'endpoint_info'): method.endpoint_info.object = self endpoint_name = method.endpoint_info.name @@ -499,7 +499,7 @@ class BaseResource(models.Model): except Exception as e: from passerelle.utils.conversion import exception_to_text - self.set_availability('down', message=exception_to_text(e)[:500]) + self.set_availability_status('down', message=exception_to_text(e)[:500]) else: self.set_availability_status('up') 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