-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,7 +8,8 @@ const AuthProvider = require('./authprovider'); | |
const BasicProvider = require('./basicprovider'); | ||
const OidcProvider = require('./oidcprovider'); | ||
|
||
const Capabilities = require('./capabilities'); | ||
const GdcCapabilities = require('./gdc/capabilities'); | ||
const GdcMigrate = require('./gdc/migrate'); | ||
const FileTypes = require('./filetypes'); | ||
const UserFile = require('./userfile'); | ||
const Job = require('./job'); | ||
|
@@ -18,6 +19,7 @@ const Service = require('./service'); | |
const Builder = require('./builder/builder'); | ||
const BuilderNode = require('./builder/node'); | ||
|
||
|
||
const CONFORMANCE_RELS = [ | ||
'conformance', | ||
'http://www.opengis.net/def/rel/ogc/1.0/conformance' | ||
|
@@ -120,7 +122,8 @@ class Connection { | |
} | ||
} | ||
|
||
this.capabilitiesObject = new Capabilities(data); | ||
GdcMigrate.connection = this; | ||
this.capabilitiesObject = new GdcCapabilities(data); | ||
return this.capabilitiesObject; | ||
} | ||
|
||
|
@@ -802,6 +805,45 @@ class Connection { | |
return await pg.describeUserProcess(); | ||
} | ||
|
||
isOgcProcess(process) { | ||
Check failure on line 808 in src/connection.js GitHub Actions / checks
|
||
let nodes = Object.values(process.process_graph); | ||
return Boolean(nodes.find(node => { | ||
let process = this.processes.get(node.process_id); | ||
Check failure on line 811 in src/connection.js GitHub Actions / checks
|
||
return Utils.isObject(process) && Boolean(process.ogcapi); | ||
})); | ||
} | ||
|
||
async executeOgcProcess(process, abortController = null) { | ||
Check failure on line 816 in src/connection.js GitHub Actions / checks
|
||
let openEO = this._normalizeUserProcess(process); | ||
let mode = null; | ||
let p = Object.values(openEO.process.process_graph).find(v => { | ||
let spec = this.processes.get(v.process_id); | ||
if (Array.isArray(spec.jobControlOptions) && spec.jobControlOptions.includes("async-execute")) { | ||
mode = 'async'; | ||
} | ||
return Boolean(spec && spec.ogcapi); | ||
}); | ||
let requestBody = GdcMigrate.execute(openEO); | ||
let headers = {}; | ||
if (mode === 'async') { | ||
headers.Prefer = 'respond-async'; | ||
} | ||
console.log(p.process_id, requestBody, headers); // @todo remove | ||
let response = await this._post(`/processes/${p.process_id}/execution`, requestBody, Environment.getResponseType(), abortController, headers); | ||
let syncResult = { | ||
data: response.data, | ||
costs: null, | ||
type: null, | ||
logs: [] | ||
}; | ||
|
||
if (typeof response.headers['content-type'] === 'string') { | ||
syncResult.type = response.headers['content-type']; | ||
} | ||
|
||
return syncResult; | ||
} | ||
|
||
/** | ||
* Executes a process synchronously and returns the result as the response. | ||
* | ||
|
@@ -823,6 +865,9 @@ class Connection { | |
budget: budget | ||
}) | ||
); | ||
if (this.isOgcProcess(requestBody.process)) { | ||
return this.executeOgcProcess(process, abortController); | ||
} | ||
let response = await this._post('/result', requestBody, Environment.getResponseType(), abortController); | ||
let syncResult = { | ||
data: response.data, | ||
|
@@ -1131,16 +1176,18 @@ class Connection { | |
* @param {*} body | ||
* @param {string} responseType - Response type according to axios, defaults to `json`. | ||
* @param {?AbortController} [abortController=null] - An AbortController object that can be used to cancel the request. | ||
* @param {Array.<Object.<string, string>>} [headers={}] - Headers | ||
Check warning on line 1179 in src/connection.js GitHub Actions / checks
Check warning on line 1179 in src/connection.js GitHub Actions / checks
|
||
* @returns {Promise<AxiosResponse>} | ||
* @throws {Error} | ||
* @see https://github.com/axios/axios#request-config | ||
*/ | ||
async _post(path, body, responseType, abortController = null) { | ||
async _post(path, body, responseType, abortController = null, headers = {}) { | ||
let options = { | ||
method: 'post', | ||
responseType: responseType, | ||
responseType, | ||
url: path, | ||
data: body | ||
data: body, | ||
headers | ||
}; | ||
return await this._send(options, abortController); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,219 @@ | ||
const Capabilities = require("../capabilities"); | ||
const Utils = require('@openeo/js-commons/src/utils'); | ||
const Migrate = require('./migrate'); | ||
|
||
class GdcCapabilities extends Capabilities { | ||
Check failure on line 5 in src/gdc/capabilities.js GitHub Actions / checks
|
||
|
||
constructor(data) { | ||
Check failure on line 7 in src/gdc/capabilities.js GitHub Actions / checks
|
||
super(data); | ||
Object.assign(this.featureMap, { | ||
describeCoverage: 'get /collections/{}/coverage', | ||
describeCoverageDomainset: 'get /collections/{}/coverage/domainset', | ||
describeCoverageRangetype: 'get /collections/{}/coverage/rangetype', | ||
describeCoverageRangeset: 'get /collections/{}/coverage/rangeset', | ||
describeCoverageMetadata: 'get /collections/{}/coverage/metadata', | ||
executeOgcProcess: 'post /processes/{}/execution', | ||
}); | ||
this.checkConformance(); | ||
} | ||
|
||
getConformanceClasses() { | ||
Check failure on line 20 in src/gdc/capabilities.js GitHub Actions / checks
|
||
if(!Array.isArray(this.data.conformsTo)) { | ||
return []; | ||
} | ||
return this.data.conformsTo; | ||
} | ||
|
||
hasConformance(uri) { | ||
Check failure on line 27 in src/gdc/capabilities.js GitHub Actions / checks
|
||
if(!Array.isArray(this.data.conformsTo)) { | ||
return false; | ||
} | ||
return this.data.conformsTo.includes(uri); | ||
} | ||
|
||
_getLink(rel) { | ||
Check failure on line 34 in src/gdc/capabilities.js GitHub Actions / checks
|
||
if (!Array.isArray(this.data.links)) { | ||
return null; | ||
} | ||
return this.data.links.find(link => link.rel === rel) || null; | ||
} | ||
|
||
checkConformance() { | ||
Check failure on line 41 in src/gdc/capabilities.js GitHub Actions / checks
|
||
if (!Array.isArray(this.data.endpoints)) { | ||
this.data.endpoints = []; | ||
} | ||
const isCoverage = this.hasConformance('http://www.opengis.net/spec/ogcapi-coverages-1/0.0/conf/geodata-coverage'); | ||
const isFeatures = this.hasConformance('http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/core'); | ||
if (isCoverage || isFeatures) { | ||
this.data.endpoints.push({ | ||
"path": "/collections", | ||
"methods": ["GET"] | ||
}); | ||
this.data.endpoints.push({ | ||
"path": "/collections/{collection_id}", | ||
"methods": ["GET"] | ||
}); | ||
} | ||
// if (isFeatures) { | ||
// this.data.endpoints.push({ | ||
// "path": "/collections/{collection_id}/items", | ||
// "methods": ["GET"] | ||
// }); | ||
// this.data.endpoints.push({ | ||
// "path": "/collections/{collection_id}/items/{item_id}", | ||
// "methods": ["GET"] | ||
// }); | ||
// } | ||
if (isCoverage) { | ||
this.data.endpoints.push({ | ||
"path": "/collections/{collection_id}/coverage", | ||
"methods": ["GET"] | ||
}); | ||
this.data.endpoints.push({ | ||
"path": "/collections/{collection_id}/coverage", | ||
"methods": ["GET"] | ||
}); | ||
this.data.endpoints.push({ | ||
"path": "/collections/{collection_id}/coverage/domainset", | ||
"methods": ["GET"] | ||
}); | ||
this.data.endpoints.push({ | ||
"path": "/collections/{collection_id}/coverage/rangetype", | ||
"methods": ["GET"] | ||
}); | ||
this.data.endpoints.push({ | ||
"path": "/collections/{collection_id}/coverage/rangeset", | ||
"methods": ["GET"] | ||
}); | ||
this.data.endpoints.push({ | ||
"path": "/collections/{collection_id}/coverage/metadata", | ||
"methods": ["GET"] | ||
}); | ||
} | ||
const isProcessApi = this.hasConformance('http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/core'); | ||
const processDismiss = this.hasConformance('http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/dismiss'); | ||
const processJobList = this.hasConformance('http://www.opengis.net/spec/ogcapi-processes-1/1.0/req/job-list'); | ||
const processLink = this._getLink('https://www.opengis.net/def/rel/ogc/1.0/processes'); | ||
if (isProcessApi || processLink) { | ||
this.data.endpoints.push({ | ||
"path": "/processes", | ||
"methods": ["GET"] | ||
}); | ||
this.data.endpoints.push({ | ||
"path": "/processes/{processId}", | ||
"methods": ["GET"] | ||
}); | ||
this.data.endpoints.push({ | ||
"path": "/processes/{processId}/execution", | ||
"methods": ["POST"] | ||
}); | ||
let jobMethods = ["GET"]; | ||
if (processDismiss) { // @todo Is dismiss equivalent to openEO job cancellation or deletion? | ||
jobMethods.push("DELETE"); | ||
} | ||
this.data.endpoints.push({ | ||
"path": "/jobs/{job_id}", | ||
"methods": jobMethods | ||
}); | ||
this.data.endpoints.push({ | ||
"path": "/jobs/{job_id}/results", | ||
"methods": ["GET"] | ||
}); | ||
} | ||
const jobLink = this._getLink('https://www.opengis.net/def/rel/ogc/1.0/job-list'); | ||
if (processJobList || jobLink) { | ||
this.data.endpoints.push({ | ||
"path": "/jobs", | ||
"methods": ["GET"] | ||
}); | ||
} | ||
this.init(); | ||
} | ||
|
||
/** | ||
* Initializes the class. | ||
* | ||
* @protected | ||
*/ | ||
init() { | ||
if (Array.isArray(this.data.endpoints)) { | ||
super.init(); | ||
} | ||
} | ||
|
||
/** | ||
* Validates the capabilities. | ||
* | ||
* Throws an error in case of an issue, otherwise just passes. | ||
* | ||
* @protected | ||
* @throws {Error} | ||
*/ | ||
validate() { | ||
if(!Utils.isObject(this.data)) { | ||
throw new Error("No capabilities retrieved."); | ||
} | ||
} | ||
|
||
/** | ||
* Returns the openEO API version implemented by the back-end. | ||
* | ||
* @returns {string} openEO API version number.F | ||
*/ | ||
apiVersion() { | ||
return this.data.api_version; | ||
} | ||
|
||
/** | ||
* Returns the GDC API version implemented by the back-end. | ||
* | ||
* @returns {string} GDC API version number. | ||
*/ | ||
gdcVersion() { | ||
return this.data.gdc_version || "1.0.0-beta"; | ||
} | ||
|
||
isEndpoint(response, method, endpoint) { | ||
Check failure on line 176 in src/gdc/capabilities.js GitHub Actions / checks
|
||
if (response.config.method !== method) { | ||
return false; | ||
} | ||
if (endpoint.includes('{}')) { | ||
let pattern = '^' + endpoint.replace('{}', '[^/]+') + '$'; | ||
let regex = new RegExp(pattern); | ||
return regex.test(response.config.url); | ||
} | ||
return endpoint === response.config.url; | ||
} | ||
|
||
/** | ||
* Migrates a response, if required. | ||
* | ||
* @param {AxiosResponse} response | ||
* @protected | ||
* @returns {AxiosResponse} | ||
*/ | ||
migrate(response) { | ||
if (this.isEndpoint(response, 'get', '/collections')) { | ||
response.data.collections = response.data.collections.map(collection => Migrate.collection(collection, response)); | ||
} | ||
else if (this.isEndpoint(response, 'get', '/collections/{}')) { | ||
response.data = Migrate.collection(response.data, response); | ||
} | ||
else if (this.isEndpoint(response, 'get', '/processes')) { | ||
response.data.processes = response.data.processes.map(process => Migrate.process(process, response)); | ||
} | ||
else if (this.isEndpoint(response, 'get', '/jobs')) { | ||
response.data.jobs = response.data.jobs.map(job => Migrate.job(job, response)); | ||
} | ||
else if (this.isEndpoint(response, 'get', '/jobs/{}')) { | ||
response.data = Migrate.job(response.data, response); | ||
} | ||
|
||
response = Migrate.all(response); | ||
|
||
return response; | ||
} | ||
} | ||
|
||
|
||
module.exports = GdcCapabilities; |