Skip to content

Commit

Permalink
Improve support for the Federation Extension #63
Browse files Browse the repository at this point in the history
  • Loading branch information
m-mohr committed Jan 3, 2025
1 parent 4b2e45d commit fd78bb8
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 21 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- New function `getMissingBackends` for `Logs`
- New property `federation:backends` added to the array returned by `validateProcess`

## [2.6.0] - 2024-07-11

### Added
Expand Down
64 changes: 48 additions & 16 deletions openeo.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ declare module OpenEO {
* @param {string|Buffer} str - String to encode.
* @returns {string} String encoded in Base64.
*/
static base64encode(str: string|Buffer): string;
static base64encode(str: string | Buffer): string;
/**
* Detect the file name for the given data source.
*
Expand Down Expand Up @@ -302,14 +302,14 @@ declare module OpenEO {
username: string;
/**
* Authenticate with HTTP Basic.
*
*
* @async
* @param {string} username
* @param {string} password
* @param {string} username
* @param {string} password
* @returns {Promise<void>}
* @throws {Error}
*/
login(username: string, password: string) : Promise<void>;
login(username: string, password: string): Promise<void>;
}
/**
* Capabilities of a back-end.
Expand Down Expand Up @@ -652,7 +652,7 @@ declare module OpenEO {
* @public
* @type {Array.<string>}
*/
public "federation:missing": Array<string>;
public 'federation:missing': Array<string>;
/**
* Returns the file types response as a JSON serializable representation of the data that is API compliant.
*
Expand Down Expand Up @@ -812,9 +812,26 @@ declare module OpenEO {
* @type {Connection}
*/
protected connection: Connection;
endpoint: string;
lastId: string;
level: string;
/**
* @protected
* @type {string}
*/
protected endpoint: string;
/**
* @protected
* @type {string}
*/
protected lastId: string;
/**
* @protected
* @type {?string}
*/
protected level: string | null;
/**
* @protected
* @type {Set<String>}
*/
protected missing: Set<string>;
/**
* Retrieves the next log entries since the last request.
*
Expand All @@ -825,6 +842,16 @@ declare module OpenEO {
* @returns {Promise<Array.<Log>>}
*/
nextLogs(limit?: number): Promise<Array<Log>>;
/**
* Retrieves the backend identifiers that are (partially) missing in the logs.
*
* This is only filled after the first request using `nextLogs` or `next`.
*
* @returns {Array.<string>}
* @see {Logs#nextLogs}
* @see {Logs#next}
*/
getMissingBackends(): Array<string>;
/**
* Retrieves the next log entries since the last request.
*
Expand Down Expand Up @@ -2259,10 +2286,10 @@ declare module OpenEO {
*
* @async
* @param {Process} process - User-defined process to validate.
* @returns {Promise<Array.<ApiError>>} errors - A list of API compatible error objects. A valid process returns an empty list.
* @returns {Promise<ValidationResult>} errors - A list of API compatible error objects. A valid process returns an empty list.
* @throws {Error}
*/
validateProcess(process: Process): Promise<Array<ApiError>>;
validateProcess(process: Process): Promise<ValidationResult>;
/**
* Lists all user-defined processes of the authenticated user.
*
Expand Down Expand Up @@ -2413,7 +2440,7 @@ declare module OpenEO {
protected _getLinkHref(links: Array<Link>, rel: string | Array<string>): string | null;
/**
* Makes all links in the list absolute.
*
*
* @param {Array.<Link>} links - An array of links.
* @param {?string|AxiosResponse} [base=null] - The base url to use for relative links, or an response to derive the url from.
* @returns {Array.<Link>}
Expand Down Expand Up @@ -2492,11 +2519,11 @@ declare module OpenEO {
download(url: string, authorize: boolean): Promise<Readable | Blob>;
/**
* Get the authorization header for requests.
*
*
* @protected
* @returns {object.<string, string>}
*/
protected _getAuthHeaders() : object<string, string>;
protected _getAuthHeaders(): object<string, string>;
/**
* Sends a HTTP request.
*
Expand Down Expand Up @@ -2876,7 +2903,7 @@ declare module OpenEO {
*
* Adds two properties: `links` and `federation:missing`.
*/
export type ResponseArray = Array;
export type ResponseArray = any;
export type ServiceType = object<string, any>;
export type SyncResult = {
/**
Expand Down Expand Up @@ -2915,7 +2942,12 @@ declare module OpenEO {
budget: number | null;
links: Array<Link> | null;
};

/**
* An array, but enriched with additional details from an openEO API response.
*
* Adds the property `federation:backends`.
*/
export type ValidationResult = any;
}

export = OpenEO;
6 changes: 4 additions & 2 deletions src/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -728,13 +728,15 @@ class Connection {
*
* @async
* @param {Process} process - User-defined process to validate.
* @returns {Promise<Array.<ApiError>>} errors - A list of API compatible error objects. A valid process returns an empty list.
* @returns {Promise<ValidationResult>} errors - A list of API compatible error objects. A valid process returns an empty list.
* @throws {Error}
*/
async validateProcess(process) {
let response = await this._post('/validation', this._normalizeUserProcess(process).process);
if (Array.isArray(response.data.errors)) {
return response.data.errors;
const errors = response.data.errors;
errors['federation:backends'] = Array.isArray(response.data['federation:missing']) ? response.data['federation:missing'] : [];
return errors;
}
else {
throw new Error("Invalid validation response received.");
Expand Down
36 changes: 36 additions & 0 deletions src/logs.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,26 @@ class Logs {
* @type {Connection}
*/
this.connection = connection;
/**
* @protected
* @type {string}
*/
this.endpoint = endpoint;
/**
* @protected
* @type {string}
*/
this.lastId = "";
/**
* @protected
* @type {?string}
*/
this.level = level;
/**
* @protected
* @type {Set<String>}

Check warning on line 38 in src/logs.js

View workflow job for this annotation

GitHub Actions / checks

Invalid JSDoc @type type "String"; prefer: "string"

Check warning on line 38 in src/logs.js

View workflow job for this annotation

GitHub Actions / checks

Invalid JSDoc @type type "String"; prefer: "string"
*/
this.missing = new Set();
}

/**
Expand All @@ -37,6 +54,19 @@ class Logs {
return Array.isArray(response.logs) ? response.logs : [];
}

/**
* Retrieves the backend identifiers that are (partially) missing in the logs.
*
* This is only filled after the first request using `nextLogs` or `next`.
*
* @returns {Array.<string>}
* @see {Logs#nextLogs}
* @see {Logs#next}
*/
getMissingBackends() {
return Array.from(this.missing);
}

/**
* Retrieves the next log entries since the last request.
*
Expand Down Expand Up @@ -64,7 +94,13 @@ class Logs {
else {
response.data.logs = [];
}

response.data.links = Array.isArray(response.data.links) ? response.data.links : [];

if (Array.isArray(response.data["federation:missing"])) {
response.data["federation:missing"].forEach(backend => this.missing.add(backend));
}

return response.data;
}

Expand Down
15 changes: 13 additions & 2 deletions src/typedefs.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@
* An array of backends in the federation.
*
* @typedef FederationBackend
* @type {Object}
* @type {object}
* @property {string} url URL to the versioned API endpoint of the back-end.
* @property {string} title Name of the back-end.
* @property {string} description A description of the back-end and its specifics.
Expand Down Expand Up @@ -257,4 +257,15 @@
* @property {?UserAccountStorage} storage
* @property {?number} budget
* @property {?Array.<Link>} links
*/
*/

/**
* An array, but enriched with additional details from an openEO API response.
*
* Adds the property `federation:backends`.
*
* @typedef ValidationResult
* @augments Array
* @type {Array.<ApiError>}
* @property {Array.<string>} ["federation:backends"] The back-ends that support / do not support the process.
*/
6 changes: 5 additions & 1 deletion tests/earthengine.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,8 @@ describe('GEE back-end', () => {
test('Valid process graph', async () => {
let result = await con.validateProcess(VALID_PROCESS);
expect(Array.isArray(result)).toBeTruthy();
expect(result).toEqual([]);
expect(result.length).toBe(0);
expect(result["federation:backends"]).toEqual([]);
});

test('Invalid process graph', async () => {
Expand Down Expand Up @@ -485,11 +486,14 @@ describe('GEE back-end', () => {
test('Debug Job', async () => {
let logsIterator = job.debugJob();
expect(logsIterator instanceof Logs).toBeTruthy();
expect(logsIterator.getMissingBackends()).toEqual([]);
let logs1 = await logsIterator.next();
expect(Array.isArray(logs1.logs)).toBeTruthy();
expect(Array.isArray(logs1.links)).toBeTruthy();
expect(logsIterator.getMissingBackends()).toEqual([]);
let logs2 = await logsIterator.nextLogs();
expect(Array.isArray(logs2)).toBeTruthy();
expect(logsIterator.getMissingBackends()).toEqual([]);
// ToDo: Add more tests
});

Expand Down

0 comments on commit fd78bb8

Please sign in to comment.