Example #1
0
def ows_response_tween(request, handler):
    """Tween that wraps any API request with appropriate dispatch of error conversion to handle formatting."""
    try:
        result = handler(request)
        if hasattr(handler, OWS_TWEEN_HANDLED):
            if isinstance(result, Exception) and not isinstance(
                    result, (HTTPSuccessful, HTTPRedirection)):
                raise result  # let the previous tween handler handle this case
        return result
    # NOTE:
    #   Handle exceptions from most explicit definitions to least explicit.
    #   Exceptions in 'weaver.exceptions' sometimes derive from 'OWSException' to provide additional details.
    #   Furthermore, 'OWSException' have extensive details with references to 'HTTPException' and 'pywps.exceptions'.
    except HTTPException as err:
        LOGGER.debug("http exception -> ows exception response.")
        # Use the same json formatter than OWSException
        raised_error = err
        raised_error._json_formatter = OWSException.json_formatter
        return_error = raised_error
        exc_info_err = False
        exc_log_lvl = logging.WARNING if err.status_code < 500 else logging.ERROR
    except OWSException as err:  # could be 'WeaverException' with 'OWSException' base
        LOGGER.debug("direct ows exception response")
        raised_error = err
        return_error = err
        exc_info_err = False
        exc_log_lvl = logging.WARNING
    except NotImplementedError as err:
        LOGGER.debug("not implemented error -> ows exception response")
        raised_error = err
        return_error = OWSNotImplemented(str(err))
        exc_info_err = sys.exc_info()
        exc_log_lvl = logging.ERROR
    except Exception as err:
        LOGGER.debug("unhandled %s exception -> ows exception response",
                     type(err).__name__)
        raised_error = err
        return_error = OWSException(detail=str(err),
                                    status=HTTPInternalServerError)
        exc_info_err = sys.exc_info()
        exc_log_lvl = logging.ERROR
    # FIXME:
    #   https://github.com/crim-ca/weaver/issues/215
    #   convivial generation of this repr format should be directly in common exception class
    raised_err_code = getattr(raised_error, "code",
                              getattr(raised_error, "status_code", 500))
    raised_err_repr = "({}) <{}> {!s}".format(
        type(raised_error).__name__, raised_err_code, raised_error)
    if raised_error != return_error:
        err_msg = "\n  Raised: [{}]\n  Return: [{!r}]".format(
            raised_err_repr, return_error)
    else:
        err_msg = " [{}]".format(raised_err_repr)
    LOGGER.log(exc_log_lvl,
               "Handled request exception:%s",
               err_msg,
               exc_info=exc_info_err)
    LOGGER.debug("Handled request details:\n%s\n%s", raised_err_repr,
                 getattr(raised_error, "text", ""))
    return return_error
Example #2
0
def add_provider(request):
    """
    Add a provider.
    """
    store = get_db(request).get_store(StoreServices)

    try:
        new_service = Service(url=request.json["url"],
                              name=get_any_id(request.json))
    except KeyError as exc:
        raise OWSMissingParameterValue(
            "Missing json parameter '{!s}'.".format(exc), value=exc)

    if "public" in request.json:
        new_service["public"] = request.json["public"]
    if "auth" in request.json:
        new_service["auth"] = request.json["auth"]

    try:
        store.save_service(new_service)
    except NotImplementedError:
        raise OWSNotImplemented(
            sd.NotImplementedPostProviderResponse.description,
            value=new_service)

    return HTTPCreated(json=get_capabilities(new_service, request))
Example #3
0
def add_provider(request):
    # type: (PyramidRequest) -> AnyViewResponse
    """
    Register a new service provider.
    """
    schema = sd.CreateProviderRequestBody()
    schema_ref = get_schema_ref(schema, request)
    try:
        body = schema.deserialize(request.json)
    except colander.Invalid as invalid:
        data = {
            "description": f"Invalid schema: [{invalid!s}]",
            "value": invalid.value
        }
        data.update(schema_ref)
        raise HTTPBadRequest(json=data)

    store = get_db(request).get_store(StoreServices)
    prov_id = get_any_id(body)
    try:
        store.fetch_by_name(prov_id)
    except ServiceNotFound:
        pass
    else:
        raise HTTPConflict(f"Provider [{prov_id}] already exists.")
    try:
        new_service = Service(url=body["url"], name=prov_id)
    except KeyError as exc:
        raise OWSMissingParameterValue(f"Missing JSON parameter '{exc!s}'.",
                                       value=exc)

    if "public" in body:
        new_service["public"] = body["public"]
    if "auth" in body:
        new_service["auth"] = body["auth"]

    try:
        # validate that metadata or any pre-fetch operation can be resolved
        service = new_service.summary(request, fetch=True, ignore=False)
        if not service:
            raise colander.Invalid(None, value=body)
        store.save_service(new_service)
    except NotImplementedError:  # raised when supported service types / conversion
        raise OWSNotImplemented(
            sd.NotImplementedPostProviderResponse.description,
            value=new_service)
    except ServiceParsingError:  # derives from HTTPUnprocessableEntity with relevant error message
        raise
    except colander.Invalid as invalid:
        data = {
            "description":
            "Provider properties could not be parsed correctly.",
            "value": invalid.value
        }
        data.update(schema_ref)
        raise HTTPUnprocessableEntity(json=data)
    data = get_schema_ref(sd.ProviderSummarySchema, request)
    data.update(service)
    return HTTPCreated(json=data)
Example #4
0
def remove_provider(request):
    """
    Remove an existing service provider.
    """
    service, store = get_service(request)

    try:
        store.delete_service(service.name)
    except NotImplementedError:
        raise OWSNotImplemented(sd.NotImplementedDeleteProviderResponse.description)

    return HTTPNoContent(json={})