public void ItAllowsEndpointErrorsToBeIgnored()
        {
            var endpoint = new FederatedSparqlRemoteEndpoint(new[]
            {
                new SparqlRemoteEndpoint(new Uri(_fixture.Server1.Urls[0] + "/query")),
                new SparqlRemoteEndpoint(new Uri(_fixture.Server2.Urls[0] + "/fail")),
            })
            {
                IgnoreFailedRequests = true
            };
            var results = endpoint.QueryWithResultSet("SELECT * WHERE {?s ?p ?o}");

            results.Should().NotBeNull().And.HaveCount(1);
            _fixture.Server1.FindLogEntries(new RequestMessagePathMatcher(MatchBehaviour.AcceptOnMatch, "/query"))
            .Should().HaveCount(1).And.Contain(x =>
                                               x.RequestMessage.Method.Equals("get", StringComparison.InvariantCultureIgnoreCase));
        }
 private bool SetupSparqlEndpointData()
 {
     try
     {
         FederatedSparqlRemoteEndpoint federatedSparqlRemoteEndpoint =
             new FederatedSparqlRemoteEndpoint(_testSparqlEndpoints);
         var response =
             federatedSparqlRemoteEndpoint.QueryWithResultSet("select ?s where {?s ?p ?o} limit 1");
         if (response.Count() == 3)
         {
             return(true);
         }
         return(false);
     }
     catch (Exception)
     {
         return(false);
     }
 }
Esempio n. 3
0
        /// <summary>
        /// Tries to load a SPARQL Endpoint based on information from the Configuration Graph.
        /// </summary>
        /// <param name="g">Configuration Graph.</param>
        /// <param name="objNode">Object Node.</param>
        /// <param name="targetType">Target Type.</param>
        /// <param name="obj">Output Object.</param>
        /// <returns></returns>
        public bool TryLoadObject(IGraph g, INode objNode, Type targetType, out object obj)
        {
            BaseEndpoint endpoint = null;

            obj = null;

            switch (targetType.FullName)
            {
            case QueryEndpoint:
                String queryEndpointUri = ConfigurationLoader.GetConfigurationValue(g, objNode, new INode[] { g.CreateUriNode(UriFactory.Create(ConfigurationLoader.PropertyQueryEndpointUri)), g.CreateUriNode(UriFactory.Create(ConfigurationLoader.PropertyEndpointUri)) });
                if (queryEndpointUri == null)
                {
                    return(false);
                }

                // Get Default/Named Graphs if specified
                IEnumerable <String> defaultGraphs = from n in ConfigurationLoader.GetConfigurationData(g, objNode, g.CreateUriNode(UriFactory.Create(ConfigurationLoader.PropertyDefaultGraphUri)))
                                                     select n.ToString();

                IEnumerable <String> namedGraphs = from n in ConfigurationLoader.GetConfigurationData(g, objNode, g.CreateUriNode(UriFactory.Create(ConfigurationLoader.PropertyNamedGraphUri)))
                                                   select n.ToString();

                endpoint = new SparqlRemoteEndpoint(UriFactory.Create(queryEndpointUri), defaultGraphs, namedGraphs);
                break;

            case UpdateEndpoint:
                String updateEndpointUri = ConfigurationLoader.GetConfigurationValue(g, objNode, new INode[] { g.CreateUriNode(UriFactory.Create(ConfigurationLoader.PropertyUpdateEndpointUri)), g.CreateUriNode(UriFactory.Create(ConfigurationLoader.PropertyEndpointUri)) });
                if (updateEndpointUri == null)
                {
                    return(false);
                }

                endpoint = new SparqlRemoteUpdateEndpoint(UriFactory.Create(updateEndpointUri));
                break;

            case FederatedEndpoint:
                IEnumerable <INode> endpoints = ConfigurationLoader.GetConfigurationData(g, objNode, g.CreateUriNode(UriFactory.Create(ConfigurationLoader.PropertyQueryEndpoint)))
                                                .Concat(ConfigurationLoader.GetConfigurationData(g, objNode, g.CreateUriNode(UriFactory.Create(ConfigurationLoader.PropertyEndpoint))));
                foreach (INode e in endpoints)
                {
                    Object temp = ConfigurationLoader.LoadObject(g, e);
                    if (temp is SparqlRemoteEndpoint)
                    {
                        if (endpoint == null)
                        {
                            endpoint = new FederatedSparqlRemoteEndpoint((SparqlRemoteEndpoint)temp);
                        }
                        else
                        {
                            ((FederatedSparqlRemoteEndpoint)endpoint).AddEndpoint((SparqlRemoteEndpoint)temp);
                        }
                    }
                    else
                    {
                        throw new DotNetRdfConfigurationException("Unable to load the SPARQL Endpoint identified by the Node '" + e.ToString() + "' as one of the values for the dnr:queryEndpoint/dnr:endpoint property points to an Object which cannot be loaded as an object which is a SparqlRemoteEndpoint");
                    }
                }
                break;
            }

            if (endpoint != null)
            {
                // Are there any credentials specified?
                String user, pwd;
                ConfigurationLoader.GetUsernameAndPassword(g, objNode, true, out user, out pwd);
                if (user != null && pwd != null)
                {
                    endpoint.SetCredentials(user, pwd);
                }

                // Is there a Proxy Server specified
                INode proxyNode = ConfigurationLoader.GetConfigurationNode(g, objNode, g.CreateUriNode(UriFactory.Create(ConfigurationLoader.PropertyProxy)));
                if (proxyNode != null)
                {
                    Object proxy = ConfigurationLoader.LoadObject(g, proxyNode);
                    if (proxy is IWebProxy)
                    {
                        endpoint.Proxy = (IWebProxy)proxy;

                        // Are we supposed to use the same credentials for the proxy as for the endpoint?
                        bool useCredentialsForProxy = ConfigurationLoader.GetConfigurationBoolean(g, objNode, g.CreateUriNode(UriFactory.Create(ConfigurationLoader.PropertyUseCredentialsForProxy)), false);
                        if (useCredentialsForProxy)
                        {
                            endpoint.UseCredentialsForProxy = true;
                        }
                    }
                    else
                    {
                        throw new DotNetRdfConfigurationException("Unable to load SPARQL Endpoint identified by the Node '" + objNode.ToString() + "' as the value for the dnr:proxy property points to an Object which cannot be loaded as an object of type WebProxy");
                    }
                }
            }

            obj = endpoint;
            return(endpoint != null);
        }
Esempio n. 4
0
        /// <summary>
        /// Evaluates the Service Clause by generating instance(s) of <see cref="SparqlRemoteEndpoint">SparqlRemoteEndpoint</see> as required and issuing the query to the remote endpoint(s).
        /// </summary>
        /// <param name="context">Evaluation Context.</param>
        /// <returns></returns>
        public BaseMultiset Evaluate(SparqlEvaluationContext context)
        {
            bool bypassSilent = false;

            try
            {
                SparqlRemoteEndpoint endpoint;
                Uri    endpointUri;
                String baseUri = (context.Query.BaseUri == null) ? String.Empty : context.Query.BaseUri.AbsoluteUri;
                SparqlParameterizedString sparqlQuery = new SparqlParameterizedString("SELECT * WHERE ");

                String pattern = _pattern.ToString();
                pattern = pattern.Substring(pattern.IndexOf('{'));
                sparqlQuery.CommandText += pattern;

                // Pass through LIMIT and OFFSET to the remote service
                if (context.Query.Limit >= 0)
                {
                    // Calculate a LIMIT which is the LIMIT plus the OFFSET
                    // We'll apply OFFSET locally so don't pass that through explicitly
                    int limit = context.Query.Limit;
                    if (context.Query.Offset > 0)
                    {
                        limit += context.Query.Offset;
                    }
                    sparqlQuery.CommandText += " LIMIT " + limit;
                }

                // Select which service to use
                if (_endpointSpecifier.TokenType == Token.URI)
                {
                    endpointUri = UriFactory.Create(Tools.ResolveUri(_endpointSpecifier.Value, baseUri));
                    endpoint    = new SparqlRemoteEndpoint(endpointUri);
                }
                else if (_endpointSpecifier.TokenType == Token.VARIABLE)
                {
                    // Get all the URIs that are bound to this Variable in the Input
                    String var = _endpointSpecifier.Value.Substring(1);
                    if (!context.InputMultiset.ContainsVariable(var))
                    {
                        throw new RdfQueryException("Cannot evaluate a SERVICE clause which uses a Variable as the Service specifier when the Variable is unbound");
                    }
                    List <IUriNode> services = new List <IUriNode>();
                    foreach (ISet s in context.InputMultiset.Sets)
                    {
                        if (s.ContainsVariable(var))
                        {
                            if (s[var].NodeType == NodeType.Uri)
                            {
                                services.Add((IUriNode)s[var]);
                            }
                        }
                    }
                    services = services.Distinct().ToList();

                    // Now generate a Federated Remote Endpoint
                    List <SparqlRemoteEndpoint> serviceEndpoints = new List <SparqlRemoteEndpoint>();
                    services.ForEach(u => serviceEndpoints.Add(new SparqlRemoteEndpoint(u.Uri)));
                    endpoint = new FederatedSparqlRemoteEndpoint(serviceEndpoints);
                }
                else
                {
                    // Note that we must bypass the SILENT operator in this case as this is not an evaluation failure
                    // but a query syntax error
                    bypassSilent = true;
                    throw new RdfQueryException("SERVICE Specifier must be a URI/Variable Token but a " + _endpointSpecifier.GetType().ToString() + " Token was provided");
                }

                // Where possible do substitution and execution to get accurate and correct SERVICE results
                context.OutputMultiset = new Multiset();
                List <String> existingVars = (from v in _pattern.Variables
                                              where context.InputMultiset.ContainsVariable(v)
                                              select v).ToList();

                if (existingVars.Any() || context.Query.Bindings != null)
                {
                    // Pre-bound variables/BINDINGS clause so do substitution and execution

                    // Build the set of possible bindings
                    HashSet <ISet> bindings = new HashSet <ISet>();
                    if (context.Query.Bindings != null && !_pattern.Variables.IsDisjoint(context.Query.Bindings.Variables))
                    {
                        // Possible Bindings comes from BINDINGS clause
                        // In this case each possibility is a distinct binding tuple defined in the BINDINGS clause
                        foreach (BindingTuple tuple in context.Query.Bindings.Tuples)
                        {
                            bindings.Add(new Set(tuple));
                        }
                    }
                    else
                    {
                        // Possible Bindings get built from current input (if there was a BINDINGS clause the variables it defines are not in this SERVICE clause)
                        // In this case each possibility only contains Variables bound so far
                        foreach (ISet s in context.InputMultiset.Sets)
                        {
                            Set t = new Set();
                            foreach (String var in existingVars)
                            {
                                t.Add(var, s[var]);
                            }
                            bindings.Add(t);
                        }
                    }

                    // Execute the Query for every possible Binding and build up our Output Multiset from all the results
                    foreach (ISet s in bindings)
                    {
                        // Q: Should we continue processing here if and when we hit an error?

                        foreach (String var in s.Variables)
                        {
                            sparqlQuery.SetVariable(var, s[var]);
                        }
                        SparqlResultSet results = endpoint.QueryWithResultSet(sparqlQuery.ToString());
                        context.CheckTimeout();

                        foreach (SparqlResult r in results)
                        {
                            Set t = new Set(r);
                            foreach (String var in s.Variables)
                            {
                                t.Add(var, s[var]);
                            }
                            context.OutputMultiset.Add(t);
                        }
                    }

                    return(context.OutputMultiset);
                }
                else
                {
                    // No pre-bound variables/BINDINGS clause so just execute the query

                    // Try and get a Result Set from the Service
                    SparqlResultSet results = endpoint.QueryWithResultSet(sparqlQuery.ToString());

                    // Transform this Result Set back into a Multiset
                    foreach (SparqlResult r in results.Results)
                    {
                        context.OutputMultiset.Add(new Set(r));
                    }

                    return(context.OutputMultiset);
                }
            }
            catch (Exception ex)
            {
                if (_silent && !bypassSilent)
                {
                    // If Evaluation Errors are SILENT is specified then a Multiset containing a single set with all values unbound is returned
                    // Unless some of the SPARQL queries did return results in which we just return the results we did obtain
                    if (context.OutputMultiset.IsEmpty)
                    {
                        Set s = new Set();
                        foreach (String var in _pattern.Variables.Distinct())
                        {
                            s.Add(var, null);
                        }
                        context.OutputMultiset.Add(s);
                    }
                    return(context.OutputMultiset);
                }
                else
                {
                    throw new RdfQueryException("Query execution failed because evaluating a SERVICE clause failed - this may be due to an error with the remote service", ex);
                }
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Evaluates the Service Clause by generating instance(s) of <see cref="SparqlRemoteEndpoint">SparqlRemoteEndpoint</see> as required and issuing the query to the remote endpoint(s)
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <returns></returns>
        public BaseMultiset Evaluate(SparqlEvaluationContext context)
        {
            bool bypassSilent = false;
            try
            {
            #if SILVERLIGHT
                throw new PlatformNotSupportedException("SERVICE is not currently supported under Silverlight");
            #else
                SparqlRemoteEndpoint endpoint;
                Uri endpointUri;
                String baseUri = (context.Query.BaseUri == null) ? String.Empty : context.Query.BaseUri.ToString();
                SparqlParameterizedString sparqlQuery = new SparqlParameterizedString("SELECT * WHERE ");

                String pattern = this._pattern.ToString();
                pattern = pattern.Substring(pattern.IndexOf('{'));
                sparqlQuery.CommandText += pattern;

                //Pass through LIMIT and OFFSET to the remote service
                if (context.Query.Limit >= 0)
                {
                    //Calculate a LIMIT which is the LIMIT plus the OFFSET
                    //We'll apply OFFSET locally so don't pass that through explicitly
                    int limit = context.Query.Limit;
                    if (context.Query.Offset > 0) limit += context.Query.Offset;
                    sparqlQuery.CommandText += " LIMIT " + limit;
                }

                //Select which service to use
                if (this._endpointSpecifier.TokenType == Token.URI)
                {
                    endpointUri = UriFactory.Create(Tools.ResolveUri(this._endpointSpecifier.Value, baseUri));
                    endpoint = new SparqlRemoteEndpoint(endpointUri);
                }
                else if (this._endpointSpecifier.TokenType == Token.VARIABLE)
                {
                    //Get all the URIs that are bound to this Variable in the Input
                    String var = this._endpointSpecifier.Value.Substring(1);
                    if (!context.InputMultiset.ContainsVariable(var)) throw new RdfQueryException("Cannot evaluate a SERVICE clause which uses a Variable as the Service specifier when the Variable is unbound");
                    List<IUriNode> services = new List<IUriNode>();
                    foreach (ISet s in context.InputMultiset.Sets)
                    {
                        if (s.ContainsVariable(var))
                        {
                            if (s[var].NodeType == NodeType.Uri)
                            {
                                services.Add((IUriNode)s[var]);
                            }
                        }
                    }
                    services = services.Distinct().ToList();

                    //Now generate a Federated Remote Endpoint
                    List<SparqlRemoteEndpoint> serviceEndpoints = new List<SparqlRemoteEndpoint>();
                    services.ForEach(u => serviceEndpoints.Add(new SparqlRemoteEndpoint(u.Uri)));
                    endpoint = new FederatedSparqlRemoteEndpoint(serviceEndpoints);
                }
                else
                {
                    //Note that we must bypass the SILENT operator in this case as this is not an evaluation failure
                    //but a query syntax error
                    bypassSilent = true;
                    throw new RdfQueryException("SERVICE Specifier must be a URI/Variable Token but a " + this._endpointSpecifier.GetType().ToString() + " Token was provided");
                }

                //Where possible do substitution and execution to get accurate and correct SERVICE results
                context.OutputMultiset = new Multiset();
                List<String> existingVars = (from v in this._pattern.Variables
                                             where context.InputMultiset.ContainsVariable(v)
                                             select v).ToList();

                if (existingVars.Any() || context.Query.Bindings != null)
                {
                    //Pre-bound variables/BINDINGS clause so do substitution and execution

                    //Build the set of possible bindings
                    HashSet<ISet> bindings = new HashSet<ISet>();
                    if (context.Query.Bindings != null && !this._pattern.Variables.IsDisjoint(context.Query.Bindings.Variables))
                    {
                        //Possible Bindings comes from BINDINGS clause
                        //In this case each possibility is a distinct binding tuple defined in the BINDINGS clause
                        foreach (BindingTuple tuple in context.Query.Bindings.Tuples)
                        {
                            bindings.Add(new Set(tuple));
                        }
                    }
                    else
                    {
                        //Possible Bindings get built from current input (if there was a BINDINGS clause the variables it defines are not in this SERVICE clause)
                        //In this case each possibility only contains Variables bound so far
                        foreach (ISet s in context.InputMultiset.Sets)
                        {
                            Set t = new Set();
                            foreach (String var in existingVars)
                            {
                                t.Add(var, s[var]);
                            }
                            bindings.Add(t);
                        }
                    }

                    //Execute the Query for every possible Binding and build up our Output Multiset from all the results
                    foreach (ISet s in bindings)
                    {
                        //Q: Should we continue processing here if and when we hit an error?

                        foreach (String var in s.Variables)
                        {
                            sparqlQuery.SetVariable(var, s[var]);
                        }
                        SparqlResultSet results = endpoint.QueryWithResultSet(sparqlQuery.ToString());
                        context.CheckTimeout();

                        foreach (SparqlResult r in results)
                        {
                            Set t = new Set(r);
                            foreach (String var in s.Variables)
                            {
                                t.Add(var, s[var]);
                            }
                            context.OutputMultiset.Add(t);
                        }
                    }

                    return context.OutputMultiset;
                }
                else
                {
                    //No pre-bound variables/BINDINGS clause so just execute the query

                    //Try and get a Result Set from the Service
                    SparqlResultSet results = endpoint.QueryWithResultSet(sparqlQuery.ToString());

                    //Transform this Result Set back into a Multiset
                    foreach (SparqlResult r in results.Results)
                    {
                        context.OutputMultiset.Add(new Set(r));
                    }

                    return context.OutputMultiset;
                }
            #endif
            }
            catch (Exception ex)
            {
                if (this._silent && !bypassSilent)
                {

                    //If Evaluation Errors are SILENT is specified then a Multiset containing a single set with all values unbound is returned
                    //Unless some of the SPARQL queries did return results in which we just return the results we did obtain
                    if (context.OutputMultiset.IsEmpty)
                    {
                        Set s = new Set();
                        foreach (String var in this._pattern.Variables.Distinct())
                        {
                            s.Add(var, null);
                        }
                        context.OutputMultiset.Add(s);
                    }
                    return context.OutputMultiset;
                }
                else
                {
                    throw new RdfQueryException("Query execution failed because evaluating a SERVICE clause failed - this may be due to an error with the remote service", ex);
                }
            }
        }