Skip to content

Commit a902fa1

Browse files
committed
add ledger-specific query route
Also add support for SPARQL protocol headers for specifying query graphs.
1 parent e130e17 commit a902fa1

4 files changed

Lines changed: 63 additions & 5 deletions

File tree

deps.edn

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{:deps {org.clojure/clojure {:mvn/version "1.11.3"}
22
org.clojure/core.async {:mvn/version "1.6.681"}
33
com.fluree/db {:git/url "https://github.com/fluree/db.git"
4-
:git/sha "f2bcf88ddf90c44ef50369da4edcb82f91f023e1"}
4+
:git/sha "f86dffe929d6f1294deb3ec22f4da58e6a989c32"}
55
com.fluree/json-ld {:git/url "https://github.com/fluree/json-ld.git"
66
:git/sha "74083536c84d77f8cdd4b686b5661714010baad3"}
77

src/fluree/server/handler.clj

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,16 @@
189189
:coercion ^:replace query-coercer
190190
:handler #'ledger/query})
191191

192+
(def ledger-query-endpoint
193+
{:summary "Endpoint for submitting queries to a specific ledger"
194+
:parameters {:body QueryRequestBody
195+
:path [:map [:ledger-alias :string]]}
196+
:responses {200 {:body QueryResponse}
197+
400 {:body ErrorResponse}
198+
500 {:body ErrorResponse}}
199+
:coercion ^:replace query-coercer
200+
:handler #'ledger/query})
201+
192202
(def history-endpoint
193203
{:summary "Endpoint for submitting history queries"
194204
:parameters {:body HistoryQuery}
@@ -299,6 +309,12 @@
299309
(select-keys fluree-request-header-keys)
300310
(update-keys (fn [k] (keyword (subs k request-header-prefix-count)))))
301311

312+
;; SPARQL protocol headers for graph specification
313+
from (get headers "default-graph-uri")
314+
from-named (get headers "named-graph-uri")
315+
using (get headers "using-graph-uri")
316+
using-named (get headers "using-named-graph-uri")
317+
302318
max-fuel (when max-fuel
303319
(try (Integer/parseInt max-fuel)
304320
(catch Exception e
@@ -371,6 +387,10 @@
371387
max-fuel (assoc :max-fuel max-fuel)
372388
format (assoc :format format)
373389
output (assoc :output output)
390+
from (assoc :from from)
391+
from-named (assoc :from from-named)
392+
using (assoc :using using)
393+
using-named (assoc :using using-named)
374394
ledger (assoc :ledger ledger)
375395
policy (assoc :policy policy)
376396
policy-class (assoc :policy-class policy-class)
@@ -561,6 +581,10 @@
561581
{:get query-endpoint
562582
:post query-endpoint}])
563583

584+
(def fluree-ledger-query-routes
585+
["/query/{*ledger-alias}"
586+
{:post ledger-query-endpoint}])
587+
564588
(def fluree-history-routes
565589
["/history"
566590
{:get history-endpoint
@@ -599,6 +623,7 @@
599623
:update fluree-update-route
600624
:transact fluree-transact-routes
601625
:query fluree-query-routes
626+
:ledger-query fluree-ledger-query-routes
602627
:history fluree-history-routes
603628
:remote fluree-remote-routes
604629
:subscription fluree-subscription-routes})

src/fluree/server/handlers/ledger.clj

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@
55
[fluree.server.handlers.shared :refer [defhandler deref!] :as shared]))
66

77
(defhandler query
8-
[{:keys [fluree/conn fluree/opts] {:keys [body]} :parameters :as _req}]
8+
[{:keys [fluree/conn fluree/opts] {:keys [body path]} :parameters :as _req}]
99
(let [query (or (::handler/query body) body)
10+
;; supply ledger-alias from path params if not overridden by a header
11+
opts* (update opts :ledger #(or % (:ledger-alias path)))
1012
{:keys [status result] :as query-response}
11-
(deref! (fluree/query-connection conn query opts))]
12-
(log/debug "query handler received query:" query opts)
13+
(deref! (fluree/query-connection conn query opts*))]
14+
(log/debug "query handler received query:" query opts*)
1315
(shared/with-tracking-headers {:status status, :body result}
1416
query-response)))
1517

test/fluree/server/integration/sparql_test.clj

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
(:require [clojure.string :as str]
33
[clojure.test :refer [deftest is testing use-fixtures]]
44
[fluree.db.util.json :as json]
5-
[fluree.server.integration.test-system
5+
[fluree.server.integration.test-system :as test-system
66
:refer [api-post create-rand-ledger run-test-server sparql-headers
77
sparql-results-headers sparql-update-headers]]))
88

@@ -63,3 +63,34 @@
6363
"@graph" [{"@id" "ex:query-sparql-test"
6464
"foo:name" ["query-sparql-test"]}]}
6565
(-> rdf-res :body (json/parse false)))))))
66+
67+
(deftest sparql-federated-query
68+
(let [ledger-name "test-federated-query"
69+
service (str "http://localhost:" @test-system/api-port "/fluree/query/" ledger-name)
70+
71+
txn-req {"ledger" ledger-name
72+
"@context" {"ex" "http://example.com/"}
73+
"insert" (mapv #(do {"@id" (str "ex:" %)
74+
"@type" (if (odd? %) "ex:Odd" "ex:Even")
75+
"ex:name" (str "name" %)
76+
"ex:num" [(dec %) % (inc %)]
77+
"ex:ref" {"@id" (str "ex:" (inc %))}})
78+
(range 10))}
79+
txn-res (api-post :create {:body (json/stringify txn-req) :headers test-system/json-headers})
80+
81+
service-q (str/join "\n" ["PREFIX ex: <http://example.com/>"
82+
"SELECT ?name ?type"
83+
(str "FROM <" ledger-name ">")
84+
"WHERE { ?s a ex:Even ; ex:ref ?ref . "
85+
(str "SERVICE <" service "> { ?ref ex:name ?name ; a ?type . }")
86+
"}"])
87+
service-res (api-post :query {:body service-q :headers sparql-headers})]
88+
(is (= 201 (:status txn-res)))
89+
(is (= 200 (:status service-res)))
90+
(testing "federated query can join across local and remote graphs"
91+
(is (= [["name1" "ex:Odd"]
92+
["name3" "ex:Odd"]
93+
["name5" "ex:Odd"]
94+
["name7" "ex:Odd"]
95+
["name9" "ex:Odd"]]
96+
(-> service-res :body (json/parse false)))))))

0 commit comments

Comments
 (0)