1
+ const Capabilities = require ( "../capabilities" ) ;
2
+ const Utils = require ( '@openeo/js-commons/src/utils' ) ;
3
+ const Migrate = require ( './migrate' ) ;
4
+
5
+ class GdcCapabilities extends Capabilities {
6
+
7
+ constructor ( data ) {
8
+ super ( data ) ;
9
+ Object . assign ( this . featureMap , {
10
+ describeCoverage : 'get /collections/{}/coverage' ,
11
+ describeCoverageDomainset : 'get /collections/{}/coverage/domainset' ,
12
+ describeCoverageRangetype : 'get /collections/{}/coverage/rangetype' ,
13
+ describeCoverageRangeset : 'get /collections/{}/coverage/rangeset' ,
14
+ describeCoverageMetadata : 'get /collections/{}/coverage/metadata' ,
15
+ executeOgcProcess : 'post /processes/{}/execution' ,
16
+ } ) ;
17
+ this . checkConformance ( ) ;
18
+ }
19
+
20
+ getConformanceClasses ( ) {
21
+ if ( ! Array . isArray ( this . data . conformsTo ) ) {
22
+ return [ ] ;
23
+ }
24
+ return this . data . conformsTo ;
25
+ }
26
+
27
+ hasConformance ( uri ) {
28
+ if ( ! Array . isArray ( this . data . conformsTo ) ) {
29
+ return false ;
30
+ }
31
+ return this . data . conformsTo . includes ( uri ) ;
32
+ }
33
+
34
+ _getLink ( rel ) {
35
+ if ( ! Array . isArray ( this . data . links ) ) {
36
+ return null ;
37
+ }
38
+ return this . data . links . find ( link => link . rel === rel ) || null ;
39
+ }
40
+
41
+ checkConformance ( ) {
42
+ if ( ! Array . isArray ( this . data . endpoints ) ) {
43
+ this . data . endpoints = [ ] ;
44
+ }
45
+ const isCoverage = this . hasConformance ( 'http://www.opengis.net/spec/ogcapi-coverages-1/0.0/conf/geodata-coverage' ) ;
46
+ const isFeatures = this . hasConformance ( 'http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/core' ) ;
47
+ if ( isCoverage || isFeatures ) {
48
+ this . data . endpoints . push ( {
49
+ "path" : "/collections" ,
50
+ "methods" : [ "GET" ]
51
+ } ) ;
52
+ this . data . endpoints . push ( {
53
+ "path" : "/collections/{collection_id}" ,
54
+ "methods" : [ "GET" ]
55
+ } ) ;
56
+ }
57
+ // if (isFeatures) {
58
+ // this.data.endpoints.push({
59
+ // "path": "/collections/{collection_id}/items",
60
+ // "methods": ["GET"]
61
+ // });
62
+ // this.data.endpoints.push({
63
+ // "path": "/collections/{collection_id}/items/{item_id}",
64
+ // "methods": ["GET"]
65
+ // });
66
+ // }
67
+ if ( isCoverage ) {
68
+ this . data . endpoints . push ( {
69
+ "path" : "/collections/{collection_id}/coverage" ,
70
+ "methods" : [ "GET" ]
71
+ } ) ;
72
+ this . data . endpoints . push ( {
73
+ "path" : "/collections/{collection_id}/coverage" ,
74
+ "methods" : [ "GET" ]
75
+ } ) ;
76
+ this . data . endpoints . push ( {
77
+ "path" : "/collections/{collection_id}/coverage/domainset" ,
78
+ "methods" : [ "GET" ]
79
+ } ) ;
80
+ this . data . endpoints . push ( {
81
+ "path" : "/collections/{collection_id}/coverage/rangetype" ,
82
+ "methods" : [ "GET" ]
83
+ } ) ;
84
+ this . data . endpoints . push ( {
85
+ "path" : "/collections/{collection_id}/coverage/rangeset" ,
86
+ "methods" : [ "GET" ]
87
+ } ) ;
88
+ this . data . endpoints . push ( {
89
+ "path" : "/collections/{collection_id}/coverage/metadata" ,
90
+ "methods" : [ "GET" ]
91
+ } ) ;
92
+ }
93
+ const isProcessApi = this . hasConformance ( 'http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/core' ) ;
94
+ const processDismiss = this . hasConformance ( 'http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/dismiss' ) ;
95
+ const processJobList = this . hasConformance ( 'http://www.opengis.net/spec/ogcapi-processes-1/1.0/req/job-list' ) ;
96
+ const processLink = this . _getLink ( 'https://www.opengis.net/def/rel/ogc/1.0/processes' ) ;
97
+ if ( isProcessApi || processLink ) {
98
+ this . data . endpoints . push ( {
99
+ "path" : "/processes" ,
100
+ "methods" : [ "GET" ]
101
+ } ) ;
102
+ this . data . endpoints . push ( {
103
+ "path" : "/processes/{processId}" ,
104
+ "methods" : [ "GET" ]
105
+ } ) ;
106
+ this . data . endpoints . push ( {
107
+ "path" : "/processes/{processId}/execution" ,
108
+ "methods" : [ "POST" ]
109
+ } ) ;
110
+ let jobMethods = [ "GET" ] ;
111
+ if ( processDismiss ) { // @todo Is dismiss equivalent to openEO job cancellation or deletion?
112
+ jobMethods . push ( "DELETE" ) ;
113
+ }
114
+ this . data . endpoints . push ( {
115
+ "path" : "/jobs/{job_id}" ,
116
+ "methods" : jobMethods
117
+ } ) ;
118
+ this . data . endpoints . push ( {
119
+ "path" : "/jobs/{job_id}/results" ,
120
+ "methods" : [ "GET" ]
121
+ } ) ;
122
+ }
123
+ const jobLink = this . _getLink ( 'https://www.opengis.net/def/rel/ogc/1.0/job-list' ) ;
124
+ if ( processJobList || jobLink ) {
125
+ this . data . endpoints . push ( {
126
+ "path" : "/jobs" ,
127
+ "methods" : [ "GET" ]
128
+ } ) ;
129
+ }
130
+ this . init ( ) ;
131
+ }
132
+
133
+ /**
134
+ * Initializes the class.
135
+ *
136
+ * @protected
137
+ */
138
+ init ( ) {
139
+ if ( Array . isArray ( this . data . endpoints ) ) {
140
+ super . init ( ) ;
141
+ }
142
+ }
143
+
144
+ /**
145
+ * Validates the capabilities.
146
+ *
147
+ * Throws an error in case of an issue, otherwise just passes.
148
+ *
149
+ * @protected
150
+ * @throws {Error }
151
+ */
152
+ validate ( ) {
153
+ if ( ! Utils . isObject ( this . data ) ) {
154
+ throw new Error ( "No capabilities retrieved." ) ;
155
+ }
156
+ }
157
+
158
+ /**
159
+ * Returns the openEO API version implemented by the back-end.
160
+ *
161
+ * @returns {string } openEO API version number.F
162
+ */
163
+ apiVersion ( ) {
164
+ return this . data . api_version ;
165
+ }
166
+
167
+ /**
168
+ * Returns the GDC API version implemented by the back-end.
169
+ *
170
+ * @returns {string } GDC API version number.
171
+ */
172
+ gdcVersion ( ) {
173
+ return this . data . gdc_version || "1.0.0-beta" ;
174
+ }
175
+
176
+ isEndpoint ( response , method , endpoint ) {
177
+ if ( response . config . method !== method ) {
178
+ return false ;
179
+ }
180
+ if ( endpoint . includes ( '{}' ) ) {
181
+ let pattern = '^' + endpoint . replace ( '{}' , '[^/]+' ) + '$' ;
182
+ let regex = new RegExp ( pattern ) ;
183
+ return regex . test ( response . config . url ) ;
184
+ }
185
+ return endpoint === response . config . url ;
186
+ }
187
+
188
+ /**
189
+ * Migrates a response, if required.
190
+ *
191
+ * @param {AxiosResponse } response
192
+ * @protected
193
+ * @returns {AxiosResponse }
194
+ */
195
+ migrate ( response ) {
196
+ if ( this . isEndpoint ( response , 'get' , '/collections' ) ) {
197
+ response . data . collections = response . data . collections . map ( collection => Migrate . collection ( collection , response ) ) ;
198
+ }
199
+ else if ( this . isEndpoint ( response , 'get' , '/collections/{}' ) ) {
200
+ response . data = Migrate . collection ( response . data , response ) ;
201
+ }
202
+ else if ( this . isEndpoint ( response , 'get' , '/processes' ) ) {
203
+ response . data . processes = response . data . processes . map ( process => Migrate . process ( process , response ) ) ;
204
+ }
205
+ else if ( this . isEndpoint ( response , 'get' , '/jobs' ) ) {
206
+ response . data . jobs = response . data . jobs . map ( job => Migrate . job ( job , response ) ) ;
207
+ }
208
+ else if ( this . isEndpoint ( response , 'get' , '/jobs/{}' ) ) {
209
+ response . data = Migrate . job ( response . data , response ) ;
210
+ }
211
+
212
+ response = Migrate . all ( response ) ;
213
+
214
+ return response ;
215
+ }
216
+ }
217
+
218
+
219
+ module . exports = GdcCapabilities ;
0 commit comments