Coverage report: /development/source/library/org/datagraph/spocq-shard/src/store/service-description.lisp

KindCoveredAll%
expression122154 79.2
branch816 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; -*-
2
 
3
 (in-package :org.datagraph.spocq.implementation)
4
 ;; (load "/development/source/library/org/datagraph/spocq/src/store/property-paths.lisp")
5
 
6
 
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.
11
 
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 
16
  
17
  ---
18
  [1] http://www.w3.org/TR/sparql11-service-description/
19
 ")
20
 
21
 (defstruct (service-description (:include symbolic-solution-field
22
                                           (dimensions *describe-dimensions*)))
23
   (timestamp 0))
24
 
25
 
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.")
31
 
32
   (:method ((repository-id string))
33
     (repository-service-description (repository repository-id)))
34
 
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))))
39
       (if *transaction*
40
           (make-with-transaction)
41
           (with-open-repository (repository :read-only t :read-only-p t :normal-dispositon :abort)
42
             (make-with-transaction))))))
43
 
44
 
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))
79
            (stream-description
80
             (when revision-bounds
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)
94
       ,@stream-description
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))))
125
 
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))
145
       
146
       ;; features
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|))))))
161
 
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."
165
     ))
166
 
167
 ;;; (with-open-repository ((lookup-repository-id :account-name "jhacker" :repository-name "basic-term-1")) (compute-repository-service-description-solutions *repository*))
168
 #+(or)
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)
174
       
175
 
176
 
177
       
178
       
179
 
180
 
181