From 550ec76a35c5a9a731fcea3da7bf3f84aeae3ace Mon Sep 17 00:00:00 2001 From: "Pablo F. Mescher" Date: Wed, 15 Jan 2020 10:33:42 +0100 Subject: [PATCH 1/6] Decoupled Aquarius class from Ocean class and removed inheritance from Instantiable Signed-off-by: Pablo F. Mescher --- package.json | 2 +- src/aquarius/Aquarius.ts | 31 ++++++++++++++++---------- src/ocean/Ocean.ts | 5 ++--- src/ocean/utils/OceanUtils.ts | 6 ++--- src/ocean/utils/ServiceAgreement.ts | 17 +++++++++----- src/ocean/utils/SignatureUtils.ts | 14 +++++++----- src/ocean/utils/WebServiceConnector.ts | 10 ++++----- src/squid.ts | 3 ++- test/aquarius/Aquarius.test.ts | 12 ++++++++++ 9 files changed, 64 insertions(+), 36 deletions(-) diff --git a/package.json b/package.json index a59d2e2..f6ce6fc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@oceanprotocol/squid", - "version": "1.0.0", + "version": "1.0.2", "description": "JavaScript client library for Ocean Protocol", "main": "./dist/node/squid.js", "typings": "./dist/node/squid.d.ts", diff --git a/src/aquarius/Aquarius.ts b/src/aquarius/Aquarius.ts index bb3c0b2..5cbbfc2 100644 --- a/src/aquarius/Aquarius.ts +++ b/src/aquarius/Aquarius.ts @@ -1,7 +1,8 @@ import { URL } from 'whatwg-url' import { DDO } from '../ddo/DDO' import DID from '../ocean/DID' -import { Instantiable, InstantiableConfig } from '../Instantiable.abstract' +import { Logger } from '../utils' +import { WebServiceConnector } from '../ocean/utils/WebServiceConnector' const apiPath = '/api/v1/aquarius/assets/ddo' @@ -24,22 +25,27 @@ export interface SearchQuery { * Provides a interface with Aquarius. * Aquarius provides an off-chain database store for metadata about data assets. */ -export class Aquarius extends Instantiable { +export class Aquarius { + private fetch: WebServiceConnector + private logger: Logger + private aquariusUri: string + private get url() { - return this.config.aquariusUri + return this.aquariusUri } - constructor(config: InstantiableConfig) { - super() - this.setInstanceConfig(config) + constructor(aquariusUri: string, logger?: Logger) { + this.fetch = new WebServiceConnector(logger) + this.logger = logger + this.aquariusUri = aquariusUri } public async getVersionInfo() { - return (await this.ocean.utils.fetch.get(this.url)).json() + return (await this.fetch.get(this.url)).json() } public async getAccessUrl(accessToken: any, payload: any): Promise { - const accessUrl: string = await this.ocean.utils.fetch + const accessUrl: string = await this.fetch .post(`${accessToken.service_endpoint}/${accessToken.resource_id}`, payload) .then((response: any): string => { if (response.ok) { @@ -69,7 +75,7 @@ export class Aquarius extends Instantiable { * @return {Promise} */ public async queryMetadata(query: SearchQuery): Promise { - const result: QueryResult = await this.ocean.utils.fetch + const result: QueryResult = await this.fetch .post(`${this.url}${apiPath}/query`, JSON.stringify(query)) .then((response: any) => { if (response.ok) { @@ -107,7 +113,8 @@ export class Aquarius extends Instantiable { ) fullUrl.searchParams.append('offset', query.offset.toString()) fullUrl.searchParams.append('page', query.page.toString()) - const result: QueryResult = await this.ocean.utils.fetch + + const result: QueryResult = await this.fetch .get(fullUrl) .then((response: any) => { if (response.ok) { @@ -138,7 +145,7 @@ export class Aquarius extends Instantiable { */ public async storeDDO(ddo: DDO): Promise { const fullUrl = `${this.url}${apiPath}` - const result: DDO = await this.ocean.utils.fetch + const result: DDO = await this.fetch .post(fullUrl, DDO.serialize(ddo)) .then((response: any) => { if (response.ok) { @@ -174,7 +181,7 @@ export class Aquarius extends Instantiable { ): Promise { did = did && DID.parse(did) const fullUrl = metadataServiceEndpoint || `${this.url}${apiPath}/${did.getDid()}` - const result = await this.ocean.utils.fetch + const result = await this.fetch .get(fullUrl) .then((response: any) => { if (response.ok) { diff --git a/src/ocean/Ocean.ts b/src/ocean/Ocean.ts index 1bfead7..e9a0a46 100644 --- a/src/ocean/Ocean.ts +++ b/src/ocean/Ocean.ts @@ -37,10 +37,11 @@ export class Ocean extends Instantiable { } instance.setInstanceConfig(instanceConfig) + instance.utils = await OceanUtils.getInstance(instanceConfig) instance.keeper = await Keeper.getInstance(instanceConfig) instance.brizo = new Brizo(instanceConfig) - instance.aquarius = new Aquarius(instanceConfig) + instance.aquarius = new Aquarius(instanceConfig.config.aquariusUri, instanceConfig.logger) instance.accounts = await OceanAccounts.getInstance(instanceConfig) instance.auth = await OceanAuth.getInstance(instanceConfig) @@ -50,8 +51,6 @@ export class Ocean extends Instantiable { instance.tokens = await OceanTokens.getInstance(instanceConfig) instance.versions = await OceanVersions.getInstance(instanceConfig) - instance.utils = await OceanUtils.getInstance(instanceConfig) - return instance } diff --git a/src/ocean/utils/OceanUtils.ts b/src/ocean/utils/OceanUtils.ts index 2d5a0a2..c285583 100644 --- a/src/ocean/utils/OceanUtils.ts +++ b/src/ocean/utils/OceanUtils.ts @@ -16,9 +16,9 @@ export class OceanUtils extends Instantiable { const instance = new OceanUtils() instance.setInstanceConfig(config) - instance.agreements = new ServiceAgreement(config) - instance.signature = new SignatureUtils(config) - instance.fetch = new WebServiceConnector(config) + instance.agreements = new ServiceAgreement(config.ocean, config.logger, config.web3) + instance.signature = new SignatureUtils(config.web3, config.logger) + instance.fetch = new WebServiceConnector(config.logger) return instance } diff --git a/src/ocean/utils/ServiceAgreement.ts b/src/ocean/utils/ServiceAgreement.ts index 91fd685..05fc249 100644 --- a/src/ocean/utils/ServiceAgreement.ts +++ b/src/ocean/utils/ServiceAgreement.ts @@ -2,13 +2,18 @@ import { ServiceAgreementTemplateCondition } from '../../ddo/ServiceAgreementTem import { DDO } from '../../ddo/DDO' import { ServiceAccess } from '../../ddo/Service' import Account from '../Account' -import { zeroX } from '../../utils' -import { Instantiable, InstantiableConfig } from '../../Instantiable.abstract' +import { zeroX, Logger } from '../../utils' +import { Ocean } from '../../squid' +import Web3 from 'web3' -export class ServiceAgreement extends Instantiable { - constructor(config: InstantiableConfig) { - super() - this.setInstanceConfig(config) +export class ServiceAgreement { + private ocean: Ocean + private logger: Logger + private web3: Web3 + constructor(ocean: Ocean, logger: Logger, web3: Web3) { + this.ocean = ocean + this.logger = logger + this.web3 = web3 } public async signServiceAgreement( diff --git a/src/ocean/utils/SignatureUtils.ts b/src/ocean/utils/SignatureUtils.ts index b37a27e..3879f72 100644 --- a/src/ocean/utils/SignatureUtils.ts +++ b/src/ocean/utils/SignatureUtils.ts @@ -1,9 +1,13 @@ -import { Instantiable, InstantiableConfig } from '../../Instantiable.abstract' +import Web3 from 'web3' +import { Logger } from '../../utils' -export class SignatureUtils extends Instantiable { - constructor(config: InstantiableConfig) { - super() - this.setInstanceConfig(config) +export class SignatureUtils { + private web3: Web3 + private logger: Logger; + + constructor(web3: Web3, logger: Logger) { + this.web3 = web3 + this.logger = logger; } public async signText( diff --git a/src/ocean/utils/WebServiceConnector.ts b/src/ocean/utils/WebServiceConnector.ts index 37a07b9..a8a38e4 100644 --- a/src/ocean/utils/WebServiceConnector.ts +++ b/src/ocean/utils/WebServiceConnector.ts @@ -1,17 +1,17 @@ import { BodyInit, RequestInit, Response } from 'node-fetch' import fs from 'fs' -import { Instantiable, InstantiableConfig } from '../../Instantiable.abstract' const fetch = require('node-fetch') import save = require('save-file') +import { Logger } from '../../utils' /** * Provides a common interface to web services. */ -export class WebServiceConnector extends Instantiable { - constructor(config: InstantiableConfig) { - super() - this.setInstanceConfig(config) +export class WebServiceConnector { + public logger: Logger; + constructor(logger: Logger) { + this.logger = logger; } public post(url: string, payload: BodyInit): Promise { diff --git a/src/squid.ts b/src/squid.ts index 973039f..204fa5d 100644 --- a/src/squid.ts +++ b/src/squid.ts @@ -4,6 +4,7 @@ import DID from './ocean/DID' import { Ocean } from './ocean/Ocean' import { LoggerInstance as Logger } from './utils/Logger' import Keeper from './keeper/Keeper' +import { Aquarius } from './aquarius/Aquarius' import * as templates from './keeper/contracts/templates' import * as conditions from './keeper/contracts/conditions' @@ -24,4 +25,4 @@ export { export { AgreementTemplate } from './keeper/contracts/templates' export { Condition, ConditionState } from './keeper/contracts/conditions' -export { Ocean, Account, Config, DID, Logger, Keeper, conditions, templates, utils } +export { Ocean, Account, Config, DID, Logger, Keeper, Aquarius, conditions, templates, utils } diff --git a/test/aquarius/Aquarius.test.ts b/test/aquarius/Aquarius.test.ts index 7cce648..e0465eb 100644 --- a/test/aquarius/Aquarius.test.ts +++ b/test/aquarius/Aquarius.test.ts @@ -97,6 +97,18 @@ describe('Aquarius', () => { assert.equal(result.totalResults, 1) }) + it('should query metadata by text with a new instance', async () => { + spy.on(ocean.utils.fetch, 'get', () => reponsify(getResults([new DDO()]))) + + const aquariusNew = new Aquarius(config.aquariusUri, ocean.utils, null) + const result = await aquariusNew.queryMetadataByText(query) + assert.typeOf(result.results, 'array') + assert.lengthOf(result.results, 1) + assert.equal(result.page, 0) + assert.equal(result.totalPages, 1) + assert.equal(result.totalResults, 1) + }) + it('should query metadata and return real ddo', async () => { spy.on(ocean.utils.fetch, 'get', () => reponsify(getResults([new DDO()]))) From dd599c9f17dc317303a8f4f4317219abebdbc8e3 Mon Sep 17 00:00:00 2001 From: "Pablo F. Mescher" Date: Wed, 15 Jan 2020 11:42:52 +0100 Subject: [PATCH 2/6] Fixed broken tests Signed-off-by: Pablo F. Mescher --- src/aquarius/Aquarius.ts | 2 +- test/aquarius/Aquarius.test.ts | 21 +++++++++++---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/aquarius/Aquarius.ts b/src/aquarius/Aquarius.ts index 5cbbfc2..d6984f8 100644 --- a/src/aquarius/Aquarius.ts +++ b/src/aquarius/Aquarius.ts @@ -26,7 +26,7 @@ export interface SearchQuery { * Aquarius provides an off-chain database store for metadata about data assets. */ export class Aquarius { - private fetch: WebServiceConnector + public fetch: WebServiceConnector private logger: Logger private aquariusUri: string diff --git a/test/aquarius/Aquarius.test.ts b/test/aquarius/Aquarius.test.ts index e0465eb..7065de6 100644 --- a/test/aquarius/Aquarius.test.ts +++ b/test/aquarius/Aquarius.test.ts @@ -5,6 +5,7 @@ import { Aquarius, SearchQuery } from '../../src/aquarius/Aquarius' import { DDO } from '../../src/ddo/DDO' import DID from '../../src/ocean/DID' import config from '../config' +import { Logger } from '../../src/utils' use(spies) @@ -53,7 +54,7 @@ describe('Aquarius', () => { } as SearchQuery it('should query metadata', async () => { - spy.on(ocean.utils.fetch, 'post', () => reponsify(getResults([new DDO()]))) + spy.on(aquarius.fetch, 'post', () => reponsify(getResults([new DDO()]))) const result = await aquarius.queryMetadata(query) assert.typeOf(result.results, 'array') @@ -64,7 +65,7 @@ describe('Aquarius', () => { }) it('should query metadata and return real ddo', async () => { - spy.on(ocean.utils.fetch, 'post', () => reponsify(getResults([new DDO()]))) + spy.on(aquarius.fetch, 'post', () => reponsify(getResults([new DDO()]))) const result = await aquarius.queryMetadata(query) assert.typeOf(result.results, 'array') @@ -87,7 +88,7 @@ describe('Aquarius', () => { } as SearchQuery it('should query metadata by text', async () => { - spy.on(ocean.utils.fetch, 'get', () => reponsify(getResults([new DDO()]))) + spy.on(aquarius.fetch, 'get', () => reponsify(getResults([new DDO()]))) const result = await aquarius.queryMetadataByText(query) assert.typeOf(result.results, 'array') @@ -98,9 +99,9 @@ describe('Aquarius', () => { }) it('should query metadata by text with a new instance', async () => { - spy.on(ocean.utils.fetch, 'get', () => reponsify(getResults([new DDO()]))) - - const aquariusNew = new Aquarius(config.aquariusUri, ocean.utils, null) + const aquariusNew = new Aquarius(config.aquariusUri, new Logger()) + spy.on(aquariusNew.fetch, 'get', () => reponsify(getResults([new DDO()]))) + const result = await aquariusNew.queryMetadataByText(query) assert.typeOf(result.results, 'array') assert.lengthOf(result.results, 1) @@ -110,7 +111,7 @@ describe('Aquarius', () => { }) it('should query metadata and return real ddo', async () => { - spy.on(ocean.utils.fetch, 'get', () => reponsify(getResults([new DDO()]))) + spy.on(aquarius.fetch, 'get', () => reponsify(getResults([new DDO()]))) const result = await aquarius.queryMetadataByText(query) assert.typeOf(result.results, 'array') @@ -126,7 +127,7 @@ describe('Aquarius', () => { id: did.getId() }) - spy.on(ocean.utils.fetch, 'post', () => reponsify(ddo)) + spy.on(aquarius.fetch, 'post', () => reponsify(ddo)) const result: DDO = await aquarius.storeDDO(ddo) assert(result) @@ -141,8 +142,8 @@ describe('Aquarius', () => { id: did.getId() }) - spy.on(ocean.utils.fetch, 'post', () => reponsify(ddo)) - spy.on(ocean.utils.fetch, 'get', () => reponsify(ddo)) + spy.on(aquarius.fetch, 'post', () => reponsify(ddo)) + spy.on(aquarius.fetch, 'get', () => reponsify(ddo)) const storageResult: DDO = await aquarius.storeDDO(ddo) assert(storageResult) From 9cd18b62f5450b5e4637f22243f574608536e428 Mon Sep 17 00:00:00 2001 From: "Pablo F. Mescher" Date: Wed, 15 Jan 2020 11:46:22 +0100 Subject: [PATCH 3/6] Unbumped version Signed-off-by: Pablo F. Mescher --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f6ce6fc..a59d2e2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@oceanprotocol/squid", - "version": "1.0.2", + "version": "1.0.0", "description": "JavaScript client library for Ocean Protocol", "main": "./dist/node/squid.js", "typings": "./dist/node/squid.d.ts", From e0f533b469b29a99d6039b07a0ac737ad0031e9e Mon Sep 17 00:00:00 2001 From: Jorge Shirai Date: Wed, 15 Jan 2020 15:24:32 +0100 Subject: [PATCH 4/6] Require logger argument in Aquarius constructor. Improve Aquarius constructor comment/documentation. --- src/aquarius/Aquarius.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/aquarius/Aquarius.ts b/src/aquarius/Aquarius.ts index d6984f8..cd52a2f 100644 --- a/src/aquarius/Aquarius.ts +++ b/src/aquarius/Aquarius.ts @@ -22,7 +22,7 @@ export interface SearchQuery { } /** - * Provides a interface with Aquarius. + * Provides an interface with Aquarius. * Aquarius provides an off-chain database store for metadata about data assets. */ export class Aquarius { @@ -34,7 +34,12 @@ export class Aquarius { return this.aquariusUri } - constructor(aquariusUri: string, logger?: Logger) { + /** + * Instantiate Aquarius (independently of Ocean) for off-chain interaction. + * @param {String} aquariusUri + * @param {Logger} logger + */ + constructor(aquariusUri: string, logger: Logger) { this.fetch = new WebServiceConnector(logger) this.logger = logger this.aquariusUri = aquariusUri From df1c4fafd7150ec8b20a6bc94db7e197f9e8fe67 Mon Sep 17 00:00:00 2001 From: Jorge Shirai Date: Wed, 15 Jan 2020 15:58:44 +0100 Subject: [PATCH 5/6] Fix lint errors. --- src/ocean/Ocean.ts | 5 ++++- src/ocean/utils/OceanUtils.ts | 6 +++++- src/ocean/utils/SignatureUtils.ts | 6 +++--- src/ocean/utils/WebServiceConnector.ts | 6 +++--- src/squid.ts | 13 ++++++++++++- test/aquarius/Aquarius.test.ts | 2 +- 6 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/ocean/Ocean.ts b/src/ocean/Ocean.ts index e9a0a46..dd618f2 100644 --- a/src/ocean/Ocean.ts +++ b/src/ocean/Ocean.ts @@ -41,7 +41,10 @@ export class Ocean extends Instantiable { instance.keeper = await Keeper.getInstance(instanceConfig) instance.brizo = new Brizo(instanceConfig) - instance.aquarius = new Aquarius(instanceConfig.config.aquariusUri, instanceConfig.logger) + instance.aquarius = new Aquarius( + instanceConfig.config.aquariusUri, + instanceConfig.logger + ) instance.accounts = await OceanAccounts.getInstance(instanceConfig) instance.auth = await OceanAuth.getInstance(instanceConfig) diff --git a/src/ocean/utils/OceanUtils.ts b/src/ocean/utils/OceanUtils.ts index c285583..581398b 100644 --- a/src/ocean/utils/OceanUtils.ts +++ b/src/ocean/utils/OceanUtils.ts @@ -16,7 +16,11 @@ export class OceanUtils extends Instantiable { const instance = new OceanUtils() instance.setInstanceConfig(config) - instance.agreements = new ServiceAgreement(config.ocean, config.logger, config.web3) + instance.agreements = new ServiceAgreement( + config.ocean, + config.logger, + config.web3 + ) instance.signature = new SignatureUtils(config.web3, config.logger) instance.fetch = new WebServiceConnector(config.logger) diff --git a/src/ocean/utils/SignatureUtils.ts b/src/ocean/utils/SignatureUtils.ts index 3879f72..9da6072 100644 --- a/src/ocean/utils/SignatureUtils.ts +++ b/src/ocean/utils/SignatureUtils.ts @@ -3,11 +3,11 @@ import { Logger } from '../../utils' export class SignatureUtils { private web3: Web3 - private logger: Logger; - + private logger: Logger + constructor(web3: Web3, logger: Logger) { this.web3 = web3 - this.logger = logger; + this.logger = logger } public async signText( diff --git a/src/ocean/utils/WebServiceConnector.ts b/src/ocean/utils/WebServiceConnector.ts index a8a38e4..04c4f8f 100644 --- a/src/ocean/utils/WebServiceConnector.ts +++ b/src/ocean/utils/WebServiceConnector.ts @@ -1,17 +1,17 @@ import { BodyInit, RequestInit, Response } from 'node-fetch' import fs from 'fs' +import { Logger } from '../../utils' const fetch = require('node-fetch') import save = require('save-file') -import { Logger } from '../../utils' /** * Provides a common interface to web services. */ export class WebServiceConnector { - public logger: Logger; + public logger: Logger constructor(logger: Logger) { - this.logger = logger; + this.logger = logger } public post(url: string, payload: BodyInit): Promise { diff --git a/src/squid.ts b/src/squid.ts index 204fa5d..a665558 100644 --- a/src/squid.ts +++ b/src/squid.ts @@ -25,4 +25,15 @@ export { export { AgreementTemplate } from './keeper/contracts/templates' export { Condition, ConditionState } from './keeper/contracts/conditions' -export { Ocean, Account, Config, DID, Logger, Keeper, Aquarius, conditions, templates, utils } +export { + Ocean, + Account, + Config, + DID, + Logger, + Keeper, + Aquarius, + conditions, + templates, + utils +} diff --git a/test/aquarius/Aquarius.test.ts b/test/aquarius/Aquarius.test.ts index 7065de6..9dfd587 100644 --- a/test/aquarius/Aquarius.test.ts +++ b/test/aquarius/Aquarius.test.ts @@ -101,7 +101,7 @@ describe('Aquarius', () => { it('should query metadata by text with a new instance', async () => { const aquariusNew = new Aquarius(config.aquariusUri, new Logger()) spy.on(aquariusNew.fetch, 'get', () => reponsify(getResults([new DDO()]))) - + const result = await aquariusNew.queryMetadataByText(query) assert.typeOf(result.results, 'array') assert.lengthOf(result.results, 1) From 791d22cb9204419ef642142baf16a86a6361322d Mon Sep 17 00:00:00 2001 From: Jorge Shirai Date: Mon, 20 Jan 2020 11:38:20 +0100 Subject: [PATCH 6/6] Add example Aquarius instantiation doc in README. Use LoggerInstance alias in Aquarius.test.ts. --- README.md | 13 +++++++++++++ test/aquarius/Aquarius.test.ts | 4 ++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a038cd9..a035396 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,19 @@ const ocean: Ocean = await Ocean.getInstance({ For an overview of endpoint configurations making up various Ocean networks, please refer to [`.env.local.example`](https://github.com/oceanprotocol/commons/blob/master/client/.env.local.example) from commons. +Optionally, you can initialize an Aquarius connection without relying on the rest of Ocean to be loaded. This is useful for outputting asset metadata stored in Aquarius without the need to configure Web3 and all other Ocean Protocol network connections. + +```js +import { Ocean, Aquarius, Logger } from 'squid' + +const aquarius = new Aquarius('http://localhost:5000', Logger) +const asset = aquarius.retrieveDDO('did:op:e6fda48e8d814d5d9655645aac3c046cc87528dbc1a9449799e579d7b83d1360') + +const ocean = await Ocean.getInstance({ ... }) +// Aquarius will still be available under ocean.aquarius, just later +const asset = ocean.aquarius.retrieveDDO('did:op:e6fda48e8d814d5d9655645aac3c046cc87528dbc1a9449799e579d7b83d1360') +``` + ### Examples You can see how `squid-js` is used on: diff --git a/test/aquarius/Aquarius.test.ts b/test/aquarius/Aquarius.test.ts index 9dfd587..0927779 100644 --- a/test/aquarius/Aquarius.test.ts +++ b/test/aquarius/Aquarius.test.ts @@ -5,7 +5,7 @@ import { Aquarius, SearchQuery } from '../../src/aquarius/Aquarius' import { DDO } from '../../src/ddo/DDO' import DID from '../../src/ocean/DID' import config from '../config' -import { Logger } from '../../src/utils' +import { LoggerInstance } from '../../src/utils' use(spies) @@ -99,7 +99,7 @@ describe('Aquarius', () => { }) it('should query metadata by text with a new instance', async () => { - const aquariusNew = new Aquarius(config.aquariusUri, new Logger()) + const aquariusNew = new Aquarius(config.aquariusUri, LoggerInstance) spy.on(aquariusNew.fetch, 'get', () => reponsify(getResults([new DDO()]))) const result = await aquariusNew.queryMetadataByText(query)