Coverage report: /development/source/library/org/datagraph/spocq-shard/src/store/service-description.lisp
| Kind | Covered | All | % |
| expression | 122 | 154 | 79.2 |
| branch | 8 | 16 | 50.0 |
Key
Not instrumented
Conditionalized out
Executed
Not executed
Both branches taken
One branch taken
Neither branch taken
1
;;; -*- Mode: lisp; Syntax: ansi-common-lisp; Base: 10; Package: org.datagraph.spocq.implementation; -*-
3
(in-package :org.datagraph.spocq.implementation)
4
;; (load "/development/source/library/org/datagraph/spocq/src/store/property-paths.lisp")
7
(:documentation "service descriptions"
8
"Implements support for service descriptions . This includes
9
- generate a description for a Dydra endpoint
10
- retrieve and extract properties from service descriptions for remote entities.
12
in addition to the content specified by the sparql specification[1], the description includes
13
properties for provenance discovery (see provenance.lisp):
14
- prov:hasProvenance for its particular graph in the provenance repository
15
- prov:hasProvenanceService for the uri of the complete provenance repository
18
[1] http://www.w3.org/TR/sparql11-service-description/
21
(defstruct (service-description (:include symbolic-solution-field
22
(dimensions *describe-dimensions*)))
26
(defgeneric repository-service-description (repository)
27
(:documentation "Return the service description for the given repository as a
28
symbolic solution field. Each element is a s-p-o list.
29
Includes the http access resource, settings for default grap/named graphs,
30
entailament settings, and provenance settings.")
32
(:method ((repository-id string))
33
(repository-service-description (repository repository-id)))
35
(:method ((repository repository))
36
(flet ((make-with-transaction ()
37
(make-service-description :solutions (compute-repository-service-description-solutions repository)
38
:timestamp (get-universal-time))))
40
(make-with-transaction)
41
(with-open-repository (repository :read-only t :read-only-p t :normal-dispositon :abort)
42
(make-with-transaction))))))
45
(defgeneric compute-repository-service-description-solutions (repository)
46
(:method ((id string))
47
(compute-repository-service-description-solutions (repository id)))
48
(:method ((id spocq:iri))
49
(compute-repository-service-description-solutions (service-repository id)))
50
(:method ((id puri:uri))
51
(compute-repository-service-description-solutions (service-repository id)))
52
(:method ((repository repository))
53
(let* ((repository-identifier (repository-identifier repository))
54
(repository-url (repository-uri repository))
55
(sparql-endpoint (intern-iri (concatenate 'string (iri-lexical-form repository-url) "/sparql")))
56
(federation-endpoint (intern-iri (concatenate 'string *site-protocol* "://" "localhost" "/"
57
(account-name (repository-account repository)) "/"
58
(repository-name repository))))
59
(revision (repository-revision repository))
60
(revision-uri (revision-uri revision))
61
(provenance-repository-id (metadata-provenance-repository-id repository))
62
(provenance-repository (when (not (string-equal provenance-repository-id "nil"))
63
(repository provenance-repository-id)))
64
(provenance-service-uri (when provenance-repository (repository-uri provenance-repository)))
65
(revision-provenance-service-uri (when (and provenance-repository revision-uri)
66
(intern-iri (format nil "~a?graph=~a"
67
(spocq:iri-lexical-form provenance-service-uri)
68
(spocq:iri-lexical-form revision-uri)))))
69
;; the concrete named graphs should not include the default graph, but
70
;; see below for the available graphs
71
(named-graphs (remove |urn:dydra|:|default|
72
(list-repository-context-objects :repository-handle *transaction*)))
73
(default-dataset-node (cons-blank-node "dataset"))
74
(default-graph-node |urn:dydra|:|default|)
75
(all-graph-node |urn:dydra|:|all|)
76
(named-graph-node |urn:dydra|:|named|)
77
(available-collection-node (cons-blank-node "available"))
78
(revision-bounds (repository-revision-bounds repository))
81
(let ((start (spocq:date-time-interval-start revision-bounds))
82
(end (spocq:date-time-interval-end revision-bounds)))
83
`((,repository-identifier |rdf|:|type| <http://streamreasoning.org/wesp#RDFStream>)
84
(,repository-identifier |rdf|:|type| <http://streamreasoning.org/wesp#RSPService>)
85
(,repository-identifier |prov|:|startedAtTime| ,start)
86
(,repository-identifier |prov|:|endedAtTime| ,end))))))
87
`((,repository-identifier |rdf|:|type| |sd|:|Service|)
88
(,repository-identifier |sd|:|endpoint| ,sparql-endpoint)
89
(,repository-identifier |sd|:|endpoint| ,federation-endpoint)
90
(,repository-identifier |rdf|:|type| |urn:dydra|:|Repository|)
91
(,repository-identifier |rdf|:|type| |http://rdfs.org/ns/void#|:|Dataset|)
92
(,repository-identifier |http://rdfs.org/ns/void#|:|sparqlEndpoint| ,sparql-endpoint)
93
(,repository-identifier |http://rdfs.org/ns/void#|:|sparqlEndpoint| ,federation-endpoint)
95
;; describe the provenance service when the respective repository has been defined
96
,@(when provenance-service-uri
97
`((,repository-identifier |prov|:|hasProvenanceService| ,provenance-service-uri)))
98
,@(when revision-provenance-service-uri
99
`((,repository-identifier |prov|:|hasProvenance| ,revision-provenance-service-uri)))
100
(,repository-identifier |sd|:|defaultDataset| ,default-dataset-node)
101
;; describe the default dataset as per the repository's default context identifier
102
;; indicating either default, named, or all for the default graph
103
(,default-dataset-node |rdf|:|type| |sd|:|Dataset|)
104
(,default-dataset-node |sd|:|defaultGraph| ,(repository-default-context-term repository))
105
(,repository-identifier |sd|:|availableGraphs| ,available-collection-node)
106
(,available-collection-node |rdf|:|type| |sd|:|GraphCollection|)
107
;; indicate that the default graph and the designators for all and 'named' are available
108
;; for use with 'from' and 'using'
109
(,available-collection-node |sd|:|namedGraph| ,default-graph-node)
110
(,default-graph-node |rdf|:|type| |sd|:|Graph|)
111
(,default-graph-node |sd|:|name| ,default-graph-node)
112
(,default-graph-node |void|:|triples| ,(repository-pattern-count repository nil nil nil default-graph-node))
113
(,available-collection-node |sd|:|namedGraph| ,named-graph-node)
114
(,named-graph-node |rdf|:|type| |sd|:|Graph|)
115
(,named-graph-node |sd|:|name| ,named-graph-node)
116
(,available-collection-node |sd|:|namedGraph| ,all-graph-node)
117
(,all-graph-node |rdf|:|type| |sd|:|Graph|)
118
(,all-graph-node |sd|:|name| ,all-graph-node)
119
;; indicate the concrete named graphs
120
,@(loop for named-graph in named-graphs
121
append `((,available-collection-node |sd|:|namedGraph| ,named-graph)
122
(,named-graph |rdf|:|type| |sd|:|NamedGraph|)
123
(,named-graph |sd|:|name| ,named-graph)
124
(,named-graph |void|:|triples| ,(repository-pattern-count repository nil nil nil named-graph))))
126
;; this is a stupid way to specify encodings, but the spec requires these rather than mime types
127
,@(loop for format-iri in '(<http://www.w3.org/ns/formats/RDF_XML>
128
<http://www.w3.org/ns/formats/JSON-LD>
129
<http://www.w3.org/ns/formats/SPARQL_Results_CSV>
130
<http://www.w3.org/ns/formats/SPARQL_Results_JSON>
131
<http://www.w3.org/ns/formats/SPARQL_Results_XML>)
132
collect `(,repository-identifier |sd|:|resultFormat| ,format-iri))
133
,@(loop for (media-type-class format)
134
in '((mime:application/sql <http://www.w3.org/ns/formats/SQL>)
135
(mime:application/sparql-query <http://www.w3.org/ns/formats/SPARQL_Query>))
136
when (find (find-class media-type-class)
137
(generic-function-methods #'send-response-message)
138
:key #'(lambda (m) (fourth (method-specializers m))))
139
collect `(,repository-identifier |sd|:|resultFormat| ,format))
140
,@(loop for format-iri in '(<http://www.w3.org/ns/formats/N-Quads>
141
<http://www.w3.org/ns/formats/N-Triples>
142
<http://www.w3.org/ns/formats/RDF_XML>
143
<http://www.w3.org/ns/formats/Turtle>)
144
collect `(,repository-identifier |sd|:|inputFormat| ,format-iri))
147
(,repository-identifier |sd|:|supportedLanguage| |sd|:|SPARQL10Query|)
148
(,repository-identifier |sd|:|supportedLanguage| |sd|:|SPARQL11Query|)
149
(,repository-identifier |sd|:|supportedLanguage| |sd|:|SPARQL11Update|)
150
;; only if so configured
151
,@(when (eq (repository-default-context-term repository) |urn:dydra|:|all|)
152
`((,repository-identifier |sd|:|feature| |sd|:|UnionDefaultGraph|)))
153
;; sd:EmptyGraphs is _not_ included
154
;; but sd:BasicFederatedQuery can be
155
,@(when (federation-enabled-p repository)
156
`(#+(or)(,repository-identifier |sd|:|feature| |sd|:|DereferencesURIs|)
157
(,repository-identifier |sd|:|feature| |sd|:|BasicFederatedQuery|)))
158
;; if free-text is supported
159
,@(when (text-index-suported-p repository)
160
`((,repository-identifier |sd|:|feature| |sd|:|TextIndex|))))))
162
(:method ((repository service-repository))
163
"If the repository is a serviced by a remote host, attempt to retrieve and
164
cache its service description. If that fails, construct a default property set."
167
;;; (with-open-repository ((lookup-repository-id :account-name "jhacker" :repository-name "basic-term-1")) (compute-repository-service-description-solutions *repository*))
169
(spocq.e:with-open-repository (r (lookup-repository-id :account-name "jhacker" :repository-name "graph-dawg-graph-08"))
170
(loop for context in '(<urn:dydra:default> <urn:dydra:named> <urn:dydra:all>)
171
do (setf (slot-value r 'default-context-term) context)
172
(let ((*print-pretty* nil)) (format t "~%--- ~s~%~{ ~s~^~%~}" context (compute-repository-service-description-solutions r)))))
173
;;; (service-description :repository-id (lookup-repository-id :account-name "jhacker" :repository-name "graph-dawg-graph-08") :response-content-type mime:application/sparql-results+term-number)