Reputation: 3047
I am not sure if its the way I am using HyperGraphQL
or my limited knowledge of SPARQL/RDF, any pointers will be greatly appreciated.
I am trying to setup multiple SPARQL endpoints and want to be able to create a graph that is able to span across these endpoint.
I have tried to use the following chinook.db
and I have split this data in to 3 different SPARQL services like shown below:
I am trying to create a SPARQL link across these service boundaries, for e.g. customers
object in Orders
service has a link to a employees
object in HR
service so that when I query for Customer
I am able to get (Orders)Customer.SupportedRep --> (HR)Employee
. basically I should be able to get Employee details supporting that customer.
I have setup my configuration like below:
1. chinook.json
{
"name": "chinook-hgql",
"schema": "chinook.graphql",
"server": {
"port": 8889,
"graphql": "/graphql",
"graphiql": "/graphiql"
},
"services": [
{
"id": "chinook-orders-sparql",
"type": "LocalModelSPARQLService",
"filepath": "chinook/chinook-orders.ttl",
"filetype": "TTL"
},
{
"id": "chinook-hr-sparql",
"type": "SPARQLEndpointService",
"url": "http://localhost:7003/sparql",
"graph": "",
"user": "",
"password": ""
}
]
}
2: Schema File: chinook.graphql
type __Context {
Customers: _@href(iri: "http://localhost:7002/resource/vocab/CUSTOMERS")
Employees: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES")
label: _@href(iri: "http://www.w3.org/2000/01/rdf-schema#label")
comment: _@href(iri: "http://www.w3.org/2000/01/rdf-schema#comment")
customerId: _@href(iri: "http://localhost:7002/resource/vocab/CUSTOMERS_CUSTOMERID")
customerFirstName: _@href(iri: "http://localhost:7002/resource/vocab/CUSTOMERS_FIRSTNAME")
customerLastName: _@href(iri: "http://localhost:7002/resource/vocab/CUSTOMERS_LASTNAME")
customerCompany: _@href(iri: "http://localhost:7002/resource/vocab/CUSTOMERS_COMPANY")
customerAddress: _@href(iri: "http://localhost:7002/resource/vocab/CUSTOMERS_ADDRESS")
customerCity: _@href(iri: "http://localhost:7002/resource/vocab/CUSTOMERS_CITY")
customerState: _@href(iri: "http://localhost:7002/resource/vocab/CUSTOMERS_STATE")
customerCountry: _@href(iri: "http://localhost:7002/resource/vocab/CUSTOMERS_COUNTRY")
customerPostalCode: _@href(iri: "http://localhost:7002/resource/vocab/CUSTOMERS_POSTALCODE")
customerPhone: _@href(iri: "http://localhost:7002/resource/vocab/CUSTOMERS_PHONE")
customerFax: _@href(iri: "http://localhost:7002/resource/vocab/CUSTOMERS_FAX")
customerEmail: _@href(iri: "http://localhost:7002/resource/vocab/CUSTOMERS_EMAIL")
SupportRep: _@href(iri: "http://localhost:7002/resource/vocab/CUSTOMERS_SUPPORTREPID")
employeeId: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES_EMPLOYEEID")
employeeFirstName: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES_FIRSTNAME")
employeeLastName: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES_LASTNAME")
employeeTitle: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES_TITLE")
employeeReportsTo: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES_REPORTSTO")
employeeBirthDate: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES_BIRTHDATE")
employeeHireDate: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES_HIREDATE")
employeeAddress: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES_ADDRESS")
employeeCity: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES_CITY")
employeeState: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES_STATE")
employeeCountry: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES_COUNTRY")
employeePostalCode: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES_POSTALCODE")
employeePhone: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES_PHONE")
employeeFax: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES_FAX")
employeeEmail: _@href(iri: "http://localhost:7003/resource/vocab/EMPLOYEES_EMAIL")
}
type Customers @service(id:"chinook-orders-sparql") {
customerId: String @service(id:"chinook-orders-sparql")
customerFirstName: String @service(id:"chinook-orders-sparql")
customerLastName: String @service(id:"chinook-orders-sparql")
customerCompany: String @service(id:"chinook-orders-sparql")
customerAddress: String @service(id:"chinook-orders-sparql")
customerCity: String @service(id:"chinook-orders-sparql")
customerState: String @service(id:"chinook-orders-sparql")
customerCountry: String @service(id:"chinook-orders-sparql")
customerPostalCode: String @service(id:"chinook-orders-sparql")
customerPhone: String @service(id:"chinook-orders-sparql")
customerFax: String @service(id:"chinook-orders-sparql")
customerEmail: String @service(id:"chinook-orders-sparql")
SupportRep: Employees @service(id:"chinook-hr-sparql")
}
type Employees @service(id:"chinook-hr-sparql") {
employeeId: String @service(id:"chinook-hr-sparql")
employeeFirstName: String @service(id:"chinook-hr-sparql")
employeeLastName: String @service(id:"chinook-hr-sparql")
employeeTitle: String @service(id:"chinook-hr-sparql")
employeeReportsTo: Employees @service(id:"chinook-hr-sparql")
employeeBirthDate: String @service(id:"chinook-hr-sparql")
employeeHireDate: String @service(id:"chinook-hr-sparql")
employeeAddress: String @service(id:"chinook-hr-sparql")
employeeCity: String @service(id:"chinook-hr-sparql")
employeeState: String @service(id:"chinook-hr-sparql")
employeeCountry: String @service(id:"chinook-hr-sparql")
employeePostalCode: String @service(id:"chinook-hr-sparql")
employeePhone: String @service(id:"chinook-hr-sparql")
employeeFax: String @service(id:"chinook-hr-sparql")
employeeEmail: String @service(id:"chinook-hr-sparql")
}
Please notice how I am trying to build this relationship above, and this is where I am having issues:
SupportRep: Employees @service(id:"chinook-hr-sparql")
ALSO in my data in the TTL file I have changes the links for SupportRep to have the links to the URI of HR system by manually editing the values to show the following:
<http://localhost:7002/resource/CUSTOMERS/1> rdf:type owl:NamedIndividual ,
vocab:CUSTOMERS ;
vocab:CUSTOMERS_ADDRESS "Av. Brigadeiro Faria Lima, 2170" ;
vocab:CUSTOMERS_CITY "São José dos Campos" ;
vocab:CUSTOMERS_COMPANY "Embraer - Empresa Brasileira de Aeronáutica S.A." ;
vocab:CUSTOMERS_COUNTRY "Brazil" ;
vocab:CUSTOMERS_CUSTOMERID 1 ;
vocab:CUSTOMERS_EMAIL "[email protected]" ;
vocab:CUSTOMERS_FAX "+55 (12) 3923-5566" ;
vocab:CUSTOMERS_FIRSTNAME "Luís" ;
vocab:CUSTOMERS_LASTNAME "Gonçalves" ;
vocab:CUSTOMERS_PHONE "+55 (12) 3923-5555" ;
vocab:CUSTOMERS_POSTALCODE "12227-000" ;
vocab:CUSTOMERS_STATE "SP" ;
vocab:CUSTOMERS_SUPPORTREPID <http://localhost:7003/resource/EMPLOYEES/3> ;
rdfs:label "CUSTOMERS #1" .
Please notice the vocab:CUSTOMERS_SUPPORTREPID <http://localhost:7003/resource/EMPLOYEES/3>
how it points to an outside URL on port 7003
instead of 7002
When I try to fetch the Customer's SupportRep Name, the query is failing on the HyperGraphQL
with following message:
java.util.concurrent.ExecutionException: HttpException: 400 HTTP 400 error making the query:
Parse error: SELECT * WHERE { VALUES ?x_2 { <http://localhost:7002/resource/CUSTOMERS/11> } OPTIONAL { ?x_2 <http://localhost:7002/resource/vocab/CUSTOMERS_SUPPORTREPID> ?x_2_1 . ?x_2_1 a <http://localhost:7003/resource/vocab/EMPLOYEES> OPTIONAL { ?x_2_1 <http://localhost:7003/resource/vocab/EMPLOYEES_FIRSTNAME> ?x_2_1_1 } } }
Lexical error at line 3, column 11. Encountered: " " (32), after : "VALUES"
at java.util.concurrent.FutureTask.report(Unknown Source)
at java.util.concurrent.FutureTask.get(Unknown Source)
at org.hypergraphql.datafetching.services.SPARQLEndpointService.iterateFutureResults(SPARQLEndpointService.java:86)
at org.hypergraphql.datafetching.services.SPARQLEndpointService.executeQuery(SPARQLEndpointService.java:69)
at org.hypergraphql.datafetching.ExecutionTreeNode.generateTreeModel(ExecutionTreeNode.java:357)
at org.hypergraphql.datafetching.FetchingExecution.call(FetchingExecution.java:21)
at org.hypergraphql.datafetching.FetchingExecution.call(FetchingExecution.java:8)]
Can someone please help me understand what is wrong with my approach, or how can I fix this issue?
UPDATE 1:
I finally managed to get the logging working and here is what I see on the logs:
[pool-5-thread-1] DEBUG org.hypergraphql.datafetching.SPARQLEndpointExecution - SELECT * WHERE { VALUES ?x_1 { <http://localhost:7002/resource/CUSTOMERS/11> } OPTIONAL { ?x_1 <http://localhost:7002/resource/vocab/CUSTOMERS_SUPPORTREPID> ?x_1_1 .?x_1_1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://localhost:7003/resource/vocab/EMPLOYEES> . OPTIONAL { ?x_1_1 <http://localhost:7003/resource/vocab/EMPLOYEES_FIRSTNAME> ?x_1_1_1 . } } }
[pool-5-thread-1] DEBUG org.apache.jena.riot.web.HttpOp - [1] GET http://localhost:7003/sparql?query=SELECT++*%0AWHERE%0A++%7B+VALUES+%3Fx_1+%7B+%3Chttp%3A%2F%2Flocalhost%3A7002%2Fresource%2FCUSTOMERS%2F11%3E+%7D%0A++++OPTIONAL%0A++++++%7B+%3Fx_1++++%3Chttp%3A%2F%2Flocalhost%3A7002%2Fresource%2Fvocab%2FCUSTOMERS_SUPPORTREPID%3E++%3Fx_1_1+.%0A++++++++%3Fx_1_1++a+++++++++++++++++++++%3Chttp%3A%2F%2Flocalhost%3A7003%2Fresource%2Fvocab%2FEMPLOYEES%3E%0A++++++++OPTIONAL%0A++++++++++%7B+%3Fx_1_1++%3Chttp%3A%2F%2Flocalhost%3A7003%2Fresource%2Fvocab%2FEMPLOYEES_FIRSTNAME%3E++%3Fx_1_1_1+%7D%0A++++++%7D%0A++%7D%0A
So, its actually making the call to the external SPARQL endpoint
however the endpoint at http://localhost:7003/sparql
knows nothing about
{ VALUES ?x_1 { <http://localhost:7002/resource/CUSTOMERS/11> }
how can we address this issue?
Upvotes: 1
Views: 214
Reputation: 3047
I finally figured out that the way HyperGraphQL
generates these SPARQL
is like below
SELECT * WHERE { VALUES ?x_1 { <http://localhost:7002/resource/CUSTOMERS/11> } OPTIONAL { ?x_1 <http://localhost:7002/resource/vocab/CUSTOMERS_SUPPORTREPID> ?x_1_1 .?x_1_1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://localhost:7003/resource/vocab/EMPLOYEES> . OPTIONAL { ?x_1_1 <http://localhost:7003/resource/vocab/EMPLOYEES_FIRSTNAME> ?x_1_1_1 . } } }
and this is actually sent on
http://localhost:7003/sparql?query=
so its basically expecting that there is a graph available on 7003
that contains the customers like this <http://localhost:7002/resource/CUSTOMERS/11>
and ?x_1 <http://localhost:7002/resource/vocab/CUSTOMERS_SUPPORTREPID> ?x_1_1 .
I got it working by copying the customer master data and this relationship over to my HR SYS
on 7003
from Orders SYS
on 7002
then this is working just fine.
However I think this breaks the very purpose of SPARQL
federation.
Upvotes: 1