def test_invalid_service(example_thrift_manager):
    request = _build_request(service_name="notaservice")
    assert [
        Error(
            code=ErrorCode.SERVICE_NOT_IN_THRIFT,
            message="Service 'notaservice' not in thrift 'todo.thrift'",
        )
    ] == example_thrift_manager.validate_request(request)
def test_invalid_endpoint(example_thrift_manager):
    request = _build_request(endpoint_name="notanendpoint")
    assert [
        Error(
            code=ErrorCode.ENDPOINT_NOT_IN_SERVICE,
            message=
            "Endpoint 'notanendpoint' not in service 'TodoService' in thrift 'todo.thrift'",
        )
    ] == example_thrift_manager.validate_request(request)
def test_thrift_not_loaded(example_thrift_manager):
    request = _build_request(thrift_file="notathrift.thrift")
    assert [
        Error(
            code=ErrorCode.THRIFT_NOT_LOADED,
            message=
            "Thrift File 'notathrift.thrift' not loaded in ThriftManager",
        )
    ] == example_thrift_manager.validate_request(request)
示例#4
0
    def validate_request(self, thrift_request):
        try:
            thrift_spec = self.service_specs[thrift_request.thrift_file]
        except KeyError:
            return [
                Error(
                    code=ErrorCode.THRIFT_NOT_LOADED,
                    message="Thrift File '{}' not loaded in ThriftManager".format(
                        thrift_request.thrift_file
                    ),
                )
            ]
        try:
            service_spec = thrift_spec[thrift_request.service_name]
        except KeyError:
            return [
                Error(
                    code=ErrorCode.SERVICE_NOT_IN_THRIFT,
                    message="Service '{}' not in thrift '{}'".format(
                        thrift_request.service_name, thrift_request.thrift_file
                    ),
                )
            ]
        try:
            endpoint_spec = service_spec.endpoints[thrift_request.endpoint_name]
        except KeyError:
            return [
                Error(
                    code=ErrorCode.ENDPOINT_NOT_IN_SERVICE,
                    message="Endpoint '{}' not in service '{}' in thrift '{}'".format(
                        thrift_request.endpoint_name,
                        thrift_request.service_name,
                        thrift_request.thrift_file,
                    ),
                )
            ]

        validation_errors = []
        for arg_spec in endpoint_spec.args:
            try:
                error = arg_spec.type_info.validate_arg(
                    thrift_request.request_body[arg_spec.name]
                )
                if error:
                    validation_errors.append(
                        FieldError(
                            arg_spec=arg_spec,
                            code=ErrorCode.FIELD_VALIDATION_ERROR,
                            message=error,
                        )
                    )
            except KeyError:
                if arg_spec.required:
                    validation_errors.append(
                        FieldError(
                            arg_spec=arg_spec,
                            code=ErrorCode.REQUIRED_FIELD_MISSING,
                            message="Required Field '{}' not found".format(
                                arg_spec.name
                            ),
                        )
                    )
        return validation_errors
示例#5
0
    def service_method(thrift, service, method):
        thrift = _add_extension_if_needed(thrift)
        error = _validate_args(thrift, service, method)
        method = thrift_manager.get_method(thrift, service, method)
        if error:
            return error
        if request.method == "POST":
            request_json = request.get_json(force=True)
            errors = []
            try:
                thrift_request = ThriftRequest(
                    thrift_file=thrift,
                    service_name=service,
                    endpoint_name=method.name,
                    host=request_json.get("host"),
                    port=request_json.get("port"),
                    protocol=request_json.get(
                        "protocol", app.config[DEFAULT_PROTOCOL_ENV]),
                    transport=request_json.get(
                        "transport", app.config[DEFAULT_TRANSPORT_ENV]),
                    request_body=request_json.get("request_body"),
                )
                errors = thrift_manager.validate_request(thrift_request)
            except ValueError as e:
                errors = [
                    Error(code=ErrorCode.INVALID_REQUEST, message=str(e))
                ]
            except TypeError as e:
                errors = [
                    Error(code=ErrorCode.INVALID_REQUEST,
                          message=str(e.args[0]))
                ]

            if errors:
                return (
                    json.dumps(
                        {
                            "errors": [
                                attr.asdict(error, recurse=True)
                                for error in errors
                            ]
                        },
                        cls=CommunicationModelEncoder,
                    ),
                    400,
                )
            else:
                return (
                    json.dumps(
                        attr.asdict(
                            thrift_manager.make_request(thrift_request),
                            recurse=True),
                        cls=CommunicationModelEncoder,
                    ),
                    200,
                    JSON_CONTENT_TYPE,
                )
        else:
            return (
                json.dumps(
                    attr.asdict(
                        ThriftRequest(
                            thrift_file=thrift,
                            service_name=service,
                            endpoint_name=method.name,
                            host="<hostname>",
                            port=9090,
                            protocol=app.config[DEFAULT_PROTOCOL_ENV],
                            transport=app.config[DEFAULT_TRANSPORT_ENV],
                            request_body={},
                        ),
                        recurse=True,
                    ),
                    cls=CommunicationModelEncoder,
                ),
                200,
                JSON_CONTENT_TYPE,
            )