Exemple #1
0
def delete_local_process(request):
    # type: (PyramidRequest) -> AnyViewResponse
    """
    Unregister a local process.
    """
    db = get_db(request)
    proc_store = db.get_store(StoreProcesses)
    process = get_process(request=request)
    process_id = process.id
    if not process.mutable:
        raise HTTPForbidden(json={
            "title": "Process immutable.",
            "type": "ProcessImmutable",
            "detail": "Cannot delete an immutable process.",
            "status": HTTPForbidden.code,
            "cause": {"mutable": False}
        })
    job_store = db.get_store(StoreJobs)
    jobs, total = job_store.find_jobs(process=process_id, status=Status.RUNNING, page=None, limit=None)
    if total != 0:
        raise HTTPForbidden(json={
            "title": "ProcessBusy",
            "type": "ProcessBusy",
            "detail": "Process with specified identifier is in use by a least one job and cannot be undeployed.",
            "status": HTTPForbidden.code,
            "cause": {"jobs": [str(job.id) for job in jobs]}
        })
    if proc_store.delete_process(process_id, visibility=Visibility.PUBLIC):
        return HTTPOk(json={
            "description": sd.OkDeleteProcessResponse.description,
            "identifier": process_id,
            "undeploymentDone": True,
        })
    LOGGER.error("Existing process [%s] should have been deleted with success status.", process_id)
    raise HTTPForbidden("Deletion of process has been refused by the database or could not have been validated.")
Exemple #2
0
def submit_local_job(request):
    """
    Execute a local process.
    """
    process = get_process(request=request)
    body = submit_job(request, process, tags=["wps-rest"])
    return get_job_submission_response(body)
Exemple #3
0
def get_local_process_payload(request):
    # type: (PyramidRequest) -> AnyViewResponse
    """
    Get a registered local process payload definition.
    """
    process = get_process(request=request)
    return HTTPOk(json=process.payload or {})
Exemple #4
0
def get_process_visibility(request):
    # type: (PyramidRequest) -> AnyViewResponse
    """
    Get the visibility of a registered local process.
    """
    process = get_process(request=request)
    return HTTPOk(json={u"value": process.visibility})
Exemple #5
0
def submit_local_job(request):
    """
    Execute a process registered locally.

    Execution location and method is according to deployed Application Package.
    """
    process = get_process(request=request)
    body = submit_job(request, process, tags=["wps-rest"])
    return get_job_submission_response(body)
Exemple #6
0
def put_local_process(request):
    # type: (PyramidRequest) -> AnyViewResponse
    """
    Update a registered local process with a new definition.

    Updates the new process MAJOR semantic version from the previous one if not specified explicitly.
    For MINOR or PATCH changes to metadata of the process definition, consider using the PATCH request.
    """
    process = get_process(request=request, revision=False)  # ignore tagged version since must always be latest
    return deploy_process_from_payload(request.text, request, overwrite=process)
Exemple #7
0
def get_local_process(request):
    """
    Get a registered local process information (DescribeProcess).
    """
    try:
        process = get_process(request=request)
        process["inputs"] = opensearch.replace_inputs_describe_process(
            process.inputs, process.payload)
        process_offering = process.process_offering()
        return HTTPOk(json=process_offering)
    except colander.Invalid as ex:
        raise HTTPBadRequest("Invalid schema: [{!s}]".format(ex))
Exemple #8
0
    def _submit_job(self, wps_request):
        # type: (WPSRequest) -> Union[WPSResponse, HTTPValid, JSON]
        """
        Dispatch operation to WPS-REST endpoint, which in turn should call back the real Celery Worker for execution.

        Returns the status response as is if XML, or convert it to JSON, according to request ``Accept`` header.
        """
        req = wps_request.http_request
        pid = wps_request.identifier
        ctx = get_wps_output_context(
            req
        )  # re-validate here in case submitted via WPS endpoint instead of REST-API
        proc = get_process(
            process_id=pid,
            settings=self.settings)  # raises if invalid or missing
        wps_process = self.processes.get(pid)

        # create the JSON payload from the XML content and submit job
        is_workflow = proc.type == ProcessType.WORKFLOW
        tags = req.args.get(
            "tags", "").split(",") + ["xml", f"wps-{wps_request.version}"]
        data = wps2json_job_payload(wps_request, wps_process)
        resp = submit_job_handler(data,
                                  self.settings,
                                  proc.processEndpointWPS1,
                                  process_id=pid,
                                  is_local=True,
                                  is_workflow=is_workflow,
                                  visibility=Visibility.PUBLIC,
                                  language=wps_request.language,
                                  tags=tags,
                                  headers=dict(req.headers),
                                  context=ctx)
        # enforced JSON results with submitted data that includes 'response=document'
        # use 'json_body' to work with any 'response' implementation
        body = resp.json_body

        # if Accept was JSON, provide response content as is
        # if anything else (even */*), return as XML
        # NOTE:
        #   It is very important to respect default XML since 'owslib.wps.WebProcessingService' does not provide any
        #   way to provide explicitly Accept header. Even our Wps1Process as Workflow step depends on this behaviour.
        accept_type = get_header("Accept", req.headers)
        if accept_type == ContentType.APP_JSON:
            resp = get_job_submission_response(body, resp.headers)
            setattr(
                resp, "_update_status",
                lambda *_, **__: None)  # patch to avoid pywps server raising
            return resp

        return body
Exemple #9
0
def get_local_process(request):
    """
    Get a registered local process information (DescribeProcess).
    """
    try:
        process = get_process(request=request)
        process["inputs"] = opensearch.replace_inputs_describe_process(
            process.inputs, process.payload)
        schema = request.params.get("schema")
        offering = process.offering(schema)
        return HTTPOk(json=offering)
    # FIXME: handle colander invalid directly in tween (https://github.com/crim-ca/weaver/issues/112)
    except colander.Invalid as ex:
        raise HTTPBadRequest("Invalid schema: [{!s}]\nValue: [{!s}]".format(
            ex, ex.value))
Exemple #10
0
def get_local_process(request):
    # type: (PyramidRequest) -> AnyViewResponse
    """
    Get a registered local process information (DescribeProcess).
    """
    try:
        process = get_process(request=request)
        process["inputs"] = opensearch.replace_inputs_describe_process(process.inputs, process.payload)
        schema = request.params.get("schema")
        ctype = guess_target_format(request)
        if ctype in ContentType.ANY_XML or str(schema).upper() == ProcessSchema.WPS:
            offering = process.offering(ProcessSchema.WPS, request=request)
            return Response(offering, content_type=add_content_type_charset(ContentType.APP_XML, "UTF-8"))
        else:
            offering = process.offering(schema)
            return HTTPOk(json=offering)
    # FIXME: handle colander invalid directly in tween (https://github.com/crim-ca/weaver/issues/112)
    except colander.Invalid as ex:
        raise HTTPBadRequest(f"Invalid schema: [{ex!s}]\nValue: [{ex.value!s}]")
Exemple #11
0
def delete_local_process(request):
    """
    Unregister a local process.
    """
    store = get_db(request).get_store(StoreProcesses)
    process = get_process(request=request, store=store)
    process_id = process.id
    if process.type == PROCESS_BUILTIN:
        raise HTTPForbidden("Cannot delete a builtin process.")
    if store.delete_process(process_id, visibility=VISIBILITY_PUBLIC):
        return HTTPOk(json={
            "undeploymentDone": True,
            "identifier": process_id
        })
    LOGGER.error(
        "Existing process [%s] should have been deleted with success status.",
        process_id)
    raise HTTPForbidden(
        "Deletion of process has been refused by the database or could not have been validated."
    )
Exemple #12
0
    def _submit_job(self, wps_request):
        # type: (WPSRequest) -> Union[WPSResponse, HTTPValid, JSON]
        """
        Dispatch operation to WPS-REST endpoint, which in turn should call back the real Celery Worker for execution.
        """
        req = wps_request.http_request
        pid = wps_request.identifier
        proc = get_process(
            process_id=pid,
            settings=self.settings)  # raises if invalid or missing
        wps_process = self.processes.get(pid)

        # create the JSON payload from the XML content and submit job
        is_workflow = proc.type == PROCESS_WORKFLOW
        tags = req.args.get("tags", "").split(",") + [
            "xml", "wps-{}".format(wps_request.version)
        ]
        data = wps2json_job_payload(wps_request, wps_process)
        body = submit_job_handler(data,
                                  self.settings,
                                  proc.processEndpointWPS1,
                                  process_id=pid,
                                  is_local=True,
                                  is_workflow=is_workflow,
                                  visibility=VISIBILITY_PUBLIC,
                                  language=wps_request.language,
                                  tags=tags,
                                  auth=dict(req.headers))

        # if Accept was JSON, provide response content as is
        accept_type = get_header("Accept", req.headers)
        if accept_type == CONTENT_TYPE_APP_JSON:
            resp = get_job_submission_response(body)
            setattr(
                resp, "_update_status",
                lambda *_, **__: None)  # patch to avoid pywps server raising
            return resp

        return body
Exemple #13
0
def submit_local_job(request):
    # type: (PyramidRequest) -> AnyViewResponse
    """
    Execute a process registered locally.

    Execution location and method is according to deployed Application Package.
    """
    process = get_process(request=request)
    ctype = clean_mime_type_format(get_header("content-type", request.headers, default=None), strip_parameters=True)
    if ctype in ContentType.ANY_XML:
        # Send the XML request to the WPS endpoint which knows how to parse it properly.
        # Execution will end up in the same 'submit_job_handler' function as other branch for JSON.
        service = get_pywps_service()
        wps_params = {"version": "1.0.0", "request": "Execute", "service": "WPS", "identifier": process.id}
        request.path_info = get_wps_path(request)
        request.query_string = get_path_kvp("", **wps_params)[1:]
        location = request.application_url + request.path_info + request.query_string
        LOGGER.warning("Route redirection [%s] -> [%s] for WPS-XML support.", request.url, location)
        http_request = extend_instance(request, WerkzeugRequest)
        http_request.shallow = False
        return service.call(http_request)
    return submit_job(request, process, tags=["wps-rest"])
Exemple #14
0
def get_process_visibility(request):
    """
    Get the visibility of a registered local process.
    """
    process = get_process(request=request)
    return HTTPOk(json={u"value": process.visibility})
Exemple #15
0
def get_local_process_payload(request):
    """
    Get a registered local process payload definition.
    """
    process = get_process(request=request)
    return HTTPOk(json=process.payload or {})