diff --git a/src/client.ts b/src/client.ts index 852045e9..6d7a824e 100644 --- a/src/client.ts +++ b/src/client.ts @@ -1,13 +1,10 @@ import { EdcConnectorClientContext } from "./context"; -import { - ManagementController, - ObservabilityController, - PublicController, -} from "./controllers"; +import { ObservabilityController, PublicController } from "./controllers"; import { Addresses } from "./entities"; import { Inner } from "./inner"; import { version } from "../package.json"; +import { ManagementController } from "./facades/management"; export class EdcConnectorClient { readonly management: ManagementController; diff --git a/src/controllers/index.ts b/src/controllers/index.ts index bdace447..cd395a3a 100644 --- a/src/controllers/index.ts +++ b/src/controllers/index.ts @@ -1,3 +1,3 @@ -export * from "./management-controller"; +export * from "./management-controllers"; export * from "./observability-controller"; export * from "./public-controller"; diff --git a/src/controllers/management-controller.ts b/src/controllers/management-controller.ts deleted file mode 100644 index 34ce1813..00000000 --- a/src/controllers/management-controller.ts +++ /dev/null @@ -1,459 +0,0 @@ -import { EdcConnectorClientContext } from "../context"; -import { - expand, - expandArray, - AssetResponse, - AssetInput, - Catalog, - CatalogRequest, - ContractAgreement, - ContractDefinition, - ContractDefinitionInput, - ContractNegotiation, - ContractNegotiationRequest, - ContractNegotiationState, - Dataplane, - DataplaneInput, - IdResponse, - PolicyDefinition, - PolicyDefinitionInput, - QuerySpec, - TransferProcess, - TransferProcessInput, - EDC_CONTEXT, -} from "../entities"; -import { Inner } from "../inner"; - -export class ManagementController { - #inner: Inner; - protocol: String = "dataspace-protocol-http"; - defaultContextValues = { - edc: EDC_CONTEXT, - }; - - constructor(inner: Inner) { - this.#inner = inner; - } - - async registerDataplane( - context: EdcConnectorClientContext, - input: DataplaneInput, - ): Promise { - return this.#inner.request(context.management, { - path: "/v2/dataplanes", - method: "POST", - apiToken: context.apiToken, - body: { - ...input, - "@context": this.defaultContextValues, - }, - }); - } - - async listDataplanes( - context: EdcConnectorClientContext, - ): Promise { - return this.#inner - .request(context.management, { - path: "/v2/dataplanes", - method: "GET", - apiToken: context.apiToken, - }) - .then((body) => expandArray(body, () => new Dataplane())); - } - - async createAsset( - context: EdcConnectorClientContext, - input: AssetInput, - ): Promise { - return this.#inner - .request(context.management, { - path: "/v3/assets", - method: "POST", - apiToken: context.apiToken, - body: { - ...input, - "@context": this.defaultContextValues, - }, - }) - .then((body) => expand(body, () => new IdResponse())); - } - - async deleteAsset( - context: EdcConnectorClientContext, - assetId: string, - ): Promise { - return this.#inner.request(context.management, { - path: `/v3/assets/${assetId}`, - method: "DELETE", - apiToken: context.apiToken, - }); - } - - async getAsset( - context: EdcConnectorClientContext, - assetId: string, - ): Promise { - return this.#inner.request(context.management, { - path: `/v3/assets/${assetId}`, - method: "GET", - apiToken: context.apiToken, - }); - } - - async queryAllAssets( - context: EdcConnectorClientContext, - query: QuerySpec = {}, - ): Promise { - return this.#inner.request(context.management, { - path: "/v3/assets/request", - method: "POST", - apiToken: context.apiToken, - body: - Object.keys(query).length === 0 - ? null - : { - ...query, - "@context": this.defaultContextValues, - }, - }); - } - - async updateAsset( - context: EdcConnectorClientContext, - input: AssetInput, - ): Promise { - return this.#inner.request(context.management, { - path: "/v3/assets", - method: "PUT", - apiToken: context.apiToken, - body: { - ...input, - "@context": this.defaultContextValues, - }, - }); - } - - async createPolicy( - context: EdcConnectorClientContext, - input: PolicyDefinitionInput, - ): Promise { - return this.#inner - .request(context.management, { - path: "/v2/policydefinitions", - method: "POST", - apiToken: context.apiToken, - body: { - ...input, - "@context": this.defaultContextValues, - }, - }) - .then((body) => expand(body, () => new IdResponse())); - } - - async deletePolicy( - context: EdcConnectorClientContext, - policyId: string, - ): Promise { - return this.#inner.request(context.management, { - path: `/v2/policydefinitions/${policyId}`, - method: "DELETE", - apiToken: context.apiToken, - }); - } - - async getPolicy( - context: EdcConnectorClientContext, - policyId: string, - ): Promise { - return this.#inner - .request(context.management, { - path: `/v2/policydefinitions/${policyId}`, - method: "GET", - apiToken: context.apiToken, - }) - .then((body) => expand(body, () => new PolicyDefinition())); - } - - async queryAllPolicies( - context: EdcConnectorClientContext, - query: QuerySpec = {}, - ): Promise { - return this.#inner - .request(context.management, { - path: "/v2/policydefinitions/request", - method: "POST", - apiToken: context.apiToken, - body: - Object.keys(query).length === 0 - ? null - : { - ...query, - "@context": this.defaultContextValues, - }, - }) - .then((body) => expandArray(body, () => new PolicyDefinition())); - } - - async createContractDefinition( - context: EdcConnectorClientContext, - input: ContractDefinitionInput, - ): Promise { - return this.#inner - .request(context.management, { - path: "/v2/contractdefinitions", - method: "POST", - apiToken: context.apiToken, - body: { - ...input, - "@context": this.defaultContextValues, - }, - }) - .then((body) => expand(body, () => new IdResponse())); - } - - async deleteContractDefinition( - context: EdcConnectorClientContext, - contractDefinitionId: string, - ): Promise { - return this.#inner.request(context.management, { - path: `/v2/contractdefinitions/${contractDefinitionId}`, - method: "DELETE", - apiToken: context.apiToken, - }); - } - - async getContractDefinition( - context: EdcConnectorClientContext, - contractDefinitionId: string, - ): Promise { - return this.#inner.request(context.management, { - path: `/v2/contractdefinitions/${contractDefinitionId}`, - method: "GET", - apiToken: context.apiToken, - }); - } - - async queryAllContractDefinitions( - context: EdcConnectorClientContext, - query: QuerySpec = {}, - ): Promise { - return this.#inner - .request(context.management, { - path: "/v2/contractdefinitions/request", - method: "POST", - apiToken: context.apiToken, - body: - Object.keys(query).length === 0 - ? null - : { - ...query, - "@context": this.defaultContextValues, - }, - }) - .then((body) => expandArray(body, () => new ContractDefinition())); - } - - async updateContractDefinition( - context: EdcConnectorClientContext, - input: ContractDefinitionInput, - ): Promise { - return this.#inner.request(context.management, { - path: "/v2/contractdefinitions", - method: "PUT", - apiToken: context.apiToken, - body: { - ...input, - "@context": this.defaultContextValues, - }, - }); - } - - async requestCatalog( - context: EdcConnectorClientContext, - input: CatalogRequest, - ): Promise { - return this.#inner - .request(context.management, { - path: "/v2/catalog/request", - method: "POST", - apiToken: context.apiToken, - body: { - "@context": this.defaultContextValues, - protocol: this.protocol, - ...input, - }, - }) - .then((body) => expand(body, () => new Catalog())); - } - - async initiateContractNegotiation( - context: EdcConnectorClientContext, - input: ContractNegotiationRequest, - ): Promise { - return this.#inner - .request(context.management, { - path: "/v2/contractnegotiations", - method: "POST", - apiToken: context.apiToken, - body: { - protocol: this.protocol, - "@context": this.defaultContextValues, - ...input, - }, - }) - .then((body) => expand(body, () => new IdResponse())); - } - - async queryNegotiations( - context: EdcConnectorClientContext, - query: QuerySpec = {}, - ): Promise { - return this.#inner - .request(context.management, { - path: "/v2/contractnegotiations/request", - method: "POST", - apiToken: context.apiToken, - body: - Object.keys(query).length === 0 - ? null - : { - ...query, - "@context": this.defaultContextValues, - }, - }) - .then((body) => expandArray(body, () => new ContractNegotiation())); - } - - async getNegotiation( - context: EdcConnectorClientContext, - negotiationId: string, - ): Promise { - return this.#inner - .request(context.management, { - path: `/v2/contractnegotiations/${negotiationId}`, - method: "GET", - apiToken: context.apiToken, - }) - .then((body) => expand(body, () => new ContractNegotiation())); - } - - async getNegotiationState( - context: EdcConnectorClientContext, - negotiationId: string, - ): Promise { - return this.#inner - .request(context.management, { - path: `/v2/contractnegotiations/${negotiationId}/state`, - method: "GET", - apiToken: context.apiToken, - }) - .then((body) => expand(body, () => new ContractNegotiationState())); - } - - async cancelNegotiation( - context: EdcConnectorClientContext, - negotiationId: string, - ): Promise { - return this.#inner.request(context.management, { - path: `/v2/contractnegotiations/${negotiationId}/cancel`, - method: "POST", - apiToken: context.apiToken, - }); - } - - async declineNegotiation( - context: EdcConnectorClientContext, - negotiationId: string, - ): Promise { - return this.#inner.request(context.management, { - path: `/v2/contractnegotiations/${negotiationId}/decline`, - method: "POST", - apiToken: context.apiToken, - }); - } - - async getAgreementForNegotiation( - context: EdcConnectorClientContext, - negotiationId: string, - ): Promise { - return this.#inner - .request(context.management, { - path: `/v2/contractnegotiations/${negotiationId}/agreement`, - method: "GET", - apiToken: context.apiToken, - }) - .then((body) => expand(body, () => new ContractAgreement())); - } - - async queryAllAgreements( - context: EdcConnectorClientContext, - query: QuerySpec = {}, - ): Promise { - return this.#inner - .request(context.management, { - path: "/v2/contractagreements/request", - method: "POST", - apiToken: context.apiToken, - body: - Object.keys(query).length === 0 - ? null - : { - ...query, - "@context": this.defaultContextValues, - }, - }) - .then((body) => expandArray(body, () => new ContractAgreement())); - } - - async getAgreement( - context: EdcConnectorClientContext, - agreementId: string, - ): Promise { - return this.#inner - .request(context.management, { - path: `/v2/contractagreements/${agreementId}`, - method: "GET", - apiToken: context.apiToken, - }) - .then((body) => expand(body, () => new ContractAgreement())); - } - - async initiateTransfer( - context: EdcConnectorClientContext, - input: TransferProcessInput, - ): Promise { - return this.#inner - .request(context.management, { - path: "/v2/transferprocesses", - method: "POST", - apiToken: context.apiToken, - body: { - "@context": this.defaultContextValues, - protocol: this.protocol, - ...input, - }, - }) - .then((body) => expand(body, () => new IdResponse())); - } - - async queryAllTransferProcesses( - context: EdcConnectorClientContext, - query: QuerySpec = {}, - ): Promise { - return this.#inner - .request(context.management, { - path: "/v2/transferprocesses/request", - method: "POST", - apiToken: context.apiToken, - body: - Object.keys(query).length === 0 - ? null - : { - ...query, - "@context": this.defaultContextValues, - }, - }) - .then((body) => expandArray(body, () => new TransferProcess())); - } -} diff --git a/src/controllers/management-controllers/asset-controller.ts b/src/controllers/management-controllers/asset-controller.ts new file mode 100644 index 00000000..b3fb815a --- /dev/null +++ b/src/controllers/management-controllers/asset-controller.ts @@ -0,0 +1,93 @@ +import { EdcConnectorClientContext } from "../../context"; +import { + expand, + AssetResponse, + AssetInput, + IdResponse, + QuerySpec, + EDC_CONTEXT, +} from "../../entities"; +import { Inner } from "../../inner"; + +export class AssetController { + #inner: Inner; + defaultContextValues = { + edc: EDC_CONTEXT, + }; + + constructor(inner: Inner) { + this.#inner = inner; + } + + async create( + context: EdcConnectorClientContext, + input: AssetInput, + ): Promise { + return this.#inner + .request(context.management, { + path: "/v3/assets", + method: "POST", + apiToken: context.apiToken, + body: { + ...input, + "@context": this.defaultContextValues, + }, + }) + .then((body) => expand(body, () => new IdResponse())); + } + + async delete( + context: EdcConnectorClientContext, + assetId: string, + ): Promise { + return this.#inner.request(context.management, { + path: `/v3/assets/${assetId}`, + method: "DELETE", + apiToken: context.apiToken, + }); + } + + async get( + context: EdcConnectorClientContext, + assetId: string, + ): Promise { + return this.#inner.request(context.management, { + path: `/v3/assets/${assetId}`, + method: "GET", + apiToken: context.apiToken, + }); + } + + async update( + context: EdcConnectorClientContext, + input: AssetInput, + ): Promise { + return this.#inner.request(context.management, { + path: "/v3/assets", + method: "PUT", + apiToken: context.apiToken, + body: { + ...input, + "@context": this.defaultContextValues, + }, + }); + } + + async queryAll( + context: EdcConnectorClientContext, + query: QuerySpec = {}, + ): Promise { + return this.#inner.request(context.management, { + path: "/v3/assets/request", + method: "POST", + apiToken: context.apiToken, + body: + Object.keys(query).length === 0 + ? null + : { + ...query, + "@context": this.defaultContextValues, + }, + }); + } +} diff --git a/src/controllers/management-controllers/catalog-controller.ts b/src/controllers/management-controllers/catalog-controller.ts new file mode 100644 index 00000000..cf6d3177 --- /dev/null +++ b/src/controllers/management-controllers/catalog-controller.ts @@ -0,0 +1,33 @@ +import { EdcConnectorClientContext } from "../../context"; +import { EDC_CONTEXT, CatalogRequest, Catalog, expand } from "../../entities"; +import { Inner } from "../../inner"; + +export class CatalogController { + #inner: Inner; + protocol: String = "dataspace-protocol-http"; + defaultContextValues = { + edc: EDC_CONTEXT, + }; + + constructor(inner: Inner) { + this.#inner = inner; + } + + async queryAll( + context: EdcConnectorClientContext, + input: CatalogRequest, + ): Promise { + return this.#inner + .request(context.management, { + path: "/v2/catalog/request", + method: "POST", + apiToken: context.apiToken, + body: { + "@context": this.defaultContextValues, + protocol: this.protocol, + ...input, + }, + }) + .then((body) => expand(body, () => new Catalog())); + } +} diff --git a/src/controllers/management-controllers/contract-agreement-controller.ts b/src/controllers/management-controllers/contract-agreement-controller.ts new file mode 100644 index 00000000..01415603 --- /dev/null +++ b/src/controllers/management-controllers/contract-agreement-controller.ts @@ -0,0 +1,53 @@ +import { EdcConnectorClientContext } from "../../context"; +import { + expand, + expandArray, + ContractAgreement, + QuerySpec, + EDC_CONTEXT, +} from "../../entities"; +import { Inner } from "../../inner"; + +export class ContractAgreementController { + #inner: Inner; + defaultContextValues = { + edc: EDC_CONTEXT, + }; + + constructor(inner: Inner) { + this.#inner = inner; + } + + async queryAll( + context: EdcConnectorClientContext, + query: QuerySpec = {}, + ): Promise { + return this.#inner + .request(context.management, { + path: "/v2/contractagreements/request", + method: "POST", + apiToken: context.apiToken, + body: + Object.keys(query).length === 0 + ? null + : { + ...query, + "@context": this.defaultContextValues, + }, + }) + .then((body) => expandArray(body, () => new ContractAgreement())); + } + + async get( + context: EdcConnectorClientContext, + agreementId: string, + ): Promise { + return this.#inner + .request(context.management, { + path: `/v2/contractagreements/${agreementId}`, + method: "GET", + apiToken: context.apiToken, + }) + .then((body) => expand(body, () => new ContractAgreement())); + } +} diff --git a/src/controllers/management-controllers/contract-defintion-controller.ts b/src/controllers/management-controllers/contract-defintion-controller.ts new file mode 100644 index 00000000..3cc39d44 --- /dev/null +++ b/src/controllers/management-controllers/contract-defintion-controller.ts @@ -0,0 +1,96 @@ +import { EdcConnectorClientContext } from "../../context"; +import { + expand, + expandArray, + ContractDefinition, + ContractDefinitionInput, + IdResponse, + QuerySpec, + EDC_CONTEXT, +} from "../../entities"; +import { Inner } from "../../inner"; + +export class ContractDefinitionController { + #inner: Inner; + defaultContextValues = { + edc: EDC_CONTEXT, + }; + + constructor(inner: Inner) { + this.#inner = inner; + } + + async create( + context: EdcConnectorClientContext, + input: ContractDefinitionInput, + ): Promise { + return this.#inner + .request(context.management, { + path: "/v2/contractdefinitions", + method: "POST", + apiToken: context.apiToken, + body: { + ...input, + "@context": this.defaultContextValues, + }, + }) + .then((body) => expand(body, () => new IdResponse())); + } + + async delete( + context: EdcConnectorClientContext, + contractDefinitionId: string, + ): Promise { + return this.#inner.request(context.management, { + path: `/v2/contractdefinitions/${contractDefinitionId}`, + method: "DELETE", + apiToken: context.apiToken, + }); + } + + async get( + context: EdcConnectorClientContext, + contractDefinitionId: string, + ): Promise { + return this.#inner.request(context.management, { + path: `/v2/contractdefinitions/${contractDefinitionId}`, + method: "GET", + apiToken: context.apiToken, + }); + } + + async queryAll( + context: EdcConnectorClientContext, + query: QuerySpec = {}, + ): Promise { + return this.#inner + .request(context.management, { + path: "/v2/contractdefinitions/request", + method: "POST", + apiToken: context.apiToken, + body: + Object.keys(query).length === 0 + ? null + : { + ...query, + "@context": this.defaultContextValues, + }, + }) + .then((body) => expandArray(body, () => new ContractDefinition())); + } + + async update( + context: EdcConnectorClientContext, + input: ContractDefinitionInput, + ): Promise { + return this.#inner.request(context.management, { + path: "/v2/contractdefinitions", + method: "PUT", + apiToken: context.apiToken, + body: { + ...input, + "@context": this.defaultContextValues, + }, + }); + } +} diff --git a/src/controllers/management-controllers/contract-negotiation-controller.ts b/src/controllers/management-controllers/contract-negotiation-controller.ts new file mode 100644 index 00000000..d3dd1368 --- /dev/null +++ b/src/controllers/management-controllers/contract-negotiation-controller.ts @@ -0,0 +1,124 @@ +import { EdcConnectorClientContext } from "../../context"; +import { + expand, + expandArray, + ContractAgreement, + ContractNegotiation, + ContractNegotiationRequest, + ContractNegotiationState, + IdResponse, + QuerySpec, + EDC_CONTEXT, +} from "../../entities"; +import { Inner } from "../../inner"; + +export class ContractNegotiationController { + #inner: Inner; + protocol: String = "dataspace-protocol-http"; + defaultContextValues = { + edc: EDC_CONTEXT, + }; + + constructor(inner: Inner) { + this.#inner = inner; + } + + async initiate( + context: EdcConnectorClientContext, + input: ContractNegotiationRequest, + ): Promise { + return this.#inner + .request(context.management, { + path: "/v2/contractnegotiations", + method: "POST", + apiToken: context.apiToken, + body: { + protocol: this.protocol, + "@context": this.defaultContextValues, + ...input, + }, + }) + .then((body) => expand(body, () => new IdResponse())); + } + + async queryAll( + context: EdcConnectorClientContext, + query: QuerySpec = {}, + ): Promise { + return this.#inner + .request(context.management, { + path: "/v2/contractnegotiations/request", + method: "POST", + apiToken: context.apiToken, + body: + Object.keys(query).length === 0 + ? null + : { + ...query, + "@context": this.defaultContextValues, + }, + }) + .then((body) => expandArray(body, () => new ContractNegotiation())); + } + + async get( + context: EdcConnectorClientContext, + negotiationId: string, + ): Promise { + return this.#inner + .request(context.management, { + path: `/v2/contractnegotiations/${negotiationId}`, + method: "GET", + apiToken: context.apiToken, + }) + .then((body) => expand(body, () => new ContractNegotiation())); + } + + async getState( + context: EdcConnectorClientContext, + negotiationId: string, + ): Promise { + return this.#inner + .request(context.management, { + path: `/v2/contractnegotiations/${negotiationId}/state`, + method: "GET", + apiToken: context.apiToken, + }) + .then((body) => expand(body, () => new ContractNegotiationState())); + } + + async cancel( + context: EdcConnectorClientContext, + negotiationId: string, + ): Promise { + return this.#inner.request(context.management, { + path: `/v2/contractnegotiations/${negotiationId}/cancel`, + method: "POST", + apiToken: context.apiToken, + }); + } + + async decline( + context: EdcConnectorClientContext, + negotiationId: string, + ): Promise { + return this.#inner.request(context.management, { + path: `/v2/contractnegotiations/${negotiationId}/decline`, + method: "POST", + apiToken: context.apiToken, + }); + } + + async getAgreement( + context: EdcConnectorClientContext, + negotiationId: string, + ): Promise { + return this.#inner + .request(context.management, { + path: `/v2/contractnegotiations/${negotiationId}/agreement`, + method: "GET", + apiToken: context.apiToken, + }) + .then((body) => expand(body, () => new ContractAgreement())); + } +} diff --git a/src/controllers/management-controllers/dataplane-controller.ts b/src/controllers/management-controllers/dataplane-controller.ts new file mode 100644 index 00000000..b435a0e9 --- /dev/null +++ b/src/controllers/management-controllers/dataplane-controller.ts @@ -0,0 +1,44 @@ +import { EdcConnectorClientContext } from "../../context"; +import { + expandArray, + Dataplane, + DataplaneInput, + EDC_CONTEXT, +} from "../../entities"; +import { Inner } from "../../inner"; + +export class DataplaneController { + #inner: Inner; + defaultContextValues = { + edc: EDC_CONTEXT, + }; + + constructor(inner: Inner) { + this.#inner = inner; + } + + async register( + context: EdcConnectorClientContext, + input: DataplaneInput, + ): Promise { + return this.#inner.request(context.management, { + path: "/v2/dataplanes", + method: "POST", + apiToken: context.apiToken, + body: { + ...input, + "@context": this.defaultContextValues, + }, + }); + } + + async list(context: EdcConnectorClientContext): Promise { + return this.#inner + .request(context.management, { + path: "/v2/dataplanes", + method: "GET", + apiToken: context.apiToken, + }) + .then((body) => expandArray(body, () => new Dataplane())); + } +} diff --git a/src/controllers/management-controllers/index.ts b/src/controllers/management-controllers/index.ts new file mode 100644 index 00000000..de33c534 --- /dev/null +++ b/src/controllers/management-controllers/index.ts @@ -0,0 +1,8 @@ +export * from "./asset-controller"; +export * from "./catalog-controller"; +export * from "./contract-agreement-controller"; +export * from "./contract-defintion-controller"; +export * from "./contract-negotiation-controller"; +export * from "./policy-defintion-controller"; +export * from "./transfer-process-controller"; +export * from "./dataplane-controller"; diff --git a/src/controllers/management-controllers/policy-defintion-controller.ts b/src/controllers/management-controllers/policy-defintion-controller.ts new file mode 100644 index 00000000..6117b006 --- /dev/null +++ b/src/controllers/management-controllers/policy-defintion-controller.ts @@ -0,0 +1,83 @@ +import { EdcConnectorClientContext } from "../../context"; +import { + expand, + expandArray, + IdResponse, + PolicyDefinition, + PolicyDefinitionInput, + QuerySpec, + EDC_CONTEXT, +} from "../../entities"; +import { Inner } from "../../inner"; + +export class PolicyDefinitionController { + #inner: Inner; + defaultContextValues = { + edc: EDC_CONTEXT, + }; + + constructor(inner: Inner) { + this.#inner = inner; + } + + async create( + context: EdcConnectorClientContext, + input: PolicyDefinitionInput, + ): Promise { + return this.#inner + .request(context.management, { + path: "/v2/policydefinitions", + method: "POST", + apiToken: context.apiToken, + body: { + ...input, + "@context": this.defaultContextValues, + }, + }) + .then((body) => expand(body, () => new IdResponse())); + } + + async delete( + context: EdcConnectorClientContext, + policyId: string, + ): Promise { + return this.#inner.request(context.management, { + path: `/v2/policydefinitions/${policyId}`, + method: "DELETE", + apiToken: context.apiToken, + }); + } + + async get( + context: EdcConnectorClientContext, + policyId: string, + ): Promise { + return this.#inner + .request(context.management, { + path: `/v2/policydefinitions/${policyId}`, + method: "GET", + apiToken: context.apiToken, + }) + .then((body) => expand(body, () => new PolicyDefinition())); + } + + async queryAll( + context: EdcConnectorClientContext, + query: QuerySpec = {}, + ): Promise { + return this.#inner + .request(context.management, { + path: "/v2/policydefinitions/request", + method: "POST", + apiToken: context.apiToken, + body: + Object.keys(query).length === 0 + ? null + : { + ...query, + "@context": this.defaultContextValues, + }, + }) + .then((body) => expandArray(body, () => new PolicyDefinition())); + } +} diff --git a/src/controllers/management-controllers/transfer-process-controller.ts b/src/controllers/management-controllers/transfer-process-controller.ts new file mode 100644 index 00000000..8706ec6d --- /dev/null +++ b/src/controllers/management-controllers/transfer-process-controller.ts @@ -0,0 +1,61 @@ +import { EdcConnectorClientContext } from "../../context"; +import { + expand, + expandArray, + IdResponse, + QuerySpec, + TransferProcess, + TransferProcessInput, + EDC_CONTEXT, +} from "../../entities"; +import { Inner } from "../../inner"; + +export class TransferProcessController { + #inner: Inner; + protocol: String = "dataspace-protocol-http"; + defaultContextValues = { + edc: EDC_CONTEXT, + }; + + constructor(inner: Inner) { + this.#inner = inner; + } + + async initiate( + context: EdcConnectorClientContext, + input: TransferProcessInput, + ): Promise { + return this.#inner + .request(context.management, { + path: "/v2/transferprocesses", + method: "POST", + apiToken: context.apiToken, + body: { + "@context": this.defaultContextValues, + protocol: this.protocol, + ...input, + }, + }) + .then((body) => expand(body, () => new IdResponse())); + } + + async queryAll( + context: EdcConnectorClientContext, + query: QuerySpec = {}, + ): Promise { + return this.#inner + .request(context.management, { + path: "/v2/transferprocesses/request", + method: "POST", + apiToken: context.apiToken, + body: + Object.keys(query).length === 0 + ? null + : { + ...query, + "@context": this.defaultContextValues, + }, + }) + .then((body) => expandArray(body, () => new TransferProcess())); + } +} diff --git a/src/facades/management.ts b/src/facades/management.ts new file mode 100644 index 00000000..8d0feebe --- /dev/null +++ b/src/facades/management.ts @@ -0,0 +1,44 @@ +import { Inner } from "../inner"; +import { + AssetController, + CatalogController, + ContractAgreementController, + ContractDefinitionController, + ContractNegotiationController, + DataplaneController, + PolicyDefinitionController, + TransferProcessController, +} from "../controllers/management-controllers"; + +export class ManagementController { + #inner: Inner; + + constructor(inner: Inner) { + this.#inner = inner; + } + + get assets() { + return new AssetController(this.#inner); + } + get catalog() { + return new CatalogController(this.#inner); + } + get contractAgreements() { + return new ContractAgreementController(this.#inner); + } + get contractDefinitions() { + return new ContractDefinitionController(this.#inner); + } + get contractNegotiations() { + return new ContractNegotiationController(this.#inner); + } + get dataplanes() { + return new DataplaneController(this.#inner); + } + get policyDefinitions() { + return new PolicyDefinitionController(this.#inner); + } + get transferProcesses() { + return new TransferProcessController(this.#inner); + } +} diff --git a/tests/controllers/management-tests/assets.test.ts b/tests/controllers/management-tests/assets.test.ts new file mode 100644 index 00000000..5cfdf2da --- /dev/null +++ b/tests/controllers/management-tests/assets.test.ts @@ -0,0 +1,316 @@ +import * as crypto from "node:crypto"; +import { + Addresses, + AssetInput, + EDC_NAMESPACE, + EdcConnectorClient, +} from "../../../src"; +import { + EdcConnectorClientError, + EdcConnectorClientErrorType, +} from "../../../src/error"; + +describe("AssetController", () => { + const apiToken = "123456"; + const consumer: Addresses = { + default: "http://localhost:19191/api", + management: "http://localhost:19193/management", + protocol: "http://consumer-connector:9194/protocol", + public: "http://localhost:19291/public", + control: "http://localhost:19292/control", + }; + + const edcClient = new EdcConnectorClient(); + + describe("edcClient.management.assets.create", () => { + it("succesfully creates an asset", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + const assetInput: AssetInput = { + "@id": crypto.randomUUID(), + properties: { + name: "product description", + contenttype: "application/json", + }, + dataAddress: { + type: "HttpData", + properties: { + baseUrl: "https://jsonplaceholder.typicode.com/users", + }, + }, + }; + + // when + const idResponse = await edcClient.management.assets.create( + context, + assetInput, + ); + + // then + expect(idResponse).toHaveProperty("createdAt"); + expect(idResponse).toHaveProperty("id"); + }); + + it("fails creating two assets with the same id", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + const assetInput: AssetInput = { + "@id": crypto.randomUUID(), + properties: { + name: "product description", + contenttype: "application/json", + }, + dataAddress: { + type: "HttpData", + properties: { + name: "Test asset", + baseUrl: "https://jsonplaceholder.typicode.com/users", + }, + }, + }; + + // when + await edcClient.management.assets.create(context, assetInput); + const maybeCreateResult = edcClient.management.assets.create( + context, + assetInput, + ); + + // then + await expect(maybeCreateResult).rejects.toThrowError( + "duplicated resource", + ); + + maybeCreateResult.catch((error) => { + expect(error).toBeInstanceOf(EdcConnectorClientError); + expect(error as EdcConnectorClientError).toHaveProperty( + "type", + EdcConnectorClientErrorType.Duplicate, + ); + }); + }); + }); + + describe("edcClient.management.delete", () => { + it("deletes a target asset", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + const assetInput: AssetInput = { + "@id": crypto.randomUUID(), + properties: { + name: "product description", + contenttype: "application/json", + }, + dataAddress: { + type: "HttpData", + properties: { + name: "Test asset", + baseUrl: "https://jsonplaceholder.typicode.com/users", + }, + }, + }; + await edcClient.management.assets.create(context, assetInput); + + // when + const asset = await edcClient.management.assets.delete( + context, + assetInput["@id"] as string, + ); + + // then + expect(asset).toBeUndefined(); + }); + + it("fails to delete an not existant asset", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + + // when + const maybeAsset = edcClient.management.assets.delete( + context, + crypto.randomUUID(), + ); + + // then + await expect(maybeAsset).rejects.toThrowError("resource not found"); + + maybeAsset.catch((error) => { + expect(error).toBeInstanceOf(EdcConnectorClientError); + expect(error as EdcConnectorClientError).toHaveProperty( + "type", + EdcConnectorClientErrorType.NotFound, + ); + }); + }); + + it.todo("fails to delete an asset that is part of an agreed contract"); + }); + + describe("edcClient.management.assets.get", () => { + it("returns a target asset", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + const assetInput: AssetInput = { + "@id": crypto.randomUUID(), + properties: { + name: "product description", + contenttype: "application/json", + }, + dataAddress: { + type: "HttpData", + properties: { + name: "Test asset", + baseUrl: "https://jsonplaceholder.typicode.com/users", + }, + }, + }; + await edcClient.management.assets.create(context, assetInput); + + // when + const asset = await edcClient.management.assets.get( + context, + assetInput["@id"] as string, + ); + + // then + expect(asset).toHaveProperty("@context"); + expect(asset).toHaveProperty("@id", assetInput["@id"]); + }); + + it("fails to fetch an not existant asset", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + + // when + const maybeAsset = edcClient.management.assets.get( + context, + crypto.randomUUID(), + ); + + // then + await expect(maybeAsset).rejects.toThrowError("resource not found"); + + maybeAsset.catch((error) => { + expect(error).toBeInstanceOf(EdcConnectorClientError); + expect(error as EdcConnectorClientError).toHaveProperty( + "type", + EdcConnectorClientErrorType.NotFound, + ); + }); + }); + }); + + describe("edcClient.management.assets.queryAll", () => { + it("succesfully retuns a list of assets", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + const assetInput: AssetInput = { + "@id": crypto.randomUUID(), + properties: { + name: "product description", + contenttype: "application/json", + }, + dataAddress: { + name: "Test asset", + baseUrl: "https://jsonplaceholder.typicode.com/users", + type: "HttpData", + }, + }; + await edcClient.management.assets.create(context, assetInput); + + // when + const assets = await edcClient.management.assets.queryAll(context); + + // then + expect(assets.length).toBeGreaterThan(0); + expect( + assets.find((asset) => asset?.["@id"] === assetInput["@id"]), + ).toBeTruthy(); + }); + }); + + describe("edcClient.management.assets.update", () => { + it("updates a target asset", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + const assetInput = { + "@id": crypto.randomUUID(), + properties: { + name: "product description", + contenttype: "application/json", + }, + dataAddress: { + type: "HttpData", + properties: { + name: "Test asset", + baseUrl: "https://jsonplaceholder.typicode.com/users", + }, + }, + }; + await edcClient.management.assets.create(context, assetInput); + const updateAssetInput = { + "@id": assetInput["@id"], + properties: { name: "updated test asset", contenttype: "text/plain" }, + dataAddress: { + type: "s3", + }, + }; + + // when + await edcClient.management.assets.update(context, updateAssetInput); + + const updatedAsset = await edcClient.management.assets.get( + context, + assetInput["@id"], + ); + + // then + expect(updatedAsset).toHaveProperty("@type"); + expect(updatedAsset).toEqual( + expect.objectContaining({ + [`${EDC_NAMESPACE}:properties`]: { + [`${EDC_NAMESPACE}:name`]: updateAssetInput.properties.name, + [`${EDC_NAMESPACE}:id`]: updateAssetInput["@id"], + [`${EDC_NAMESPACE}:contenttype`]: + updateAssetInput.properties.contenttype, + }, + [`${EDC_NAMESPACE}:dataAddress`]: { + [`${EDC_NAMESPACE}:type`]: updateAssetInput.dataAddress.type, + "@type": "edc:DataAddress", + }, + }), + ); + }); + + it("fails to update an inexistant asset", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + const updateAssetInput = { + "@id": crypto.randomUUID(), + properties: { name: "updated test asset", contenttype: "text/plain" }, + dataAddress: { + type: "s3", + }, + }; + + // when + const maybeUpdatedAsset = edcClient.management.assets.update( + context, + updateAssetInput, + ); + + // then + await expect(maybeUpdatedAsset).rejects.toThrowError( + "resource not found", + ); + + maybeUpdatedAsset.catch((error) => { + expect(error).toBeInstanceOf(EdcConnectorClientError); + expect(error as EdcConnectorClientError).toHaveProperty( + "type", + EdcConnectorClientErrorType.NotFound, + ); + }); + }); + }); +}); diff --git a/tests/controllers/management-tests/catalog.test.ts b/tests/controllers/management-tests/catalog.test.ts new file mode 100644 index 00000000..0501e99e --- /dev/null +++ b/tests/controllers/management-tests/catalog.test.ts @@ -0,0 +1,98 @@ +import * as crypto from "node:crypto"; +import { + Addresses, + AssetInput, + ContractDefinitionInput, + EdcConnectorClient, + PolicyDefinitionInput, +} from "../../../src"; + +describe("ManagementController", () => { + const apiToken = "123456"; + const consumer: Addresses = { + default: "http://localhost:19191/api", + management: "http://localhost:19193/management", + protocol: "http://consumer-connector:9194/protocol", + public: "http://localhost:19291/public", + control: "http://localhost:19292/control", + }; + const provider: Addresses = { + default: "http://localhost:29191/api", + management: "http://localhost:29193/management", + protocol: "http://provider-connector:9194/protocol", + public: "http://localhost:29291/public", + control: "http://localhost:29292/control", + }; + + const edcClient = new EdcConnectorClient(); + + describe("edcClient.management.catalog.queryAll", () => { + it("returns the catalog for a target provider", async () => { + // given + const consumerContext = edcClient.createContext(apiToken, consumer); + const providerContext = edcClient.createContext(apiToken, provider); + const assetId = crypto.randomUUID(); + + const assetInput: AssetInput = { + "@id": assetId, + properties: { + name: "product description", + contenttype: "application/json", + }, + dataAddress: { + name: "Test asset", + baseUrl: "https://jsonplaceholder.typicode.com/users", + type: "HttpData", + }, + }; + await edcClient.management.assets.create(providerContext, assetInput); + + const policyId = crypto.randomUUID(); + const policyInput: PolicyDefinitionInput = { + id: policyId, + policy: { + uid: "231802-bb34-11ec-8422-0242ac120002", + permissions: [ + { + target: assetId, + action: { + type: "USE", + }, + edctype: "dataspaceconnector:permission", + }, + ], + }, + }; + await edcClient.management.policyDefinitions.create( + providerContext, + policyInput, + ); + + const contractDefinitionId = crypto.randomUUID(); + const contractDefinitionInput: ContractDefinitionInput = { + "@id": contractDefinitionId, + accessPolicyId: policyId, + contractPolicyId: policyId, + assetsSelector: [], + }; + await edcClient.management.contractDefinitions.create( + providerContext, + contractDefinitionInput, + ); + + // when + const catalog = await edcClient.management.catalog.queryAll( + consumerContext, + { + providerUrl: provider.protocol, + }, + ); + + // then + expect(catalog).toHaveProperty("@type", [ + "https://www.w3.org/ns/dcat/Catalog", + ]); + expect(catalog).toHaveProperty("datasets"); + }); + }); +}); diff --git a/tests/controllers/management-tests/contract-agreements.test.ts b/tests/controllers/management-tests/contract-agreements.test.ts new file mode 100644 index 00000000..fb15178a --- /dev/null +++ b/tests/controllers/management-tests/contract-agreements.test.ts @@ -0,0 +1,112 @@ +import * as crypto from "node:crypto"; +import { Addresses, EdcConnectorClient } from "../../../src"; +import { + EdcConnectorClientError, + EdcConnectorClientErrorType, +} from "../../../src/error"; +import { + createContractAgreement, + createContractNegotiation, + waitForNegotiationState, +} from "../../test-utils"; + +describe("ManagementController", () => { + const apiToken = "123456"; + const consumer: Addresses = { + default: "http://localhost:19191/api", + management: "http://localhost:19193/management", + protocol: "http://consumer-connector:9194/protocol", + public: "http://localhost:19291/public", + control: "http://localhost:19292/control", + }; + const provider: Addresses = { + default: "http://localhost:29191/api", + management: "http://localhost:29193/management", + protocol: "http://provider-connector:9194/protocol", + public: "http://localhost:29291/public", + control: "http://localhost:29292/control", + }; + + const edcClient = new EdcConnectorClient(); + + describe("edcClient.management.contractAgreements.queryAll", () => { + it("retrieves all contract agreements", async () => { + // given + const consumerContext = edcClient.createContext(apiToken, consumer); + const providerContext = edcClient.createContext(apiToken, provider); + const { idResponse } = await createContractNegotiation( + edcClient, + providerContext, + consumerContext, + ); + await waitForNegotiationState( + edcClient, + consumerContext, + idResponse.id, + "FINALIZED", + ); + const contractNegotiation = + await edcClient.management.contractNegotiations.get( + consumerContext, + idResponse.id, + ); + + // when + const contractAgreements = + await edcClient.management.contractAgreements.queryAll(consumerContext); + + // then + expect(contractAgreements.length).toBeGreaterThan(0); + expect( + contractAgreements.find( + (agreement) => + agreement.id === contractNegotiation.contractAgreementId, + ), + ).toBeTruthy(); + }); + }); + + describe("edcClient.management.getAgreement", () => { + it("retrieves target contract agreement", async () => { + // given + const consumerContext = edcClient.createContext(apiToken, consumer); + const providerContext = edcClient.createContext(apiToken, provider); + + // when + const { contractNegotiation, contractAgreement } = + await createContractAgreement( + edcClient, + providerContext, + consumerContext, + ); + + // then + expect(contractAgreement).toHaveProperty( + "id", + contractNegotiation.contractAgreementId, + ); + }); + + it("fails to fetch an not existent contract negotiation", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + + // when + const maybeAsset = edcClient.management.contractAgreements.get( + context, + crypto.randomUUID(), + ); + + // then + await expect(maybeAsset).rejects.toThrowError("resource not found"); + + maybeAsset.catch((error) => { + expect(error).toBeInstanceOf(EdcConnectorClientError); + expect(error as EdcConnectorClientError).toHaveProperty( + "type", + EdcConnectorClientErrorType.NotFound, + ); + }); + }); + }); +}); diff --git a/tests/controllers/management-tests/contract-definitions.test.ts b/tests/controllers/management-tests/contract-definitions.test.ts new file mode 100644 index 00000000..643af84b --- /dev/null +++ b/tests/controllers/management-tests/contract-definitions.test.ts @@ -0,0 +1,291 @@ +import * as crypto from "node:crypto"; +import { + Addresses, + ContractDefinitionInput, + EDC_NAMESPACE, + EdcConnectorClient, +} from "../../../src"; +import { + EdcConnectorClientError, + EdcConnectorClientErrorType, +} from "../../../src/error"; + +describe("ManagementController", () => { + const apiToken = "123456"; + const consumer: Addresses = { + default: "http://localhost:19191/api", + management: "http://localhost:19193/management", + protocol: "http://consumer-connector:9194/protocol", + public: "http://localhost:19291/public", + control: "http://localhost:19292/control", + }; + + const edcClient = new EdcConnectorClient(); + + describe("edcClient.management.contractDefinitions.create", () => { + it("succesfully creates a new contract definition", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + const contractDefinitionInput: ContractDefinitionInput = { + "@id": crypto.randomUUID(), + accessPolicyId: crypto.randomUUID(), + contractPolicyId: crypto.randomUUID(), + assetsSelector: [], + }; + + // when + const idResponse = await edcClient.management.contractDefinitions.create( + context, + contractDefinitionInput, + ); + + // then + expect(idResponse).toHaveProperty("createdAt"); + expect(idResponse).toHaveProperty("id"); + }); + + it("fails creating two contract definitions with the same id", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + const contractDefinitionInput: ContractDefinitionInput = { + "@id": crypto.randomUUID(), + accessPolicyId: crypto.randomUUID(), + contractPolicyId: crypto.randomUUID(), + assetsSelector: [], + }; + + // when + await edcClient.management.contractDefinitions.create( + context, + contractDefinitionInput, + ); + const maybeCreateResult = edcClient.management.contractDefinitions.create( + context, + contractDefinitionInput, + ); + + // then + await expect(maybeCreateResult).rejects.toThrowError( + "duplicated resource", + ); + + maybeCreateResult.catch((error) => { + expect(error).toBeInstanceOf(EdcConnectorClientError); + expect(error as EdcConnectorClientError).toHaveProperty( + "type", + EdcConnectorClientErrorType.Duplicate, + ); + }); + }); + }); + + describe("edcClient.management.contractDefinitions.queryAll", () => { + it("succesfully retuns a list of contract definitions", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + const contractDefinitionInput: ContractDefinitionInput = { + "@id": "definition-" + crypto.randomUUID(), + accessPolicyId: crypto.randomUUID(), + contractPolicyId: crypto.randomUUID(), + assetsSelector: [], + }; + await edcClient.management.contractDefinitions.create( + context, + contractDefinitionInput, + ); + + // when + const contractDefinitions = + await edcClient.management.contractDefinitions.queryAll(context); + + // then + expect(contractDefinitions.length).toBeGreaterThan(0); + expect( + contractDefinitions.find( + (contractDefinition) => + contractDefinition["@id"] === contractDefinitionInput["@id"], + ), + ).toBeTruthy(); + }); + }); + + describe("edcClient.management.contractDefinitions.get", () => { + it("succesfully retuns a target contract definition", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + const contractDefinitionInput: ContractDefinitionInput = { + "@id": crypto.randomUUID(), + accessPolicyId: crypto.randomUUID(), + contractPolicyId: crypto.randomUUID(), + assetsSelector: [], + }; + const idResponse = await edcClient.management.contractDefinitions.create( + context, + contractDefinitionInput, + ); + + // when + const contractDefinition = + await edcClient.management.contractDefinitions.get( + context, + idResponse.id, + ); + + // then + expect(contractDefinition["@id"]).toBe(idResponse.id); + }); + + it("fails to fetch an not existant contract definition", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + + // when + const maybePolicy = edcClient.management.contractDefinitions.get( + context, + crypto.randomUUID(), + ); + + // then + await expect(maybePolicy).rejects.toThrowError("resource not found"); + + maybePolicy.catch((error) => { + expect(error).toBeInstanceOf(EdcConnectorClientError); + expect(error as EdcConnectorClientError).toHaveProperty( + "type", + EdcConnectorClientErrorType.NotFound, + ); + }); + }); + }); + + describe("edcClient.management.contractDefinitions.delete", () => { + it("deletes a target contract definition", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + const contractDefinitionInput: ContractDefinitionInput = { + "@id": crypto.randomUUID(), + accessPolicyId: crypto.randomUUID(), + contractPolicyId: crypto.randomUUID(), + assetsSelector: [], + }; + const idResponse = await edcClient.management.contractDefinitions.create( + context, + contractDefinitionInput, + ); + + // when + const contractDefinition = + await edcClient.management.contractDefinitions.delete( + context, + idResponse.id, + ); + + // then + expect(contractDefinition).toBeUndefined(); + }); + + it("fails to delete an not existant contract definition", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + + // when + const maybeContractDefinition = + edcClient.management.contractDefinitions.delete( + context, + crypto.randomUUID(), + ); + + // then + await expect(maybeContractDefinition).rejects.toThrowError( + "resource not found", + ); + + maybeContractDefinition.catch((error) => { + expect(error).toBeInstanceOf(EdcConnectorClientError); + expect(error as EdcConnectorClientError).toHaveProperty( + "type", + EdcConnectorClientErrorType.NotFound, + ); + }); + }); + + describe("edcClient.management.updateContractDefinition", () => { + it("updates a target contract definition", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + const contractDefinitionInput: ContractDefinitionInput = { + "@id": crypto.randomUUID(), + accessPolicyId: crypto.randomUUID(), + contractPolicyId: crypto.randomUUID(), + assetsSelector: [], + }; + + await edcClient.management.contractDefinitions.create( + context, + contractDefinitionInput, + ); + const updateContractDefinitionInput = { + "@id": contractDefinitionInput["@id"], + accessPolicyId: crypto.randomUUID(), + contractPolicyId: crypto.randomUUID(), + assetsSelector: [], + }; + + // when + await edcClient.management.contractDefinitions.update( + context, + updateContractDefinitionInput, + ); + + const updatedContractDefinition = + await edcClient.management.contractDefinitions.get( + context, + updateContractDefinitionInput["@id"] as string, + ); + + // then + expect(updatedContractDefinition).toHaveProperty("@type"); + expect( + updatedContractDefinition[`${EDC_NAMESPACE}:accessPolicyId`], + ).toEqual(updateContractDefinitionInput.accessPolicyId); + expect( + updatedContractDefinition[`${EDC_NAMESPACE}:contractPolicyId`], + ).toEqual(updateContractDefinitionInput.contractPolicyId); + expect( + updatedContractDefinition[`${EDC_NAMESPACE}:assetsSelector`], + ).toEqual(updateContractDefinitionInput.assetsSelector); + }); + + it("fails to update an inexistant contract definition", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + const updateContractDefinitionInput = { + "@id": crypto.randomUUID(), + accessPolicyId: crypto.randomUUID(), + contractPolicyId: crypto.randomUUID(), + assetsSelector: [], + }; + + // when + const maybeUpdatedContractDefinition = + edcClient.management.contractDefinitions.update( + context, + updateContractDefinitionInput, + ); + + // then + await expect(maybeUpdatedContractDefinition).rejects.toThrowError( + "resource not found", + ); + + maybeUpdatedContractDefinition.catch((error) => { + expect(error).toBeInstanceOf(EdcConnectorClientError); + expect(error as EdcConnectorClientError).toHaveProperty( + "type", + EdcConnectorClientErrorType.NotFound, + ); + }); + }); + }); + }); +}); diff --git a/tests/controllers/management-tests/contract-negotiations.test.ts b/tests/controllers/management-tests/contract-negotiations.test.ts new file mode 100644 index 00000000..c7664f37 --- /dev/null +++ b/tests/controllers/management-tests/contract-negotiations.test.ts @@ -0,0 +1,355 @@ +import * as crypto from "node:crypto"; +import { Addresses, EdcConnectorClient } from "../../../src"; +import { + EdcConnectorClientError, + EdcConnectorClientErrorType, +} from "../../../src/error"; +import { + createContractAgreement, + createContractNegotiation, + waitForNegotiationState, +} from "../../test-utils"; + +describe("ManagementController", () => { + const apiToken = "123456"; + const consumer: Addresses = { + default: "http://localhost:19191/api", + management: "http://localhost:19193/management", + protocol: "http://consumer-connector:9194/protocol", + public: "http://localhost:19291/public", + control: "http://localhost:19292/control", + }; + const provider: Addresses = { + default: "http://localhost:29191/api", + management: "http://localhost:29193/management", + protocol: "http://provider-connector:9194/protocol", + public: "http://localhost:29291/public", + control: "http://localhost:29292/control", + }; + + const edcClient = new EdcConnectorClient(); + + describe("edcClient.management.initiateContractNegotiation", () => { + /** + TODO + Automated "decline" test case + - provider creates asset, ... + - when consumer starts needs to specify the whole policy + - if consumer changes the policy (e.g. remove permission) + - provider will decline + */ + + it("kickstart a contract negotiation", async () => { + // given + const consumerContext = edcClient.createContext(apiToken, consumer); + const providerContext = edcClient.createContext(apiToken, provider); + + // when + const { idResponse } = await createContractNegotiation( + edcClient, + providerContext, + consumerContext, + ); + + // then + expect(idResponse).toHaveProperty("id"); + expect(idResponse).toHaveProperty("createdAt"); + }); + }); + + describe("edcClient.management.contractNegotiations.queryAll", () => { + it("retrieves all contract negotiations", async () => { + // given + const consumerContext = edcClient.createContext(apiToken, consumer); + const providerContext = edcClient.createContext(apiToken, provider); + const { idResponse } = await createContractNegotiation( + edcClient, + providerContext, + consumerContext, + ); + + // when + const contractNegotiations = + await edcClient.management.contractNegotiations.queryAll( + consumerContext, + ); + + // then + expect(contractNegotiations.length).toBeGreaterThan(0); + expect( + contractNegotiations.find( + (contractNegotiation) => contractNegotiation["@id"] === idResponse.id, + ), + ).toBeTruthy(); + }); + + it("filters negotiations on the provider side based on agreements' assed ID", async () => { + // given + const consumerContext = edcClient.createContext(apiToken, consumer); + const providerContext = edcClient.createContext(apiToken, provider); + const { assetId } = await createContractAgreement( + edcClient, + providerContext, + consumerContext, + ); + + // when + const [providerNegotiation] = + await edcClient.management.contractNegotiations.queryAll( + providerContext, + { + filterExpression: [ + { + operandLeft: "contractAgreement.assetId", + operandRight: assetId, + operator: "=", + }, + ], + }, + ); + + // then + expect(providerNegotiation).toBeTruthy(); + }); + }); + + describe("edcClient.management.contractNegotiations.get", () => { + it("retrieves target contract negotiation", async () => { + // given + const consumerContext = edcClient.createContext(apiToken, consumer); + const providerContext = edcClient.createContext(apiToken, provider); + const { idResponse } = await createContractNegotiation( + edcClient, + providerContext, + consumerContext, + ); + + // when + const contractNegotiation = + await edcClient.management.contractNegotiations.get( + consumerContext, + idResponse.id, + ); + + // then + expect(contractNegotiation).toHaveProperty("@id", idResponse.id); + }); + + it("fails to fetch an not existant contract negotiation", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + + // when + const maybeAsset = edcClient.management.contractNegotiations.get( + context, + crypto.randomUUID(), + ); + + // then + await expect(maybeAsset).rejects.toThrowError("resource not found"); + + maybeAsset.catch((error) => { + expect(error).toBeInstanceOf(EdcConnectorClientError); + expect(error as EdcConnectorClientError).toHaveProperty( + "type", + EdcConnectorClientErrorType.NotFound, + ); + }); + }); + }); + + describe("edcClient.management.contractNegotiations.getState", () => { + it("returns the state of a target negotiation", async () => { + // given + const consumerContext = edcClient.createContext(apiToken, consumer); + const providerContext = edcClient.createContext(apiToken, provider); + const { idResponse } = await createContractNegotiation( + edcClient, + providerContext, + consumerContext, + ); + + // when + const contractNegotiationState = + await edcClient.management.contractNegotiations.getState( + consumerContext, + idResponse.id, + ); + + // then + expect(contractNegotiationState).toHaveProperty("state"); + }); + + it("fails to fetch an not existant contract negotiation's state", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + + // when + const maybeAsset = edcClient.management.contractNegotiations.getState( + context, + crypto.randomUUID(), + ); + + // then + await expect(maybeAsset).rejects.toThrowError("resource not found"); + + maybeAsset.catch((error) => { + expect(error).toBeInstanceOf(EdcConnectorClientError); + expect(error as EdcConnectorClientError).toHaveProperty( + "type", + EdcConnectorClientErrorType.NotFound, + ); + }); + }); + }); + + describe("edcClient.management.contractNegotiations.cancel", () => { + it.skip("cancel the requested target negotiation", async () => { + // given + const consumerContext = edcClient.createContext(apiToken, consumer); + const providerContext = edcClient.createContext(apiToken, provider); + const { idResponse } = await createContractNegotiation( + edcClient, + providerContext, + consumerContext, + ); + + const negotiationId = idResponse.id; + + // when + const cancelledNegotiation = + await edcClient.management.contractNegotiations.cancel( + consumerContext, + negotiationId, + ); + await waitForNegotiationState( + edcClient, + consumerContext, + negotiationId, + "TERMINATED", + ); + + const negotiationState = + await edcClient.management.contractNegotiations.getState( + consumerContext, + negotiationId, + ); + + // then + expect(cancelledNegotiation).toBeUndefined(); + expect(negotiationState.state).toBe("TERMINATED"); + }); + + it.skip("fails to cancel an not existant contract negotiation", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + + // when + const maybeAsset = edcClient.management.contractNegotiations.cancel( + context, + crypto.randomUUID(), + ); + + // then + await expect(maybeAsset).rejects.toThrowError("resource not found"); + + maybeAsset.catch((error) => { + expect(error).toBeInstanceOf(EdcConnectorClientError); + expect(error as EdcConnectorClientError).toHaveProperty( + "type", + EdcConnectorClientErrorType.NotFound, + ); + }); + }); + }); + + describe.skip("edcClient.management.contractNegotiations.decline", () => { + it.skip("declines the a requested target negotiation", async () => { + // given + const consumerContext = edcClient.createContext(apiToken, consumer); + const providerContext = edcClient.createContext(apiToken, provider); + const { assetId, idResponse } = await createContractNegotiation( + edcClient, + providerContext, + consumerContext, + ); + + const negotiationId = idResponse.id; + + await waitForNegotiationState( + edcClient, + consumerContext, + negotiationId, + "FINALIZED", + ); + + const providerNegotiation = + await edcClient.management.contractNegotiations.queryAll( + providerContext, + { + filterExpression: [ + { + operandLeft: "contractAgreement.assetId", + operandRight: assetId, + operator: "=", + }, + ], + }, + ); + + // when + await edcClient.management.contractNegotiations.decline( + providerContext, + providerNegotiation[0].contractAgreementId, + ); + + await waitForNegotiationState( + edcClient, + consumerContext, + negotiationId, + "TERMINATING", + ); + + const negotiationState = + await edcClient.management.contractNegotiations.getState( + consumerContext, + negotiationId, + ); + + // then + expect(negotiationState.state).toBe("TERMINATING"); + }); + }); + + describe("edcClient.management.contractNegotiations.getAgreement", () => { + it("returns the a agreement for a target negotiation", async () => { + // given + const consumerContext = edcClient.createContext(apiToken, consumer); + const providerContext = edcClient.createContext(apiToken, provider); + const { assetId, idResponse } = await createContractNegotiation( + edcClient, + providerContext, + consumerContext, + ); + + const negotiationId = idResponse.id; + + await waitForNegotiationState( + edcClient, + consumerContext, + negotiationId, + "FINALIZED", + ); + + // when + const contractAgreement = + await edcClient.management.contractNegotiations.getAgreement( + consumerContext, + negotiationId, + ); + + // then + expect(contractAgreement).toHaveProperty("assetId", assetId); + }); + }); +}); diff --git a/tests/controllers/management-tests/policy-definitions.test.ts b/tests/controllers/management-tests/policy-definitions.test.ts new file mode 100644 index 00000000..78341fb3 --- /dev/null +++ b/tests/controllers/management-tests/policy-definitions.test.ts @@ -0,0 +1,187 @@ +import * as crypto from "node:crypto"; +import { + Addresses, + EdcConnectorClient, + PolicyDefinitionInput, +} from "../../../src"; +import { + EdcConnectorClientError, + EdcConnectorClientErrorType, +} from "../../../src/error"; + +describe("ManagementController", () => { + const apiToken = "123456"; + const consumer: Addresses = { + default: "http://localhost:19191/api", + management: "http://localhost:19193/management", + protocol: "http://consumer-connector:9194/protocol", + public: "http://localhost:19291/public", + control: "http://localhost:19292/control", + }; + + const edcClient = new EdcConnectorClient(); + + describe("edcClient.management.policyDefinitions.create", () => { + it("succesfully creates a new policy", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + const policyInput: PolicyDefinitionInput = { + "@id": crypto.randomUUID(), + policy: {}, + }; + + // when + const idResponse = await edcClient.management.policyDefinitions.create( + context, + policyInput, + ); + + // then + expect(idResponse).toHaveProperty("createdAt"); + expect(idResponse).toHaveProperty("id"); + }); + + it("fails creating two policies with the same id", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + const policyInput: PolicyDefinitionInput = { + "@id": crypto.randomUUID(), + policy: {}, + }; + + // when + await edcClient.management.policyDefinitions.create(context, policyInput); + const maybeCreateResult = edcClient.management.policyDefinitions.create( + context, + policyInput, + ); + + // then + await expect(maybeCreateResult).rejects.toThrowError( + "duplicated resource", + ); + + maybeCreateResult.catch((error) => { + expect(error).toBeInstanceOf(EdcConnectorClientError); + expect(error as EdcConnectorClientError).toHaveProperty( + "type", + EdcConnectorClientErrorType.Duplicate, + ); + }); + }); + }); + + describe("edcClient.management.policyDefinitions.queryAll", () => { + it("succesfully retuns a list of assets", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + const policyInput: PolicyDefinitionInput = { + "@id": crypto.randomUUID(), + policy: {}, + }; + await edcClient.management.policyDefinitions.create(context, policyInput); + + // when + const policies = await edcClient.management.policyDefinitions.queryAll( + context, + ); + + // then + expect(policies.length).toBeGreaterThan(0); + expect( + policies.find((policy) => policy["@id"] === policyInput["@id"]), + ).toBeTruthy(); + }); + }); + + describe("edcClient.management.policyDefinitions.get", () => { + it("succesfully retuns a target policy", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + const policyInput: PolicyDefinitionInput = { + "@id": crypto.randomUUID(), + policy: {}, + }; + const idResponse = await edcClient.management.policyDefinitions.create( + context, + policyInput, + ); + + // when + const policy = await edcClient.management.policyDefinitions.get( + context, + idResponse.id, + ); + + // then + expect(policy["@id"]).toBe(idResponse.id); + }); + + it("fails to fetch an not existant policy", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + + // when + const maybePolicy = edcClient.management.policyDefinitions.get( + context, + crypto.randomUUID(), + ); + + // then + await expect(maybePolicy).rejects.toThrowError("resource not found"); + + maybePolicy.catch((error) => { + expect(error).toBeInstanceOf(EdcConnectorClientError); + expect(error as EdcConnectorClientError).toHaveProperty( + "type", + EdcConnectorClientErrorType.NotFound, + ); + }); + }); + }); + + describe("edcClient.management.policyDefinitions.delete", () => { + it("deletes a target policy", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + const policyInput: PolicyDefinitionInput = { + "@id": crypto.randomUUID(), + policy: {}, + }; + await edcClient.management.policyDefinitions.create(context, policyInput); + + // when + const policy = await edcClient.management.policyDefinitions.delete( + context, + policyInput["@id"]!, + ); + + // then + expect(policy).toBeUndefined(); + }); + + it("fails to delete an not existant policy", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + + // when + const maybeAsset = edcClient.management.policyDefinitions.delete( + context, + crypto.randomUUID(), + ); + + // then + await expect(maybeAsset).rejects.toThrowError("resource not found"); + + maybeAsset.catch((error) => { + expect(error).toBeInstanceOf(EdcConnectorClientError); + expect(error as EdcConnectorClientError).toHaveProperty( + "type", + EdcConnectorClientErrorType.NotFound, + ); + }); + }); + + it.todo("fails to delete a policy that is part of an agreed contract"); + }); +}); diff --git a/tests/controllers/management-tests/transfer-processes.test.ts b/tests/controllers/management-tests/transfer-processes.test.ts new file mode 100644 index 00000000..50f3cf34 --- /dev/null +++ b/tests/controllers/management-tests/transfer-processes.test.ts @@ -0,0 +1,330 @@ +import * as crypto from "node:crypto"; +import { Addresses, EdcConnectorClient } from "../../../src"; +import { + EdcConnectorClientError, + EdcConnectorClientErrorType, +} from "../../../src/error"; +import { + createContractAgreement, + createContractNegotiation, + createReceiverServer, + waitForNegotiationState, +} from "../../test-utils"; + +describe("ManagementController", () => { + const apiToken = "123456"; + const consumer: Addresses = { + default: "http://localhost:19191/api", + management: "http://localhost:19193/management", + protocol: "http://consumer-connector:9194/protocol", + public: "http://localhost:19291/public", + control: "http://localhost:19292/control", + }; + const provider: Addresses = { + default: "http://localhost:29191/api", + management: "http://localhost:29193/management", + protocol: "http://provider-connector:9194/protocol", + public: "http://localhost:29291/public", + control: "http://localhost:29292/control", + }; + + const edcClient = new EdcConnectorClient(); + + describe.skip("edcClient.management.contractNegotiations.decline", () => { + it.skip("declines the a requested target negotiation", async () => { + // given + const consumerContext = edcClient.createContext(apiToken, consumer); + const providerContext = edcClient.createContext(apiToken, provider); + const { assetId, idResponse } = await createContractNegotiation( + edcClient, + providerContext, + consumerContext, + ); + + const negotiationId = idResponse.id; + + await waitForNegotiationState( + edcClient, + consumerContext, + negotiationId, + "FINALIZED", + ); + + const providerNegotiation = + await edcClient.management.contractNegotiations.queryAll( + providerContext, + { + filterExpression: [ + { + operandLeft: "contractAgreement.assetId", + operandRight: assetId, + operator: "=", + }, + ], + }, + ); + + // when + await edcClient.management.contractNegotiations.decline( + providerContext, + providerNegotiation[0].contractAgreementId, + ); + + await waitForNegotiationState( + edcClient, + consumerContext, + negotiationId, + "TERMINATING", + ); + + const negotiationState = + await edcClient.management.contractNegotiations.getState( + consumerContext, + negotiationId, + ); + + // then + expect(negotiationState.state).toBe("TERMINATING"); + }); + }); + + describe("edcClient.management.contractNegotiations.getAgreement", () => { + it("returns the a agreement for a target negotiation", async () => { + // given + const consumerContext = edcClient.createContext(apiToken, consumer); + const providerContext = edcClient.createContext(apiToken, provider); + const { assetId, idResponse } = await createContractNegotiation( + edcClient, + providerContext, + consumerContext, + ); + + const negotiationId = idResponse.id; + + await waitForNegotiationState( + edcClient, + consumerContext, + negotiationId, + "FINALIZED", + ); + + // when + const contractAgreement = + await edcClient.management.contractNegotiations.getAgreement( + consumerContext, + negotiationId, + ); + + // then + expect(contractAgreement).toHaveProperty("assetId", assetId); + }); + }); + + describe("edcClient.management.contractAgreements.queryAll", () => { + it("retrieves all contract agreements", async () => { + // given + const consumerContext = edcClient.createContext(apiToken, consumer); + const providerContext = edcClient.createContext(apiToken, provider); + const { idResponse } = await createContractNegotiation( + edcClient, + providerContext, + consumerContext, + ); + await waitForNegotiationState( + edcClient, + consumerContext, + idResponse.id, + "FINALIZED", + ); + const contractNegotiation = + await edcClient.management.contractNegotiations.get( + consumerContext, + idResponse.id, + ); + + // when + const contractAgreements = + await edcClient.management.contractAgreements.queryAll(consumerContext); + + // then + expect(contractAgreements.length).toBeGreaterThan(0); + expect( + contractAgreements.find( + (agreement) => + agreement.id === contractNegotiation.contractAgreementId, + ), + ).toBeTruthy(); + }); + }); + + describe("edcClient.management.getAgreement", () => { + it("retrieves target contract agreement", async () => { + // given + const consumerContext = edcClient.createContext(apiToken, consumer); + const providerContext = edcClient.createContext(apiToken, provider); + + // when + const { contractNegotiation, contractAgreement } = + await createContractAgreement( + edcClient, + providerContext, + consumerContext, + ); + + // then + expect(contractAgreement).toHaveProperty( + "id", + contractNegotiation.contractAgreementId, + ); + }); + + it("fails to fetch an not existent contract negotiation", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + + // when + const maybeAsset = edcClient.management.contractAgreements.get( + context, + crypto.randomUUID(), + ); + + // then + await expect(maybeAsset).rejects.toThrowError("resource not found"); + + maybeAsset.catch((error) => { + expect(error).toBeInstanceOf(EdcConnectorClientError); + expect(error as EdcConnectorClientError).toHaveProperty( + "type", + EdcConnectorClientErrorType.NotFound, + ); + }); + }); + }); + + describe("with receiver server", () => { + const receiverServer = createReceiverServer(); + + beforeAll(async () => { + await receiverServer.listen(); + }); + + afterAll(async () => { + await receiverServer.shutdown(); + }); + + describe("edcClient.management.transferProcesses.queryAll", () => { + it("retrieves all tranfer processes", async () => { + // given + const consumerContext = edcClient.createContext(apiToken, consumer); + const providerContext = edcClient.createContext(apiToken, provider); + const dataplaneInput = { + id: "provider-dataplane", + url: "http://provider-connector:9192/control/transfer", + allowedSourceTypes: ["HttpData"], + allowedDestTypes: ["HttpProxy", "HttpData"], + properties: { + publicApiUrl: "http://provider-connector:9291/public/", + }, + }; + + await edcClient.management.dataplanes.register( + providerContext, + dataplaneInput, + ); + + const { assetId, contractAgreement } = await createContractAgreement( + edcClient, + providerContext, + consumerContext, + ); + + const idResponse = + await edcClient.management.transferProcesses.initiate( + consumerContext, + { + assetId, + connectorId: "provider", + connectorAddress: providerContext.protocol, + contractId: contractAgreement.id, + managedResources: false, + dataDestination: { type: "HttpProxy" }, + }, + ); + + // when + const transferProcesses = + await edcClient.management.transferProcesses.queryAll( + consumerContext, + ); + + // then + expect(transferProcesses.length).toBeGreaterThan(0); + expect( + transferProcesses.find( + (transferProcess) => idResponse.id === transferProcess.id, + ), + ).toBeTruthy(); + }); + }); + }); + + describe("edcClient.management.dataplanes.register", () => { + it("succesfully register a dataplane", async () => { + // given + const context = edcClient.createContext(apiToken, consumer); + const dataplaneInput = { + id: "consumer-dataplane", + url: "http://consumer-connector:9192/control/transfer", + allowedSourceTypes: ["HttpData"], + allowedDestTypes: ["HttpProxy", "HttpData"], + properties: { + publicApiUrl: "http://consumer-connector:9291/public/", + }, + }; + + // when + const registration = await edcClient.management.dataplanes.register( + context, + dataplaneInput, + ); + + // then + expect(registration).toBeUndefined(); + }); + }); + + describe("edcClient.management.listDataplanes", () => { + it("succesfully list available dataplanes", async () => { + const context = edcClient.createContext(apiToken, consumer); + const input = { + url: "http://consumer-connector:9192/control/transfer", + allowedSourceTypes: ["HttpData"], + allowedDestTypes: ["HttpProxy", "HttpData"], + properties: { + publicApiUrl: "http://consumer-connector:9291/public/", + }, + }; + await edcClient.management.dataplanes.register(context, input); + + const dataplanes = await edcClient.management.dataplanes.list(context); + + expect(dataplanes.length).toBeGreaterThan(0); + dataplanes.forEach((dataplane) => { + expect(dataplane).toHaveProperty("id"); + expect(dataplane).toHaveProperty("url", input.url); + expect(dataplane).toHaveProperty( + "allowedDestTypes", + input.allowedDestTypes, + ); + expect(dataplane).toHaveProperty( + "allowedSourceTypes", + input.allowedSourceTypes, + ); + expect(dataplane.properties).toHaveProperty( + "edc:publicApiUrl", + "http://consumer-connector:9291/public/", + ); + }); + }); + }); +}); diff --git a/tests/controllers/management.test.ts b/tests/controllers/management.test.ts deleted file mode 100644 index 999440d9..00000000 --- a/tests/controllers/management.test.ts +++ /dev/null @@ -1,1347 +0,0 @@ -import * as crypto from "node:crypto"; -import { - Addresses, - AssetInput, - ContractDefinitionInput, - EDC_NAMESPACE, - EdcConnectorClient, - PolicyDefinitionInput, -} from "../../src"; -import { - EdcConnectorClientError, - EdcConnectorClientErrorType, -} from "../../src/error"; -import { - createContractAgreement, - createContractNegotiation, - createReceiverServer, - waitForNegotiationState, -} from "../test-utils"; - -describe("ManagementController", () => { - const apiToken = "123456"; - const consumer: Addresses = { - default: "http://localhost:19191/api", - management: "http://localhost:19193/management", - protocol: "http://consumer-connector:9194/protocol", - public: "http://localhost:19291/public", - control: "http://localhost:19292/control", - }; - const provider: Addresses = { - default: "http://localhost:29191/api", - management: "http://localhost:29193/management", - protocol: "http://provider-connector:9194/protocol", - public: "http://localhost:29291/public", - control: "http://localhost:29292/control", - }; - - const edcClient = new EdcConnectorClient(); - - describe("edcClient.management.createAsset", () => { - it("succesfully creates an asset", async () => { - // given - const context = edcClient.createContext(apiToken, consumer); - const assetInput: AssetInput = { - "@id": crypto.randomUUID(), - properties: { - name: "product description", - contenttype: "application/json", - }, - dataAddress: { - type: "HttpData", - properties: { - baseUrl: "https://jsonplaceholder.typicode.com/users", - }, - }, - }; - - // when - const idResponse = await edcClient.management.createAsset( - context, - assetInput, - ); - - // then - expect(idResponse).toHaveProperty("createdAt"); - expect(idResponse).toHaveProperty("id"); - }); - - it("fails creating two assets with the same id", async () => { - // given - const context = edcClient.createContext(apiToken, consumer); - const assetInput: AssetInput = { - "@id": crypto.randomUUID(), - properties: { - name: "product description", - contenttype: "application/json", - }, - dataAddress: { - type: "HttpData", - properties: { - name: "Test asset", - baseUrl: "https://jsonplaceholder.typicode.com/users", - }, - }, - }; - - // when - await edcClient.management.createAsset(context, assetInput); - const maybeCreateResult = edcClient.management.createAsset( - context, - assetInput, - ); - - // then - await expect(maybeCreateResult).rejects.toThrowError( - "duplicated resource", - ); - - maybeCreateResult.catch((error) => { - expect(error).toBeInstanceOf(EdcConnectorClientError); - expect(error as EdcConnectorClientError).toHaveProperty( - "type", - EdcConnectorClientErrorType.Duplicate, - ); - }); - }); - }); - - describe("edcClient.management.deleteAsset", () => { - it("deletes a target asset", async () => { - // given - const context = edcClient.createContext(apiToken, consumer); - const assetInput: AssetInput = { - "@id": crypto.randomUUID(), - properties: { - name: "product description", - contenttype: "application/json", - }, - dataAddress: { - type: "HttpData", - properties: { - name: "Test asset", - baseUrl: "https://jsonplaceholder.typicode.com/users", - }, - }, - }; - await edcClient.management.createAsset(context, assetInput); - - // when - const asset = await edcClient.management.deleteAsset( - context, - assetInput["@id"] as string, - ); - - // then - expect(asset).toBeUndefined(); - }); - - it("fails to delete an not existant asset", async () => { - // given - const context = edcClient.createContext(apiToken, consumer); - - // when - const maybeAsset = edcClient.management.deleteAsset( - context, - crypto.randomUUID(), - ); - - // then - await expect(maybeAsset).rejects.toThrowError("resource not found"); - - maybeAsset.catch((error) => { - expect(error).toBeInstanceOf(EdcConnectorClientError); - expect(error as EdcConnectorClientError).toHaveProperty( - "type", - EdcConnectorClientErrorType.NotFound, - ); - }); - }); - - it.todo("fails to delete an asset that is part of an agreed contract"); - }); - - describe("edcClient.management.getAsset", () => { - it("returns a target asset", async () => { - // given - const context = edcClient.createContext(apiToken, consumer); - const assetInput: AssetInput = { - "@id": crypto.randomUUID(), - properties: { - name: "product description", - contenttype: "application/json", - }, - dataAddress: { - type: "HttpData", - properties: { - name: "Test asset", - baseUrl: "https://jsonplaceholder.typicode.com/users", - }, - }, - }; - await edcClient.management.createAsset(context, assetInput); - - // when - const asset = await edcClient.management.getAsset( - context, - assetInput["@id"] as string, - ); - - // then - expect(asset).toHaveProperty("@context"); - expect(asset).toHaveProperty("@id", assetInput["@id"]); - }); - - it("fails to fetch an not existant asset", async () => { - // given - const context = edcClient.createContext(apiToken, consumer); - - // when - const maybeAsset = edcClient.management.getAsset( - context, - crypto.randomUUID(), - ); - - // then - await expect(maybeAsset).rejects.toThrowError("resource not found"); - - maybeAsset.catch((error) => { - expect(error).toBeInstanceOf(EdcConnectorClientError); - expect(error as EdcConnectorClientError).toHaveProperty( - "type", - EdcConnectorClientErrorType.NotFound, - ); - }); - }); - }); - - describe("edcClient.management.queryAllAssets", () => { - it("succesfully retuns a list of assets", async () => { - // given - const context = edcClient.createContext(apiToken, consumer); - const assetInput: AssetInput = { - "@id": crypto.randomUUID(), - properties: { - name: "product description", - contenttype: "application/json", - }, - dataAddress: { - name: "Test asset", - baseUrl: "https://jsonplaceholder.typicode.com/users", - type: "HttpData", - }, - }; - await edcClient.management.createAsset(context, assetInput); - - // when - const assets = await edcClient.management.queryAllAssets(context); - - // then - expect(assets.length).toBeGreaterThan(0); - expect( - assets.find((asset) => asset?.["@id"] === assetInput["@id"]), - ).toBeTruthy(); - }); - }); - - describe("edcClient.management.updateAsset", () => { - it("updates a target asset", async () => { - // given - const context = edcClient.createContext(apiToken, consumer); - const assetInput = { - "@id": crypto.randomUUID(), - properties: { - name: "product description", - contenttype: "application/json", - }, - dataAddress: { - type: "HttpData", - properties: { - name: "Test asset", - baseUrl: "https://jsonplaceholder.typicode.com/users", - }, - }, - }; - await edcClient.management.createAsset(context, assetInput); - const updateAssetInput = { - "@id": assetInput["@id"], - properties: { name: "updated test asset", contenttype: "text/plain" }, - dataAddress: { - type: "s3", - }, - }; - - // when - await edcClient.management.updateAsset(context, updateAssetInput); - - const updatedAsset = await edcClient.management.getAsset( - context, - assetInput["@id"], - ); - - // then - expect(updatedAsset).toHaveProperty("@type"); - expect(updatedAsset).toEqual( - expect.objectContaining({ - [`${EDC_NAMESPACE}:properties`]: { - [`${EDC_NAMESPACE}:name`]: updateAssetInput.properties.name, - [`${EDC_NAMESPACE}:id`]: updateAssetInput["@id"], - [`${EDC_NAMESPACE}:contenttype`]: - updateAssetInput.properties.contenttype, - }, - [`${EDC_NAMESPACE}:dataAddress`]: { - [`${EDC_NAMESPACE}:type`]: updateAssetInput.dataAddress.type, - "@type": "edc:DataAddress", - }, - }), - ); - }); - - it("fails to update an inexistant asset", async () => { - // given - const context = edcClient.createContext(apiToken, consumer); - const updateAssetInput = { - "@id": crypto.randomUUID(), - properties: { name: "updated test asset", contenttype: "text/plain" }, - dataAddress: { - type: "s3", - }, - }; - - // when - const maybeUpdatedAsset = edcClient.management.updateAsset( - context, - updateAssetInput, - ); - - // then - await expect(maybeUpdatedAsset).rejects.toThrowError( - "resource not found", - ); - - maybeUpdatedAsset.catch((error) => { - expect(error).toBeInstanceOf(EdcConnectorClientError); - expect(error as EdcConnectorClientError).toHaveProperty( - "type", - EdcConnectorClientErrorType.NotFound, - ); - }); - }); - }); - - describe("edcClient.management.createPolicy", () => { - it("succesfully creates a new policy", async () => { - // given - const context = edcClient.createContext(apiToken, consumer); - const policyInput: PolicyDefinitionInput = { - "@id": crypto.randomUUID(), - policy: {}, - }; - - // when - const idResponse = await edcClient.management.createPolicy( - context, - policyInput, - ); - - // then - expect(idResponse).toHaveProperty("createdAt"); - expect(idResponse).toHaveProperty("id"); - }); - - it("fails creating two policies with the same id", async () => { - // given - const context = edcClient.createContext(apiToken, consumer); - const policyInput: PolicyDefinitionInput = { - "@id": crypto.randomUUID(), - policy: {}, - }; - - // when - await edcClient.management.createPolicy(context, policyInput); - const maybeCreateResult = edcClient.management.createPolicy( - context, - policyInput, - ); - - // then - await expect(maybeCreateResult).rejects.toThrowError( - "duplicated resource", - ); - - maybeCreateResult.catch((error) => { - expect(error).toBeInstanceOf(EdcConnectorClientError); - expect(error as EdcConnectorClientError).toHaveProperty( - "type", - EdcConnectorClientErrorType.Duplicate, - ); - }); - }); - }); - - describe("edcClient.management.queryAllPolicies", () => { - it("succesfully retuns a list of assets", async () => { - // given - const context = edcClient.createContext(apiToken, consumer); - const policyInput: PolicyDefinitionInput = { - "@id": crypto.randomUUID(), - policy: {}, - }; - await edcClient.management.createPolicy(context, policyInput); - - // when - const policies = await edcClient.management.queryAllPolicies(context); - - // then - expect(policies.length).toBeGreaterThan(0); - expect( - policies.find((policy) => policy["@id"] === policyInput["@id"]), - ).toBeTruthy(); - }); - }); - - describe("edcClient.management.getPolicy", () => { - it("succesfully retuns a target policy", async () => { - // given - const context = edcClient.createContext(apiToken, consumer); - const policyInput: PolicyDefinitionInput = { - "@id": crypto.randomUUID(), - policy: {}, - }; - const idResponse = await edcClient.management.createPolicy( - context, - policyInput, - ); - - // when - const policy = await edcClient.management.getPolicy( - context, - idResponse.id, - ); - - // then - expect(policy["@id"]).toBe(idResponse.id); - }); - - it("fails to fetch an not existant policy", async () => { - // given - const context = edcClient.createContext(apiToken, consumer); - - // when - const maybePolicy = edcClient.management.getPolicy( - context, - crypto.randomUUID(), - ); - - // then - await expect(maybePolicy).rejects.toThrowError("resource not found"); - - maybePolicy.catch((error) => { - expect(error).toBeInstanceOf(EdcConnectorClientError); - expect(error as EdcConnectorClientError).toHaveProperty( - "type", - EdcConnectorClientErrorType.NotFound, - ); - }); - }); - }); - - describe("edcClient.management.deletePolicy", () => { - it("deletes a target policy", async () => { - // given - const context = edcClient.createContext(apiToken, consumer); - const policyInput: PolicyDefinitionInput = { - "@id": crypto.randomUUID(), - policy: {}, - }; - await edcClient.management.createPolicy(context, policyInput); - - // when - const policy = await edcClient.management.deletePolicy( - context, - policyInput["@id"]!, - ); - - // then - expect(policy).toBeUndefined(); - }); - - it("fails to delete an not existant policy", async () => { - // given - const context = edcClient.createContext(apiToken, consumer); - - // when - const maybeAsset = edcClient.management.deletePolicy( - context, - crypto.randomUUID(), - ); - - // then - await expect(maybeAsset).rejects.toThrowError("resource not found"); - - maybeAsset.catch((error) => { - expect(error).toBeInstanceOf(EdcConnectorClientError); - expect(error as EdcConnectorClientError).toHaveProperty( - "type", - EdcConnectorClientErrorType.NotFound, - ); - }); - }); - - it.todo("fails to delete a policy that is part of an agreed contract"); - }); - - describe("edcClient.management.createContractDefinition", () => { - it("succesfully creates a new contract definition", async () => { - // given - const context = edcClient.createContext(apiToken, consumer); - const contractDefinitionInput: ContractDefinitionInput = { - "@id": crypto.randomUUID(), - accessPolicyId: crypto.randomUUID(), - contractPolicyId: crypto.randomUUID(), - assetsSelector: [], - }; - - // when - const idResponse = await edcClient.management.createContractDefinition( - context, - contractDefinitionInput, - ); - - // then - expect(idResponse).toHaveProperty("createdAt"); - expect(idResponse).toHaveProperty("id"); - }); - - it("fails creating two contract definitions with the same id", async () => { - // given - const context = edcClient.createContext(apiToken, consumer); - const contractDefinitionInput: ContractDefinitionInput = { - "@id": crypto.randomUUID(), - accessPolicyId: crypto.randomUUID(), - contractPolicyId: crypto.randomUUID(), - assetsSelector: [], - }; - - // when - await edcClient.management.createContractDefinition( - context, - contractDefinitionInput, - ); - const maybeCreateResult = edcClient.management.createContractDefinition( - context, - contractDefinitionInput, - ); - - // then - await expect(maybeCreateResult).rejects.toThrowError( - "duplicated resource", - ); - - maybeCreateResult.catch((error) => { - expect(error).toBeInstanceOf(EdcConnectorClientError); - expect(error as EdcConnectorClientError).toHaveProperty( - "type", - EdcConnectorClientErrorType.Duplicate, - ); - }); - }); - }); - - describe("edcClient.management.queryAllContractDefinitions", () => { - it("succesfully retuns a list of contract definitions", async () => { - // given - const context = edcClient.createContext(apiToken, consumer); - const contractDefinitionInput: ContractDefinitionInput = { - "@id": "definition-" + crypto.randomUUID(), - accessPolicyId: crypto.randomUUID(), - contractPolicyId: crypto.randomUUID(), - assetsSelector: [], - }; - await edcClient.management.createContractDefinition( - context, - contractDefinitionInput, - ); - - // when - const contractDefinitions = - await edcClient.management.queryAllContractDefinitions(context); - - // then - expect(contractDefinitions.length).toBeGreaterThan(0); - expect( - contractDefinitions.find( - (contractDefinition) => - contractDefinition["@id"] === contractDefinitionInput["@id"], - ), - ).toBeTruthy(); - }); - }); - - describe("edcClient.management.getContractDefinition", () => { - it("succesfully retuns a target contract definition", async () => { - // given - const context = edcClient.createContext(apiToken, consumer); - const contractDefinitionInput: ContractDefinitionInput = { - "@id": crypto.randomUUID(), - accessPolicyId: crypto.randomUUID(), - contractPolicyId: crypto.randomUUID(), - assetsSelector: [], - }; - const idResponse = await edcClient.management.createContractDefinition( - context, - contractDefinitionInput, - ); - - // when - const contractDefinition = - await edcClient.management.getContractDefinition( - context, - idResponse.id, - ); - - // then - expect(contractDefinition["@id"]).toBe(idResponse.id); - }); - - it("fails to fetch an not existant contract definition", async () => { - // given - const context = edcClient.createContext(apiToken, consumer); - - // when - const maybePolicy = edcClient.management.getContractDefinition( - context, - crypto.randomUUID(), - ); - - // then - await expect(maybePolicy).rejects.toThrowError("resource not found"); - - maybePolicy.catch((error) => { - expect(error).toBeInstanceOf(EdcConnectorClientError); - expect(error as EdcConnectorClientError).toHaveProperty( - "type", - EdcConnectorClientErrorType.NotFound, - ); - }); - }); - }); - - describe("edcClient.management.deleteContractDefinition", () => { - it("deletes a target contract definition", async () => { - // given - const context = edcClient.createContext(apiToken, consumer); - const contractDefinitionInput: ContractDefinitionInput = { - "@id": crypto.randomUUID(), - accessPolicyId: crypto.randomUUID(), - contractPolicyId: crypto.randomUUID(), - assetsSelector: [], - }; - const idResponse = await edcClient.management.createContractDefinition( - context, - contractDefinitionInput, - ); - - // when - const contractDefinition = - await edcClient.management.deleteContractDefinition( - context, - idResponse.id, - ); - - // then - expect(contractDefinition).toBeUndefined(); - }); - - it("fails to delete an not existant contract definition", async () => { - // given - const context = edcClient.createContext(apiToken, consumer); - - // when - const maybeContractDefinition = - edcClient.management.deleteContractDefinition( - context, - crypto.randomUUID(), - ); - - // then - await expect(maybeContractDefinition).rejects.toThrowError( - "resource not found", - ); - - maybeContractDefinition.catch((error) => { - expect(error).toBeInstanceOf(EdcConnectorClientError); - expect(error as EdcConnectorClientError).toHaveProperty( - "type", - EdcConnectorClientErrorType.NotFound, - ); - }); - }); - }); - - describe("edcClient.management.updateContractDefinition", () => { - it("updates a target contract definition", async () => { - // given - const context = edcClient.createContext(apiToken, consumer); - const contractDefinitionInput: ContractDefinitionInput = { - "@id": crypto.randomUUID(), - accessPolicyId: crypto.randomUUID(), - contractPolicyId: crypto.randomUUID(), - assetsSelector: [], - }; - - await edcClient.management.createContractDefinition( - context, - contractDefinitionInput, - ); - const updateContractDefinitionInput = { - "@id": contractDefinitionInput["@id"], - accessPolicyId: crypto.randomUUID(), - contractPolicyId: crypto.randomUUID(), - assetsSelector: [], - }; - - // when - await edcClient.management.updateContractDefinition( - context, - updateContractDefinitionInput, - ); - - const updatedContractDefinition = - await edcClient.management.getContractDefinition( - context, - updateContractDefinitionInput["@id"] as string, - ); - - // then - expect(updatedContractDefinition).toHaveProperty("@type"); - expect( - updatedContractDefinition[`${EDC_NAMESPACE}:accessPolicyId`], - ).toEqual(updateContractDefinitionInput.accessPolicyId); - expect( - updatedContractDefinition[`${EDC_NAMESPACE}:contractPolicyId`], - ).toEqual(updateContractDefinitionInput.contractPolicyId); - expect( - updatedContractDefinition[`${EDC_NAMESPACE}:assetsSelector`], - ).toEqual(updateContractDefinitionInput.assetsSelector); - }); - - it("fails to update an inexistant contract definition", async () => { - // given - const context = edcClient.createContext(apiToken, consumer); - const updateContractDefinitionInput = { - "@id": crypto.randomUUID(), - accessPolicyId: crypto.randomUUID(), - contractPolicyId: crypto.randomUUID(), - assetsSelector: [], - }; - - // when - const maybeUpdatedContractDefinition = - edcClient.management.updateContractDefinition( - context, - updateContractDefinitionInput, - ); - - // then - await expect(maybeUpdatedContractDefinition).rejects.toThrowError( - "resource not found", - ); - - maybeUpdatedContractDefinition.catch((error) => { - expect(error).toBeInstanceOf(EdcConnectorClientError); - expect(error as EdcConnectorClientError).toHaveProperty( - "type", - EdcConnectorClientErrorType.NotFound, - ); - }); - }); - }); - - describe("edcClient.management.requestCatalog", () => { - it("returns the catalog for a target provider", async () => { - // given - const consumerContext = edcClient.createContext(apiToken, consumer); - const providerContext = edcClient.createContext(apiToken, provider); - const assetId = crypto.randomUUID(); - - const assetInput: AssetInput = { - "@id": assetId, - properties: { - name: "product description", - contenttype: "application/json", - }, - dataAddress: { - name: "Test asset", - baseUrl: "https://jsonplaceholder.typicode.com/users", - type: "HttpData", - }, - }; - await edcClient.management.createAsset(providerContext, assetInput); - - const policyId = crypto.randomUUID(); - const policyInput: PolicyDefinitionInput = { - id: policyId, - policy: { - uid: "231802-bb34-11ec-8422-0242ac120002", - permissions: [ - { - target: assetId, - action: { - type: "USE", - }, - edctype: "dataspaceconnector:permission", - }, - ], - }, - }; - await edcClient.management.createPolicy(providerContext, policyInput); - - const contractDefinitionId = crypto.randomUUID(); - const contractDefinitionInput: ContractDefinitionInput = { - "@id": contractDefinitionId, - accessPolicyId: policyId, - contractPolicyId: policyId, - assetsSelector: [], - }; - await edcClient.management.createContractDefinition( - providerContext, - contractDefinitionInput, - ); - - // when - const catalog = await edcClient.management.requestCatalog( - consumerContext, - { - providerUrl: provider.protocol, - }, - ); - - // then - expect(catalog).toHaveProperty("@type", [ - "https://www.w3.org/ns/dcat/Catalog", - ]); - expect(catalog).toHaveProperty("datasets"); - }); - }); - - describe("edcClient.management.initiateContractNegotiation", () => { - /** - TODO - Automated "decline" test case - - provider creates asset, ... - - when consumer starts needs to specify the whole policy - - if consumer changes the policy (e.g. remove permission) - - provider will decline - */ - - it("kickstart a contract negotiation", async () => { - // given - const consumerContext = edcClient.createContext(apiToken, consumer); - const providerContext = edcClient.createContext(apiToken, provider); - - // when - const { idResponse } = await createContractNegotiation( - edcClient, - providerContext, - consumerContext, - ); - - // then - expect(idResponse).toHaveProperty("id"); - expect(idResponse).toHaveProperty("createdAt"); - }); - }); - - describe("edcClient.management.queryNegotiations", () => { - it("retrieves all contract negotiations", async () => { - // given - const consumerContext = edcClient.createContext(apiToken, consumer); - const providerContext = edcClient.createContext(apiToken, provider); - const { idResponse } = await createContractNegotiation( - edcClient, - providerContext, - consumerContext, - ); - - // when - const contractNegotiations = await edcClient.management.queryNegotiations( - consumerContext, - ); - - // then - expect(contractNegotiations.length).toBeGreaterThan(0); - expect( - contractNegotiations.find( - (contractNegotiation) => contractNegotiation["@id"] === idResponse.id, - ), - ).toBeTruthy(); - }); - - it("filters negotiations on the provider side based on agreements' assed ID", async () => { - // given - const consumerContext = edcClient.createContext(apiToken, consumer); - const providerContext = edcClient.createContext(apiToken, provider); - const { assetId } = await createContractAgreement( - edcClient, - providerContext, - consumerContext, - ); - - // when - const [providerNegotiation] = - await edcClient.management.queryNegotiations(providerContext, { - filterExpression: [ - { - operandLeft: "contractAgreement.assetId", - operandRight: assetId, - operator: "=", - }, - ], - }); - - // then - expect(providerNegotiation).toBeTruthy(); - }); - }); - - describe("edcClient.management.getNegotiation", () => { - it("retrieves target contract negotiation", async () => { - // given - const consumerContext = edcClient.createContext(apiToken, consumer); - const providerContext = edcClient.createContext(apiToken, provider); - const { idResponse } = await createContractNegotiation( - edcClient, - providerContext, - consumerContext, - ); - - // when - const contractNegotiation = await edcClient.management.getNegotiation( - consumerContext, - idResponse.id, - ); - - // then - expect(contractNegotiation).toHaveProperty("@id", idResponse.id); - }); - - it("fails to fetch an not existant contract negotiation", async () => { - // given - const context = edcClient.createContext(apiToken, consumer); - - // when - const maybeAsset = edcClient.management.getNegotiation( - context, - crypto.randomUUID(), - ); - - // then - await expect(maybeAsset).rejects.toThrowError("resource not found"); - - maybeAsset.catch((error) => { - expect(error).toBeInstanceOf(EdcConnectorClientError); - expect(error as EdcConnectorClientError).toHaveProperty( - "type", - EdcConnectorClientErrorType.NotFound, - ); - }); - }); - }); - - describe("edcClient.management.getNegotiationState", () => { - it("returns the state of a target negotiation", async () => { - // given - const consumerContext = edcClient.createContext(apiToken, consumer); - const providerContext = edcClient.createContext(apiToken, provider); - const { idResponse } = await createContractNegotiation( - edcClient, - providerContext, - consumerContext, - ); - - // when - const contractNegotiationState = - await edcClient.management.getNegotiationState( - consumerContext, - idResponse.id, - ); - - // then - expect(contractNegotiationState).toHaveProperty("state"); - }); - - it("fails to fetch an not existant contract negotiation's state", async () => { - // given - const context = edcClient.createContext(apiToken, consumer); - - // when - const maybeAsset = edcClient.management.getNegotiationState( - context, - crypto.randomUUID(), - ); - - // then - await expect(maybeAsset).rejects.toThrowError("resource not found"); - - maybeAsset.catch((error) => { - expect(error).toBeInstanceOf(EdcConnectorClientError); - expect(error as EdcConnectorClientError).toHaveProperty( - "type", - EdcConnectorClientErrorType.NotFound, - ); - }); - }); - }); - - describe("edcClient.management.cancelNegotiation", () => { - it.skip("cancel the requested target negotiation", async () => { - // given - const consumerContext = edcClient.createContext(apiToken, consumer); - const providerContext = edcClient.createContext(apiToken, provider); - const { idResponse } = await createContractNegotiation( - edcClient, - providerContext, - consumerContext, - ); - - const negotiationId = idResponse.id; - - // when - const cancelledNegotiation = await edcClient.management.cancelNegotiation( - consumerContext, - negotiationId, - ); - await waitForNegotiationState( - edcClient, - consumerContext, - negotiationId, - "TERMINATED", - ); - - const negotiationState = await edcClient.management.getNegotiationState( - consumerContext, - negotiationId, - ); - - // then - expect(cancelledNegotiation).toBeUndefined(); - expect(negotiationState.state).toBe("TERMINATED"); - }); - - it.skip("fails to cancel an not existant contract negotiation", async () => { - // given - const context = edcClient.createContext(apiToken, consumer); - - // when - const maybeAsset = edcClient.management.cancelNegotiation( - context, - crypto.randomUUID(), - ); - - // then - await expect(maybeAsset).rejects.toThrowError("resource not found"); - - maybeAsset.catch((error) => { - expect(error).toBeInstanceOf(EdcConnectorClientError); - expect(error as EdcConnectorClientError).toHaveProperty( - "type", - EdcConnectorClientErrorType.NotFound, - ); - }); - }); - }); - - describe.skip("edcClient.management.declineNegotiation", () => { - it.skip("declines the a requested target negotiation", async () => { - // given - const consumerContext = edcClient.createContext(apiToken, consumer); - const providerContext = edcClient.createContext(apiToken, provider); - const { assetId, idResponse } = await createContractNegotiation( - edcClient, - providerContext, - consumerContext, - ); - - const negotiationId = idResponse.id; - - await waitForNegotiationState( - edcClient, - consumerContext, - negotiationId, - "FINALIZED", - ); - - const providerNegotiation = await edcClient.management.queryNegotiations( - providerContext, - { - filterExpression: [ - { - operandLeft: "contractAgreement.assetId", - operandRight: assetId, - operator: "=", - }, - ], - }, - ); - - // when - await edcClient.management.declineNegotiation( - providerContext, - providerNegotiation[0].contractAgreementId, - ); - - await waitForNegotiationState( - edcClient, - consumerContext, - negotiationId, - "TERMINATING", - ); - - const negotiationState = await edcClient.management.getNegotiationState( - consumerContext, - negotiationId, - ); - - // then - expect(negotiationState.state).toBe("TERMINATING"); - }); - }); - - describe("edcClient.management.getAgreementForNegotiation", () => { - it("returns the a agreement for a target negotiation", async () => { - // given - const consumerContext = edcClient.createContext(apiToken, consumer); - const providerContext = edcClient.createContext(apiToken, provider); - const { assetId, idResponse } = await createContractNegotiation( - edcClient, - providerContext, - consumerContext, - ); - - const negotiationId = idResponse.id; - - await waitForNegotiationState( - edcClient, - consumerContext, - negotiationId, - "FINALIZED", - ); - - // when - const contractAgreement = - await edcClient.management.getAgreementForNegotiation( - consumerContext, - negotiationId, - ); - - // then - expect(contractAgreement).toHaveProperty("assetId", assetId); - }); - }); - - describe("edcClient.management.queryAllAgreements", () => { - it("retrieves all contract agreements", async () => { - // given - const consumerContext = edcClient.createContext(apiToken, consumer); - const providerContext = edcClient.createContext(apiToken, provider); - const { idResponse } = await createContractNegotiation( - edcClient, - providerContext, - consumerContext, - ); - await waitForNegotiationState( - edcClient, - consumerContext, - idResponse.id, - "FINALIZED", - ); - const contractNegotiation = await edcClient.management.getNegotiation( - consumerContext, - idResponse.id, - ); - - // when - const contractAgreements = await edcClient.management.queryAllAgreements( - consumerContext, - ); - - // then - expect(contractAgreements.length).toBeGreaterThan(0); - expect( - contractAgreements.find( - (agreement) => - agreement.id === contractNegotiation.contractAgreementId, - ), - ).toBeTruthy(); - }); - }); - - describe("edcClient.management.getAgreement", () => { - it("retrieves target contract agreement", async () => { - // given - const consumerContext = edcClient.createContext(apiToken, consumer); - const providerContext = edcClient.createContext(apiToken, provider); - - // when - const { contractNegotiation, contractAgreement } = - await createContractAgreement( - edcClient, - providerContext, - consumerContext, - ); - - // then - expect(contractAgreement).toHaveProperty( - "id", - contractNegotiation.contractAgreementId, - ); - }); - - it("fails to fetch an not existent contract negotiation", async () => { - // given - const context = edcClient.createContext(apiToken, consumer); - - // when - const maybeAsset = edcClient.management.getAgreement( - context, - crypto.randomUUID(), - ); - - // then - await expect(maybeAsset).rejects.toThrowError("resource not found"); - - maybeAsset.catch((error) => { - expect(error).toBeInstanceOf(EdcConnectorClientError); - expect(error as EdcConnectorClientError).toHaveProperty( - "type", - EdcConnectorClientErrorType.NotFound, - ); - }); - }); - }); - - describe("with receiver server", () => { - const receiverServer = createReceiverServer(); - - beforeAll(async () => { - await receiverServer.listen(); - }); - - afterAll(async () => { - await receiverServer.shutdown(); - }); - - describe("edcClient.management.queryAllTransferProcesses", () => { - it("retrieves all tranfer processes", async () => { - // given - const consumerContext = edcClient.createContext(apiToken, consumer); - const providerContext = edcClient.createContext(apiToken, provider); - const dataplaneInput = { - id: "provider-dataplane", - url: "http://provider-connector:9192/control/transfer", - allowedSourceTypes: ["HttpData"], - allowedDestTypes: ["HttpProxy", "HttpData"], - properties: { - publicApiUrl: "http://provider-connector:9291/public/", - }, - }; - - await edcClient.management.registerDataplane( - providerContext, - dataplaneInput, - ); - - const { assetId, contractAgreement } = await createContractAgreement( - edcClient, - providerContext, - consumerContext, - ); - - const idResponse = await edcClient.management.initiateTransfer( - consumerContext, - { - assetId, - connectorId: "provider", - connectorAddress: providerContext.protocol, - contractId: contractAgreement.id, - managedResources: false, - dataDestination: { type: "HttpProxy" }, - }, - ); - - // when - const transferProcesses = - await edcClient.management.queryAllTransferProcesses(consumerContext); - - // then - expect(transferProcesses.length).toBeGreaterThan(0); - expect( - transferProcesses.find( - (transferProcess) => idResponse.id === transferProcess.id, - ), - ).toBeTruthy(); - }); - }); - }); - - describe("edcClient.management.registerDataplane", () => { - it("succesfully register a dataplane", async () => { - // given - const context = edcClient.createContext(apiToken, consumer); - const dataplaneInput = { - id: "consumer-dataplane", - url: "http://consumer-connector:9192/control/transfer", - allowedSourceTypes: ["HttpData"], - allowedDestTypes: ["HttpProxy", "HttpData"], - properties: { - publicApiUrl: "http://consumer-connector:9291/public/", - }, - }; - - // when - const registration = await edcClient.management.registerDataplane( - context, - dataplaneInput, - ); - - // then - expect(registration).toBeUndefined(); - }); - }); - - describe("edcClient.management.listDataplanes", () => { - it("succesfully list available dataplanes", async () => { - const context = edcClient.createContext(apiToken, consumer); - const input = { - url: "http://consumer-connector:9192/control/transfer", - allowedSourceTypes: ["HttpData"], - allowedDestTypes: ["HttpProxy", "HttpData"], - properties: { - publicApiUrl: "http://consumer-connector:9291/public/", - }, - }; - await edcClient.management.registerDataplane(context, input); - - const dataplanes = await edcClient.management.listDataplanes(context); - - expect(dataplanes.length).toBeGreaterThan(0); - dataplanes.forEach((dataplane) => { - expect(dataplane).toHaveProperty("id"); - expect(dataplane).toHaveProperty("url", input.url); - expect(dataplane).toHaveProperty( - "allowedDestTypes", - input.allowedDestTypes, - ); - expect(dataplane).toHaveProperty( - "allowedSourceTypes", - input.allowedSourceTypes, - ); - expect(dataplane.properties).toHaveProperty( - `${EDC_NAMESPACE}:publicApiUrl`, - "http://consumer-connector:9291/public/", - ); - }); - }); - }); -}); diff --git a/tests/controllers/public.test.ts b/tests/controllers/public.test.ts index 4b82924a..73f46d05 100644 --- a/tests/controllers/public.test.ts +++ b/tests/controllers/public.test.ts @@ -43,9 +43,7 @@ describe("PublicController", () => { const maybeData = edcClient.public.getTransferredData(context, {}); // then - await expect(maybeData).rejects.toThrowError( - "request was malformed", - ); + await expect(maybeData).rejects.toThrowError("request was malformed"); maybeData.catch((error) => { expect(error).toBeInstanceOf(EdcConnectorClientError); @@ -72,7 +70,7 @@ describe("PublicController", () => { }, }; - await edcClient.management.registerDataplane( + await edcClient.management.dataplanes.register( providerContext, dataplaneInput, ); @@ -83,19 +81,21 @@ describe("PublicController", () => { consumerContext, ); - const idResponse = await edcClient.management.initiateTransfer( + const idResponse = await edcClient.management.transferProcesses.initiate( consumerContext, { assetId, - "connectorId": "provider", - "connectorAddress": providerContext.protocol, - "contractId": contractAgreement.id, - "managedResources": false, - "dataDestination": { "type": "HttpProxy" } + connectorId: "provider", + connectorAddress: providerContext.protocol, + contractId: contractAgreement.id, + managedResources: false, + dataDestination: { type: "HttpProxy" }, }, ); - const transferProcessResponse = await receiverServer.waitForEvent(idResponse.id); + const transferProcessResponse = await receiverServer.waitForEvent( + idResponse.id, + ); // when const data = await edcClient.public.getTransferredData(consumerContext, { @@ -115,7 +115,7 @@ describe("PublicController", () => { } if (data.value) { - d.push(... data.value); + d.push(...data.value); } } resolve(JSON.parse(Buffer.from(d).toString())); diff --git a/tests/test-utils.ts b/tests/test-utils.ts index 588545d5..6c7cda29 100644 --- a/tests/test-utils.ts +++ b/tests/test-utils.ts @@ -48,12 +48,12 @@ export async function createContractAgreement( "FINALIZED", ); - const contractNegotiation = await client.management.getNegotiation( + const contractNegotiation = await client.management.contractNegotiations.get( consumerContext, negotiationId, ); - const contractAgreement = await client.management.getAgreement( + const contractAgreement = await client.management.contractAgreements.get( consumerContext, contractNegotiation.contractAgreementId, ); @@ -85,7 +85,7 @@ export async function createContractNegotiation( type: "HttpData", }, }; - await client.management.createAsset(providerContext, assetInput); + await client.management.assets.create(providerContext, assetInput); // Crate policy on the provider's side const policyId = crypto.randomUUID(); @@ -96,7 +96,10 @@ export async function createContractNegotiation( permissions: [], }, }; - await client.management.createPolicy(providerContext, policyInput); + await client.management.policyDefinitions.create( + providerContext, + policyInput, + ); const contractDefinitionId = "definition-" + crypto.randomUUID(); // Crate contract definition on the provider's side @@ -106,13 +109,13 @@ export async function createContractNegotiation( contractPolicyId: policyId, assetsSelector: [], }; - await client.management.createContractDefinition( + await client.management.contractDefinitions.create( providerContext, contractDefinitionInput, ); // Retrieve catalog and select contract offer - const catalog = await client.management.requestCatalog(consumerContext, { + const catalog = await client.management.catalog.queryAll(consumerContext, { providerUrl: providerContext.protocol, }); @@ -123,7 +126,7 @@ export async function createContractNegotiation( offer._compacted = undefined; // Initiate contract negotiation on the consumer's side - const idResponse = await client.management.initiateContractNegotiation( + const idResponse = await client.management.contractNegotiations.initiate( consumerContext, { connectorAddress: providerContext.protocol, @@ -160,7 +163,7 @@ export async function waitForNegotiationState( times--; await new Promise((resolve) => setTimeout(resolve, interval)); - const response = await client.management.getNegotiationState( + const response = await client.management.contractNegotiations.getState( context, negotiationId, );