Exemple #1
0
    def test_rewrite_query(self):
        rq, _ = self.loader.getTextForName('test-rq')
        # Parameters on the format returned by gquery.get_parameters
        parameters = {
            'o1': self.build_get_parameter('o1', 'x1'),
            'o2': self.build_get_parameter('o2', 'x2'),
            'o3': self.build_get_parameter('o3', 'x3'),
            'o4': self.build_get_parameter('o4', 'x4'),
            'o5': self.build_get_parameter('o5', 'x5'),
            'o6': self.build_get_parameter('o6', 'x6'),
            'o7': self.build_get_parameter('o7', 'x7')
        }
        args = {
            'o1': 'x1',
            'o2': 'x2',
            'o3': 'x3',
            'o4': 'x4',
            'o5': 'x5',
            'o6': 'x6',
            'o7': 'x7'
        }
        # Rewritten query will probably be incorrect because parameters are not
        # carefully constructed, but that is not the scope of this test
        rq_rw = gquery.rewrite_query(rq, parameters, args)

        for pName, pValue in parameters.items():
            self.assertIn(
                pName, rq, 'Original query should contain original parameter name')
            self.assertNotIn(
                pName, rq_rw, 'Rewritten query should not contain original parameter name')
            self.assertNotIn(
                pValue['name'], rq, 'Original query should not contain replacement parameter value')
            self.assertIn(
                pValue['name'], rq_rw, 'Rewritten query should contain replacement parameter value')
Exemple #2
0
def dispatchSPARQLQuery(raw_sparql_query, loader, requestArgs, acceptHeader,
                        content, formData, requestUrl):
    """Executes the specified SPARQL query."""
    endpoint, auth = gquery.guess_endpoint_uri(raw_sparql_query, loader)
    if endpoint == '':
        return 'No SPARQL endpoint indicated', 407, {}

    glogger.debug("=====================================================")
    glogger.debug("Sending query to SPARQL endpoint: {}".format(endpoint))
    glogger.debug("=====================================================")

    try:
        query_metadata = gquery.get_metadata(raw_sparql_query, endpoint)
    except Exception as e:
        # extracting metadata
        return {'error': str(e)}, 400, {}

    acceptHeader = 'application/json' if isinstance(raw_sparql_query,
                                                    dict) else acceptHeader
    pagination = query_metadata[
        'pagination'] if 'pagination' in query_metadata else ""

    rewritten_query = query_metadata['query']

    # Rewrite query using parameter values
    if query_metadata['type'] == 'SelectQuery' or query_metadata[
            'type'] == 'ConstructQuery':
        rewritten_query = gquery.rewrite_query(
            query_metadata['original_query'], query_metadata['parameters'],
            requestArgs)

    # Rewrite query using pagination
    if query_metadata[
            'type'] == 'SelectQuery' and 'pagination' in query_metadata:
        rewritten_query = gquery.paginate_query(rewritten_query,
                                                query_metadata['pagination'],
                                                requestArgs)

    resp = None
    headers = {}

    # If we have a mime field, we load the remote dump and query it locally
    if 'mime' in query_metadata and query_metadata['mime']:
        glogger.debug(
            "Detected {} MIME type, proceeding with locally loading remote dump"
            .format(query_metadata['mime']))
        g = Graph()
        try:
            query_metadata = gquery.get_metadata(raw_sparql_query, endpoint)
            g.parse(endpoint, format=query_metadata['mime'])
            glogger.debug(
                "Local RDF graph loaded successfully with {} triples".format(
                    len(g)))
        except Exception as e:
            glogger.error(e)
        results = g.query(rewritten_query, result='sparql')
        # Prepare return format as requested
        resp_string = ""
        if 'application/json' in acceptHeader or (
                content and 'application/json' in static.mimetypes[content]):
            resp_string = results.serialize(format='json')
            glogger.debug(
                "Results of SPARQL query against locally loaded dump: {}".
                format(resp_string))
        elif 'text/csv' in acceptHeader or (content and 'text/csv'
                                            in static.mimetypes[content]):
            resp_string = results.serialize(format='csv')
            glogger.debug(
                "Results of SPARQL query against locally loaded dump: {}".
                format(resp_string))
        else:
            return 'Unacceptable requested format', 415, {}
        glogger.debug(
            "Finished processing query against RDF dump, end of use case")
        del g

    # Check for INSERT/POST
    elif query_metadata['type'] == 'InsertData':
        glogger.debug("Processing INSERT query")
        # Rewrite INSERT
        rewritten_query = rewritten_query.replace(
            "?_g_iri", "{}".format(formData.get('g')))
        rewritten_query = rewritten_query.replace("<s> <p> <o>",
                                                  formData.get('data'))
        glogger.debug("INSERT query rewritten as {}".format(rewritten_query))

        # Prepare HTTP POST request
        reqHeaders = {
            'Accept': acceptHeader,
            'Content-Type': 'application/sparql-update'
        }
        response = requests.post(endpoint,
                                 data=rewritten_query,
                                 headers=reqHeaders,
                                 auth=auth)
        glogger.debug('Response header from endpoint: ' +
                      response.headers['Content-Type'])

        # Response headers
        resp = response.text
        headers['Content-Type'] = response.headers['Content-Type']

    # If there's no mime type, the endpoint is an actual SPARQL endpoint
    else:
        reqHeaders = {'Accept': acceptHeader}
        if content:
            reqHeaders = {'Accept': static.mimetypes[content]}
        data = {'query': rewritten_query}

        glogger.debug(
            'Sending HTTP request to SPARQL endpoint with params: {}'.format(
                data))
        glogger.debug(
            'Sending HTTP request to SPARQL endpoint with headers: {}'.format(
                reqHeaders))
        glogger.debug(
            'Sending HTTP request to SPARQL endpoint with auth: {}'.format(
                auth))
        try:
            response = requests.get(endpoint,
                                    params=data,
                                    headers=reqHeaders,
                                    auth=auth)
        except Exception as e:
            # Error contacting SPARQL endpoint
            glogger.debug(
                'Exception encountered while connecting to SPARQL endpoint')
            return {'error': str(e)}, 400, headers
        glogger.debug('Response header from endpoint: ' +
                      response.headers['Content-Type'])

        # Response headers
        resp = response.text
        headers['Content-Type'] = response.headers['Content-Type']

    # If the query is paginated, set link HTTP headers
    if pagination:
        # Get number of total results
        count = gquery.count_query_results(rewritten_query, endpoint)
        pageArg = requestArgs.get('page', None)

        url = urlparse(requestUrl)
        replaced = url._replace(netloc=static.SERVER_NAME)
        headerLink = pageUtils.buildPaginationHeader(count,
                                                     pagination, pageArg,
                                                     replaced.geturl())
        headers['Link'] = headerLink

    if 'proto' in query_metadata:  # sparql transformer
        resp = SPARQLTransformer.post_process(json.loads(resp),
                                              query_metadata['proto'],
                                              query_metadata['opt'])

    if 'transform' in query_metadata and acceptHeader == 'application/json':  # sparql transformer
        rq = {'proto': query_metadata['transform']}
        _, _, opt = SPARQLTransformer.pre_process(rq)
        resp = SPARQLTransformer.post_process(json.loads(resp),
                                              query_metadata['transform'], opt)

    headers['Server'] = 'grlc/' + grlc_version
    return resp, 200, headers