Ejemplo n.º 1
0
    def create_literal_inputs(self, source, inputs):
        """ Takes the http_request and parses the input to objects
        :return collections.deque:
        """

        outinputs = deque(maxlen=source.max_occurs)

        for inpt in inputs:
            newinpt = source.clone()
            # set the input to the type defined in the process
            newinpt.uom = inpt.get('uom')
            data_type = inpt.get('datatype')
            if data_type:
                newinpt.data_type = data_type

            # get the value of the field
            newinpt.data = inpt.get('data')

            outinputs.append(newinpt)

        if len(outinputs) < source.min_occurs:
            description = "At least {} inputs are required. You provided {}.".format(
                source.min_occurs,
                len(outinputs),
            )
            raise MissingParameterValue(description, locator=source.identifier)

        return outinputs
Ejemplo n.º 2
0
    def describe(self, identifiers):
        if not identifiers:
            raise MissingParameterValue('', 'identifier')
        
        identifier_elements = []
        # 'all' keyword means all processes
        if 'all' in (ident.lower() for ident in identifiers):
            for process in self.processes:
                try:
                    identifier_elements.append(self.processes[process].describe_xml())
                except Exception as e:
                    raise NoApplicableCode(e)
        else:
            for identifier in identifiers:
                try:
                    process = self.processes[identifier]
                except KeyError:
                    raise InvalidParameterValue("Unknown process %r" % identifier, "identifier")
                else:
                    try:
                        identifier_elements.append(process.describe_xml())
                    except Exception as e:
                        raise NoApplicableCode(e)

        doc = WPS.ProcessDescriptions(
            *identifier_elements
        )
        doc.attrib['{http://www.w3.org/2001/XMLSchema-instance}schemaLocation'] = 'http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsDescribeProcess_response.xsd'
        doc.attrib['service'] = 'WPS'
        doc.attrib['version'] = '1.0.0'
        doc.attrib['{http://www.w3.org/XML/1998/namespace}lang'] = 'en-CA'
        return xml_response(doc)
Ejemplo n.º 3
0
    def create_bbox_inputs(self, source, inputs):
        """ Takes the http_request and parses the input to objects
        :return collections.deque:
        """

        outinputs = deque(maxlen=source.max_occurs)

        for datainput in inputs:
            newinpt = source.clone()

            try:
                newinpt.data = [
                    datainput.minx, datainput.miny, datainput.maxx,
                    datainput.maxy
                ]
            except AttributeError:
                newinpt.data = [
                    float(coord) for coord in datainput['data'].split(',')[:4]
                ]

            outinputs.append(newinpt)

        if len(outinputs) < source.min_occurs:
            description = "At least {} inputs are required. You provided {}.".format(
                source.min_occurs,
                len(outinputs),
            )
            raise MissingParameterValue(description=description,
                                        locator=source.identifier)

        return outinputs
Ejemplo n.º 4
0
    def _construct_doc(self):

        if not self.identifiers:
            raise MissingParameterValue('Missing parameter value "identifier"', 'identifier')

        template = self.template_env.get_template(self.version + '/describe/main.xml')
        max_size = int(config.get_size_mb(config.get_config_value('server', 'maxsingleinputsize')))
        doc = template.render(max_size=max_size, **self.json)

        return doc
Ejemplo n.º 5
0
    def check_and_set_version(self, version):
        """set this.version
        """

        if not version:
            raise MissingParameterValue('Missing version', 'version')
        elif not _check_version(version):
            raise VersionNegotiationFailed(
                'The requested version "{}" is not supported by this server'.format(version), 'version')
        else:
            self.set_version(version)
Ejemplo n.º 6
0
    def create_bbox_inputs(self, source, inputs):
        """ Takes the http_request and parses the input to objects
        :return collections.deque:
        """

        outinputs = deque(maxlen=source.max_occurs)

        for datainput in inputs:
            newinpt = source.clone()
            newinpt.data = [datainput.minx, datainput.miny,
                            datainput.maxx, datainput.maxy]
            outinputs.append(newinpt)

        if len(outinputs) < source.min_occurs:
            raise MissingParameterValue(locator = source.identifier)

        return outinputs
Ejemplo n.º 7
0
    def _get_request(self):
        """HTTP GET request parser
        """

        # service shall be WPS
        service = _get_get_param(self.http_request, 'service')
        if service:
            if str(service).lower() != 'wps':
                raise InvalidParameterValue(
                    'parameter SERVICE [{}] not supported'.format(service), 'service')
        else:
            raise MissingParameterValue('service', 'service')

        operation = _get_get_param(self.http_request, 'request')

        request_parser = self._get_request_parser(operation)
        request_parser(self.http_request)
Ejemplo n.º 8
0
        def parse_post_execute(doc):
            """Parse POST Execute request
            """

            version = doc.attrib.get('version')
            wpsrequest.check_and_set_version(version)

            language = doc.attrib.get('language')
            wpsrequest.check_and_set_language(language)

            wpsrequest.operation = 'execute'

            identifier = xpath_ns(doc, './ows:Identifier')

            if not identifier:
                raise MissingParameterValue('Process identifier not set',
                                            'Identifier')

            wpsrequest.identifier = identifier[0].text
            wpsrequest.lineage = 'false'
            wpsrequest.store_execute = 'false'
            wpsrequest.status = 'false'
            wpsrequest.inputs = get_inputs_from_xml(doc)
            wpsrequest.outputs = get_output_from_xml(doc)
            wpsrequest.raw = False
            if xpath_ns(doc,
                        '/wps:Execute/wps:ResponseForm/wps:RawDataOutput'):
                wpsrequest.raw = True
                # executeResponse XML will not be stored
                wpsrequest.store_execute = 'false'

            # check if response document tag has been set then retrieve
            response_document = xpath_ns(
                doc, './wps:ResponseForm/wps:ResponseDocument')
            if len(response_document) > 0:
                wpsrequest.lineage = response_document[0].attrib.get(
                    'lineage', 'false')
                wpsrequest.store_execute = response_document[0].attrib.get(
                    'storeExecuteResponse', 'false')
                wpsrequest.status = response_document[0].attrib.get(
                    'status', 'false')
Ejemplo n.º 9
0
    def create_complex_inputs(self, source, inputs):
        """Create new ComplexInput as clone of original ComplexInput
        because of inputs can be more than one, take it just as Prototype.

        :param source: The process's input definition.
        :param inputs: The request input data.
        :return collections.deque:
        """

        outinputs = deque(maxlen=source.max_occurs)

        for inpt in inputs:
            data_input = source.clone()
            frmt = data_input.supported_formats[0]
            if 'mimeType' in inpt:
                if inpt['mimeType']:
                    frmt = data_input.get_format(inpt['mimeType'])
                else:
                    frmt = data_input.data_format

            if frmt:
                data_input.data_format = frmt
            else:
                raise InvalidParameterValue(
                    'Invalid mimeType value {} for input {}'.format(
                        inpt.get('mimeType'), source.identifier), 'mimeType')

            data_input.method = inpt.get('method', 'GET')
            data_input.process(inpt)
            outinputs.append(data_input)

        if len(outinputs) < source.min_occurs:
            description = "At least {} inputs are required. You provided {}.".format(
                source.min_occurs,
                len(outinputs),
            )
            raise MissingParameterValue(description=description,
                                        locator=source.identifier)
        return outinputs
Ejemplo n.º 10
0
    def create_complex_inputs(self, source, inputs):
        """Create new ComplexInput as clone of original ComplexInput
        because of inputs can be more then one, take it just as Prototype
        :return collections.deque:
        """

        outinputs = deque(maxlen=source.max_occurs)

        for inpt in inputs:
            data_input = source.clone()
            frmt = data_input.supported_formats[0]
            if 'mimeType' in inpt:
                if inpt['mimeType']:
                    frmt = data_input.get_format(inpt['mimeType'])
                else:
                    frmt = data_input.data_format

            if frmt:
                data_input.data_format = frmt
            else:
                raise InvalidParameterValue(
                    'Invalid mimeType value %s for input %s' %\
                    (inpt.get('mimeType'), source.identifier),
                    'mimeType') 

            data_input.method = inpt.get('method', 'GET')

            # get the referenced input otherwise get the value of the field
            href = inpt.get('href', None)

            complex_data_handler = self._get_complex_input_handler(href)
            complex_data_handler(data_input, inpt)

            outinputs.append(data_input)

        if len(outinputs) < source.min_occurs:
            raise MissingParameterValue(locator = source.identifier)
        return outinputs
Ejemplo n.º 11
0
    def _get_request(self):
        """HTTP GET request parser
        """

        # WSDL request
        wsdl = _get_get_param(self.http_request, 'WSDL')
        if wsdl is not None:
            # TODO: fix #57 then remove the exception
            raise NoApplicableCode('WSDL not implemented')

        # service shall be WPS
        service = _get_get_param(self.http_request, 'service', aslist=False)
        if service:
            if str(service).lower() != 'wps':
                raise InvalidParameterValue(
                    'parameter SERVICE [%s] not supported' % service)
        else:
            raise MissingParameterValue('service', 'service')

        operation = _get_get_param(self.http_request, 'request', aslist=False)

        request_parser = self._get_request_parser(operation)
        request_parser(self.http_request)
Ejemplo n.º 12
0
    def _parse_and_execute(self, process, wps_request):
        """Parse and execute request
        """
        # check if datainputs is required and has been passed
        if process.inputs:
            if wps_request.inputs is None:
                raise MissingParameterValue('', 'datainputs')

        # check if all mandatory inputs have been passed
        data_inputs = {}
        for inpt in process.inputs:
            if inpt.identifier not in wps_request.inputs:
                if inpt.min_occurs > 0:
                    raise MissingParameterValue(inpt.identifier, inpt.identifier)
                else:
                    data_inputs[inpt.identifier] = inpt.clone()

            # Replace the dicts with the dict of Literal/Complex inputs
            # set the input to the type defined in the process
            if isinstance(inpt, ComplexInput):
                data_inputs[inpt.identifier] = self.create_complex_inputs(inpt,
                    wps_request.inputs[inpt.identifier])
            elif isinstance(inpt, LiteralInput):
                data_inputs[inpt.identifier] = self.create_literal_inputs(inpt,
                    wps_request.inputs[inpt.identifier])
            elif isinstance(inpt, BoundingBoxInput):
                data_inputs[inpt.identifier] = self.create_bbox_inputs(inpt,
                    wps_request.inputs[inpt.identifier])

        wps_request.inputs = data_inputs
        
        # set as_reference to True for all the outputs specified as reference
        # if the output is not required to be raw
        if not wps_request.raw:
            for wps_outpt in wps_request.outputs:

                is_reference = wps_request.outputs[wps_outpt].get('asReference', 'false')
                if is_reference.lower() == 'true':
                    # check if store is supported
                    if process.store_supported == 'false':
                        raise StorageNotSupported('The storage of data is not supported for this process.')

                    is_reference = True
                else:
                    is_reference = False

                for outpt in process.outputs:
                    if outpt.identifier == wps_outpt:
                        outpt.as_reference = is_reference

        # catch error generated by process code
        try:
            wps_response = process.execute(wps_request)
        except Exception as e:
            raise NoApplicableCode('Service error: %s' % e)

        # get the specified output as raw
        if wps_request.raw:
            for outpt in wps_request.outputs:
                for proc_outpt in process.outputs:
                    if outpt == proc_outpt.identifier:
                        return Response(proc_outpt.data)

            # if the specified identifier was not found raise error
            raise InvalidParameterValue('')

        return wps_response
Ejemplo n.º 13
0
    def _get_request_parser(self, operation):
        """Factory function returing propper parsing function
        """

        wpsrequest = self

        def parse_get_getcapabilities(http_request):
            """Parse GET GetCapabilities request
            """

            acceptedversions = _get_get_param(http_request, 'acceptversions')
            wpsrequest.check_accepted_versions(acceptedversions)

        def parse_get_describeprocess(http_request):
            """Parse GET DescribeProcess request
            """
            version = _get_get_param(http_request, 'version')
            wpsrequest.check_and_set_version(version)

            language = _get_get_param(http_request, 'language')
            wpsrequest.check_and_set_language(language)

            wpsrequest.identifiers = _get_get_param(
                http_request, 'identifier', aslist=True)

        def parse_get_execute(http_request):
            """Parse GET Execute request
            """
            version = _get_get_param(http_request, 'version')
            wpsrequest.check_and_set_version(version)

            language = _get_get_param(http_request, 'language')
            wpsrequest.check_and_set_language(language)

            wpsrequest.identifier = _get_get_param(http_request, 'identifier')
            wpsrequest.store_execute = _get_get_param(
                http_request, 'storeExecuteResponse', 'false')
            wpsrequest.status = _get_get_param(http_request, 'status', 'false')
            wpsrequest.lineage = _get_get_param(
                http_request, 'lineage', 'false')
            wpsrequest.inputs = get_data_from_kvp(
                _get_get_param(http_request, 'DataInputs'), 'DataInputs')
            if self.inputs is None:
                self.inputs = {}

            wpsrequest.outputs = {}

            # take responseDocument preferably
            resp_outputs = get_data_from_kvp(
                _get_get_param(http_request, 'ResponseDocument'))
            raw_outputs = get_data_from_kvp(
                _get_get_param(http_request, 'RawDataOutput'))
            wpsrequest.raw = False
            if resp_outputs:
                wpsrequest.outputs = resp_outputs
            elif raw_outputs:
                wpsrequest.outputs = raw_outputs
                wpsrequest.raw = True
                # executeResponse XML will not be stored and no updating of
                # status
                wpsrequest.store_execute = 'false'
                wpsrequest.status = 'false'

        if not operation:
            raise MissingParameterValue('Missing request value', 'request')
        else:
            self.operation = operation.lower()

        if self.operation == 'getcapabilities':
            return parse_get_getcapabilities
        elif self.operation == 'describeprocess':
            return parse_get_describeprocess
        elif self.operation == 'execute':
            return parse_get_execute
        else:
            raise OperationNotSupported(
                'Unknown request {}'.format(self.operation), operation)
Ejemplo n.º 14
0
    def _parse_and_execute(self, process, wps_request, uuid):
        """Parse and execute request
        """

        LOGGER.debug('Checking if all mandatory inputs have been passed')
        data_inputs = {}
        for inpt in process.inputs:
            # Replace the dicts with the dict of Literal/Complex inputs
            # set the input to the type defined in the process.

            request_inputs = None
            if inpt.identifier in wps_request.inputs:
                request_inputs = wps_request.inputs[inpt.identifier]

            if not request_inputs:
                if inpt.data_set:
                    data_inputs[inpt.identifier] = [inpt.clone()]
            else:

                if isinstance(inpt, ComplexInput):
                    data_inputs[inpt.identifier] = self.create_complex_inputs(
                        inpt, request_inputs)
                elif isinstance(inpt, LiteralInput):
                    data_inputs[inpt.identifier] = self.create_literal_inputs(
                        inpt, request_inputs)
                elif isinstance(inpt, BoundingBoxInput):
                    data_inputs[inpt.identifier] = self.create_bbox_inputs(
                        inpt, request_inputs)

        for inpt in process.inputs:

            if inpt.identifier not in data_inputs:
                if inpt.min_occurs > 0:
                    LOGGER.error('Missing parameter value: %s',
                                 inpt.identifier)
                    raise MissingParameterValue(inpt.identifier,
                                                inpt.identifier)

        wps_request.inputs = data_inputs

        # set as_reference to True for all the outputs specified as reference
        # if the output is not required to be raw
        if not wps_request.raw:
            for wps_outpt in wps_request.outputs:

                is_reference = wps_request.outputs[wps_outpt].get(
                    'asReference', 'false')
                if is_reference.lower() == 'true':
                    # check if store is supported
                    if process.store_supported == 'false':
                        raise StorageNotSupported(
                            'The storage of data is not supported for this process.'
                        )

                    is_reference = True
                else:
                    is_reference = False

                for outpt in process.outputs:
                    if outpt.identifier == wps_outpt:
                        outpt.as_reference = is_reference

        # catch error generated by process code
        try:
            wps_response = process.execute(wps_request, uuid)
        except Exception as e:
            e_follow = e
            if not isinstance(e, NoApplicableCode):
                e_follow = NoApplicableCode('Service error: %s' % e)
            if wps_request.raw:
                resp = Response(e_follow.get_body(),
                                mimetype='application/xml')
                resp.call_on_close(process.clean)
                return resp
            else:
                raise e_follow

        # get the specified output as raw
        if wps_request.raw:
            for outpt in wps_request.outputs:
                for proc_outpt in process.outputs:
                    if outpt == proc_outpt.identifier:
                        return Response(proc_outpt.data)

            # if the specified identifier was not found raise error
            raise InvalidParameterValue('')

        return wps_response
Ejemplo n.º 15
0
    def _parse_and_execute(self, process, wps_request, uuid):
        """Parse and execute request
        """

        LOGGER.debug('Checking if all mandatory inputs have been passed')
        data_inputs = {}
        for inpt in process.inputs:
            # Replace the dicts with the dict of Literal/Complex inputs
            # set the input to the type defined in the process.

            request_inputs = None
            if inpt.identifier in wps_request.inputs:
                request_inputs = wps_request.inputs[inpt.identifier]

            if not request_inputs:
                if inpt._default is not None:
                    if not inpt.data_set and isinstance(inpt, ComplexInput):
                        inpt._set_default_value()

                    data_inputs[inpt.identifier] = [inpt.clone()]
            else:

                if isinstance(inpt, ComplexInput):
                    data_inputs[inpt.identifier] = self.create_complex_inputs(
                        inpt, request_inputs)
                elif isinstance(inpt, LiteralInput):
                    data_inputs[inpt.identifier] = self.create_literal_inputs(
                        inpt, request_inputs)
                elif isinstance(inpt, BoundingBoxInput):
                    data_inputs[inpt.identifier] = self.create_bbox_inputs(
                        inpt, request_inputs)

        for inpt in process.inputs:

            if inpt.identifier not in data_inputs:
                if inpt.min_occurs > 0:
                    LOGGER.error('Missing parameter value: %s',
                                 inpt.identifier)
                    raise MissingParameterValue(inpt.identifier,
                                                inpt.identifier)

        wps_request.inputs = data_inputs

        # set as_reference to True for all the outputs specified as reference
        # if the output is not required to be raw
        if not wps_request.raw:
            for wps_outpt in wps_request.outputs:

                is_reference = wps_request.outputs[wps_outpt].get(
                    'asReference', 'false')
                mimetype = wps_request.outputs[wps_outpt].get('mimetype', '')
                if is_reference.lower() == 'true':
                    # check if store is supported
                    if process.store_supported == 'false':
                        raise StorageNotSupported(
                            'The storage of data is not supported for this process.'
                        )

                    is_reference = True
                else:
                    is_reference = False

                for outpt in process.outputs:
                    if outpt.identifier == wps_outpt:
                        outpt.as_reference = is_reference
                        if isinstance(outpt, ComplexOutput) and mimetype != '':
                            data_format = [
                                f for f in outpt.supported_formats
                                if f.mime_type == mimetype
                            ]
                            if len(data_format) == 0:
                                raise InvalidParameterValue('MimeType ' +
                                                            mimetype +
                                                            ' not valid')
                            outpt.data_format = data_format[0]

        wps_response = process.execute(wps_request, uuid)
        return wps_response
Ejemplo n.º 16
0
    def __init__(self, http_request):
        self.http_request = http_request

        if http_request.method == 'GET':
            # service shall be WPS
            service = self._get_get_param('service', aslist=False)
            if service:
                if str(service).lower() != 'wps':
                    raise OperationNotSupported(
                        'parameter SERVICE [%s] not supported' % service)
            else:
                raise MissingParameterValue('service', 'service')

            # operation shall be one of GetCapabilities, DescribeProcess,
            # Execute
            self.operation = self._get_get_param('request', aslist=False)

            if not self.operation:
                raise MissingParameterValue('request')
            else:
                self.operation = self.operation.lower()

            if self.operation == 'getcapabilities':
                pass

            elif self.operation == 'describeprocess':
                self.identifiers = self._get_get_param('identifier',
                                                       aslist=True)
                if not self.identifiers:
                    raise MissingParameterValue('identifier')

            elif self.operation == 'execute':
                self.identifier = self._get_get_param('identifier')
                self.inputs = get_input_from_kvp(
                    self._get_get_param('datainputs'))

            else:
                raise InvalidParameterValue(self.operation)

        elif http_request.method == 'POST':
            doc = lxml.etree.fromstring(http_request.get_data())

            if doc.tag == WPS.GetCapabilities().tag:
                self.operation = 'getcapabilities'

            elif doc.tag == WPS.DescribeProcess().tag:
                self.operation = 'describeprocess'
                self.identifiers = [
                    identifier_el.text
                    for identifier_el in xpath_ns(doc, './ows:Identifier')
                ]

            elif doc.tag == WPS.Execute().tag:
                self.operation = 'execute'
                self.identifier = xpath_ns(doc, './ows:Identifier')[0].text
                self.inputs = get_input_from_xml(doc)

            else:
                raise InvalidParameterValue(doc.tag)

        else:
            raise MethodNotAllowed()