Projet

Général

Profil

0001-wscall-add-action-if-err-in-json-data-or-specific-he.patch

Thomas Noël, 24 août 2016 17:36

Télécharger (11,2 ko)

Voir les différences:

Subject: [PATCH] wscall: add action if err in json data or specific header
 (#12916)

 tests/test_workflows.py | 100 ++++++++++++++++++++++++++++++++++++++++++++++++
 tests/utilities.py      |   8 ++++
 wcs/wf/wscall.py        |  31 ++++++++++++---
 3 files changed, 134 insertions(+), 5 deletions(-)
tests/test_workflows.py
728 728
    formdata.workflow_data = None
729 729

  
730 730
    item = WebserviceCallStatusItem()
731
    item.url = 'http://remote.example.net/json-err0'
732
    item.post = False
733
    item.varname = 'xxx'
734
    item.perform(formdata)
735
    assert formdata.workflow_data['xxx_status'] == 200
736
    assert formdata.workflow_data['xxx_response'] == {'data': 'foo', 'err': 0}
737
    assert formdata.workflow_data.get('xxx_time')
738
    formdata.workflow_data = None
739

  
740
    item = WebserviceCallStatusItem()
741
    item.url = 'http://remote.example.net/json-err0'
742
    item.post = False
743
    item.varname = 'xxx'
744
    item.action_on_error_code = ':stop'
745
    item.perform(formdata)
746
    assert formdata.workflow_data['xxx_status'] == 200
747
    assert formdata.workflow_data['xxx_response'] == {'data': 'foo', 'err': 0}
748
    assert formdata.workflow_data.get('xxx_time')
749
    formdata.workflow_data = None
750

  
751
    item = WebserviceCallStatusItem()
752
    item.url = 'http://remote.example.net/json-err1'
753
    item.post = False
754
    item.varname = 'xxx'
755
    item.perform(formdata)
756
    assert formdata.workflow_data['xxx_status'] == 200
757
    assert formdata.workflow_data['xxx_response'] == {'data': '', 'err': 1}
758
    assert formdata.workflow_data.get('xxx_time')
759
    formdata.workflow_data = None
760

  
761
    item = WebserviceCallStatusItem()
762
    item.url = 'http://remote.example.net/json-err1'
763
    item.post = False
764
    item.varname = 'xxx'
765
    item.action_on_error_code = ':stop'
766
    with pytest.raises(AbortActionException):
767
        item.perform(formdata)
768
    assert formdata.workflow_data['xxx_status'] == 200
769
    assert formdata.workflow_data['xxx_error_response'] == {'data': '', 'err': 1}
770
    assert formdata.workflow_data.get('xxx_time')
771
    formdata.workflow_data = None
772

  
773
    item = WebserviceCallStatusItem()
774
    item.url = 'http://remote.example.net/json-errheader0'
775
    item.post = False
776
    item.varname = 'xxx'
777
    item.perform(formdata)
778
    assert formdata.workflow_data['xxx_status'] == 200
779
    assert formdata.workflow_data['xxx_error_header'] == 0
780
    assert formdata.workflow_data['xxx_response'] == {'foo': 'bar'}
781
    assert formdata.workflow_data.get('xxx_time')
782
    formdata.workflow_data = None
783

  
784
    item = WebserviceCallStatusItem()
785
    item.url = 'http://remote.example.net/json-errheader1'
786
    item.post = False
787
    item.varname = 'xxx'
788
    item.perform(formdata)
789
    assert formdata.workflow_data['xxx_status'] == 200
790
    assert formdata.workflow_data['xxx_error_header'] == 1
791
    assert formdata.workflow_data['xxx_error_response'] == {'foo': 'bar'}
792
    assert formdata.workflow_data.get('xxx_time')
793
    formdata.workflow_data = None
794

  
795
    item = WebserviceCallStatusItem()
796
    item.url = 'http://remote.example.net/json-errheader1'
797
    item.post = False
798
    item.varname = 'xxx'
799
    item.action_on_error_code = ':stop'
800
    with pytest.raises(AbortActionException):
801
        item.perform(formdata)
802
    assert formdata.workflow_data['xxx_status'] == 200
803
    assert formdata.workflow_data['xxx_error_header'] == 1
804
    assert formdata.workflow_data['xxx_error_response'] == {'foo': 'bar'}
805
    assert formdata.workflow_data.get('xxx_time')
806
    formdata.workflow_data = None
807

  
808
    item = WebserviceCallStatusItem()
731 809
    item.url = 'http://remote.example.net'
732 810
    item.post = False
733 811
    item.request_signature_key = 'xxx'
......
868 946
    formdata.workflow_data = None
869 947

  
870 948
    item = WebserviceCallStatusItem()
949
    item.url = 'http://remote.example.net/xml-errheader'
950
    item.post = False
951
    item.varname = 'xxx'
952
    item.response_type = 'attachment'
953
    item.record_errors = True
954
    item.perform(formdata)
955
    assert formdata.workflow_data.get('xxx_status') == 200
956
    assert formdata.workflow_data.get('xxx_error_header') == 1
957

  
958
    item = WebserviceCallStatusItem()
959
    item.url = 'http://remote.example.net/xml-errheader'
960
    item.post = False
961
    item.varname = 'xxx'
962
    item.response_type = 'attachment'
963
    item.record_errors = True
964
    item.action_on_error_code = ':stop'
965
    with pytest.raises(AbortActionException):
966
        item.perform(formdata)
967
    assert formdata.workflow_data.get('xxx_status') == 200
968
    assert formdata.workflow_data.get('xxx_error_header') == 1
969

  
970
    item = WebserviceCallStatusItem()
871 971
    item.url = 'http://remote.example.net/400-json'
872 972
    item.post = False
873 973
    item.record_errors = True
tests/utilities.py
250 250
            'http://remote.example.net/404-json': (404, '{"err": 1}', None),
251 251
            'http://remote.example.net/500': (500, 'internal server error', None),
252 252
            'http://remote.example.net/json': (200, '{"foo": "bar"}', None),
253
            'http://remote.example.net/json-err0': (200, '{"data": "foo", "err": 0}', None),
254
            'http://remote.example.net/json-err1': (200, '{"data": "", "err": 1}', None),
255
            'http://remote.example.net/json-errheader0': (200, '{"foo": "bar"}',
256
                                              {'x-passerelle-err': '0'}),
257
            'http://remote.example.net/json-errheader1': (200, '{"foo": "bar"}',
258
                                              {'x-passerelle-err': '1'}),
253 259
            'http://remote.example.net/xml': (200, '<?xml version="1.0"><foo/>',
254 260
                                              {'content-type': 'text/xml'}),
261
            'http://remote.example.net/xml-errheader': (200, '<?xml version="1.0"><foo/>',
262
                                              {'content-type': 'text/xml', 'x-passerelle-err': '1'}),
255 263
            }.get(base_url, (200, '', {}))
256 264

  
257 265
        class FakeResponse(object):
wcs/wf/wscall.py
109 109
    action_on_5xx = ':stop'
110 110
    action_on_bad_data = ':pass'
111 111
    action_on_network_errors = ':stop'
112
    action_on_error_code = ':pass'
112 113
    notify_on_errors = True
113 114
    record_errors = False
114 115

  
......
133 134
    def get_parameters(self):
134 135
        return ('url', 'post', 'varname', 'request_signature_key', 'post_data',
135 136
                'action_on_4xx', 'action_on_5xx', 'action_on_bad_data',
136
                'action_on_network_errors', 'notify_on_errors',
137
                'action_on_network_errors', 'action_on_error_code', 'notify_on_errors',
137 138
                'record_errors', 'label', 'method', 'response_type',
138 139
                'qs_data')
139 140

  
......
199 200
        error_actions.extend([(x.id, _('Jump to %s') % x.name) for x in
200 201
            self.parent.parent.possible_status])
201 202
        for attribute in ('action_on_4xx', 'action_on_5xx', 'action_on_network_errors',
202
                'action_on_bad_data'):
203
                'action_on_bad_data', 'action_on_error_code'):
203 204
            if not attribute in parameters:
204 205
                continue
205 206
            if attribute == 'action_on_bad_data':
......
213 214
                    'action_on_4xx': _('Action on HTTP error 4xx'),
214 215
                    'action_on_5xx': _('Action on HTTP error 5xx'),
215 216
                    'action_on_bad_data': _('Action on non-JSON response'),
216
                    'action_on_network_errors': _('Action on network errors')
217
                    'action_on_network_errors': _('Action on network errors'),
218
                    'action_on_error_code': _('Action on JSON or header error'),
217 219
                    }.get(attribute)
218 220
            form.add(SingleSelectWidget, '%s%s' % (prefix, attribute),
219 221
                    title=label,
......
249 251
            self.action_on_error(self.action_on_network_errors, formdata,
250 252
                    exc_info=sys.exc_info())
251 253

  
254
        error_code = 0
255
        error_code_header = response.getheader('x-passerelle-err')
256
        if error_code_header:
257
            # result is good only if header value is '0'
258
            try:
259
                error_code = int(error_code_header)
260
            except ValueError as e:
261
                error_code = error_code_header
262

  
252 263
        if self.varname:
253 264
            workflow_data = {
254 265
                '%s_status' % self.varname: status,
255 266
                '%s_time' % self.varname: datetime.datetime.now().isoformat(),
256 267
            }
268
            if error_code_header:
269
                workflow_data['%s_error_header' % self.varname] = error_code
257 270
            if status in (204, 205):
258 271
                pass # not returning any content
259
            elif (status // 100) == 2:
272
            elif (status // 100) == 2 and error_code == 0:
260 273
                self.store_response(formdata, response, data, workflow_data)
261 274
            else: # on error, record data if it is JSON
262 275
                try:
......
268 281
            formdata.update_workflow_data(workflow_data)
269 282
            formdata.store()
270 283

  
284
        if error_code != 0:
285
            self.action_on_error(self.action_on_error_code, formdata, response, data=data)
271 286
        if (status // 100) == 4:
272 287
            self.action_on_error(self.action_on_4xx, formdata, response, data=data)
273 288
        if (status // 100) == 5:
......
283 298
                self.action_on_error(self.action_on_bad_data, formdata,
284 299
                        response, data=data, exc_info=sys.exc_info())
285 300
            else:
301
                if d.get('err'):
302
                    workflow_data['%s_error_response' % self.varname] = d
303
                    formdata.update_workflow_data(workflow_data)
304
                    formdata.store()
305
                    self.action_on_error(self.action_on_error_code, formdata,
306
                                         response, data=data)
286 307
                workflow_data['%s_response' % self.varname] = d
287 308
                if isinstance(d.get('data'), dict) and d['data'].get('display_id'):
288 309
                    formdata.id_display = d.get('data', {}).get('display_id')
......
332 353
    def get_target_status(self):
333 354
        targets = []
334 355
        for attribute in ('action_on_4xx', 'action_on_5xx', 'action_on_bad_data',
335
                'action_on_network_errors'):
356
                'action_on_network_errors', 'action_on_error_code'):
336 357
            value = getattr(self, attribute)
337 358
            if value in (':pass', ':stop'):
338 359
                continue
339
-