diff --git a/.github/ISSUE_TEMPLATE/release.md b/.github/ISSUE_TEMPLATE/release.md new file mode 100644 index 000000000..82fb55d4b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/release.md @@ -0,0 +1,30 @@ +--- +name: Release +about: Create an issue to track a release process. +title: "Release v0.0.1-milestone-8-sovity{{version}}" +labels: ["task/release", "scope/ce"] +assignees: "" +--- + +# Release + +## Work Breakdown + +Feel free to edit this release checklist in-progress depending on what tasks need to be done: +- [ ] Decide a release version depending on the previous release. +- [ ] Update this issue's title to the new version +- [ ] `release-prep` PR: + - [ ] Update the CHANGELOG.md. + - [ ] Add a clean `Unreleased` version. + - [ ] Add the version to the old section. + - [ ] Add the current date to the old version. + - [ ] Write or review a `Deployment Migration Notes` section. + - [ ] Write or review a release summary. + - [ ] Remove empty sections from the patch notes. + - [ ] Merge the `release-prep` PR. +- [ ] Wait for the main branch to be green. +- [ ] Create a release and re-use the changelog section as release description, and the version as title. +- [ ] Check if the pipeline built the release versions in the Actions-Section (or you won't see it). +- [ ] Revisit the changed list of tasks and compare it with [.github/ISSUE_TEMPLATE/release.md](https://github.com/sovity/edc-ui/blob/main/.github/ISSUE_TEMPLATE/release.md). Propose changes where it + makes sense. +- [ ] Close this issue. diff --git a/fake-backend/json/connectorLimits.json b/fake-backend/json/connectorLimits.json index 882e3a71e..66e3a4bf8 100644 --- a/fake-backend/json/connectorLimits.json +++ b/fake-backend/json/connectorLimits.json @@ -1,4 +1,4 @@ { - "numActiveConsumingContractAgreements": 2, - "maxActiveConsumingContractAgreements": 1 + "numActiveConsumingContractAgreements": 3, + "maxActiveConsumingContractAgreements": 2 } diff --git a/fake-backend/json/contractAgreementPage.json b/fake-backend/json/contractAgreementPage.json index 893422e24..c3315baaa 100644 --- a/fake-backend/json/contractAgreementPage.json +++ b/fake-backend/json/contractAgreementPage.json @@ -119,7 +119,7 @@ "assetId": "urn:artifact:my-test-asset", "createdAt": "2023-04-24T12:32:28.492Z", "properties": { - "asset:prop:id": "urn:artifact:my-test-asset" + "asset:prop:id": "urn:artifact:consumed-asset" } }, "contractPolicy": { @@ -128,7 +128,7 @@ { "edctype": "dataspaceconnector:permission", "uid": null, - "target": "urn:artifact:my-test-asset", + "target": "urn:artifact:consumed-asset", "action": { "type": "USE", "includedIn": null, @@ -191,6 +191,23 @@ "createdAt": "2023-04-24T12:32:28.492Z", "properties": { "asset:prop:id": "urn:artifact:my-test-asset-2", + "asset:prop:name": "Consuming Contract Offer If Asset Propreties Weren't Buggy", + "asset:prop:version": "1.1", + "asset:prop:originator": "https://example-connector.rail-mgmt.bahn.de/api/v1/ids/data", + "asset:prop:originatorOrganization": "Deutsche Bahn AG", + "asset:prop:keywords": "db, bahn, rail, Rail-Designer", + "asset:prop:contenttype": "application/json", + "asset:prop:description": "Train Network Map released on 10.01.2023, valid until 31.02.2023. \nFile format is xyz as exported by Rail-Designer.", + "asset:prop:language": "https://w3id.org/idsa/code/EN", + "asset:prop:publisher": "https://my.cool-api.gg/about", + "asset:prop:standardLicense": "https://my.cool-api.gg/license", + "asset:prop:endpointDocumentation": "https://my.cool-api.gg/docs", + "http://w3id.org/mds#dataCategory": "Infrastructure and Logistics", + "http://w3id.org/mds#dataSubcategory": "General Information About Planning Of Routes", + "http://w3id.org/mds#dataModel": "my-data-model-001", + "http://w3id.org/mds#geoReferenceMethod": "my-geo-reference-method", + "http://w3id.org/mds#transportMode": "Rail", + "asset:prop:some-unsupported-property": "F10E2821BBBEA527EA02200352313BC059445190", "asset:prop:datasource:http:hints:proxyMethod": "true", "asset:prop:datasource:http:hints:proxyPath": "true", "asset:prop:datasource:http:hints:proxyQueryParams": "true", @@ -243,6 +260,77 @@ } }, "transferProcesses": [] + }, + { + "contractAgreementId": "my-test-asset-cd:6ebbc301-9b1e-4cd7-9f17-97b5b786752", + "direction": "CONSUMING", + "counterPartyAddress": "http://edc2:11003/api/v1/ids/data", + "counterPartyId": "my-connector", + "contractSigningDate": "2022-03-25T11:18:59.659Z", + "contractStartDate": "2022-03-25T11:18:59.659Z", + "contractEndDate": "2022-05-01T20:04:35.658Z", + "asset": { + "assetId": "urn:artifact:my-test-asset", + "createdAt": "2023-04-24T12:32:28.492Z", + "properties": { + "asset:prop:id": "urn:artifact:consumed-asset-2" + } + }, + "contractPolicy": { + "legacyPolicy": { + "permissions": [ + { + "edctype": "dataspaceconnector:permission", + "uid": null, + "target": "urn:artifact:consumed-asset", + "action": { + "type": "USE", + "includedIn": null, + "constraint": null + }, + "assignee": null, + "assigner": null, + "constraints": [ + { + "edctype": "AtomicConstraint", + "leftExpression": { + "edctype": "dataspaceconnector:literalexpression", + "value": "ALWAYS_TRUE" + }, + "rightExpression": { + "edctype": "dataspaceconnector:literalexpression", + "value": "true" + }, + "operator": "EQ" + } + ], + "duties": [] + } + ], + "prohibitions": [], + "obligations": [], + "extensibleProperties": {}, + "inheritsFrom": null, + "assigner": null, + "assignee": null, + "target": "urn:artifact:my-test-asset", + "@type": { + "@policytype": "set" + } + } + }, + "transferProcesses": [ + { + "transferProcessId": "522138de-349d-4b68-9356-7e5929f053e0", + "lastUpdatedDate": "2023-04-24T12:32:43.027Z", + "state": { + "code": 800, + "name": "COMPLETED", + "simplifiedState": "OK" + }, + "errorMessage": null + } + ] } ] } diff --git a/src/app/component-library/catalog/asset-detail-dialog/asset-property-grid-group-builder.ts b/src/app/component-library/catalog/asset-detail-dialog/asset-property-grid-group-builder.ts index ab11ce296..756ff7f2f 100644 --- a/src/app/component-library/catalog/asset-detail-dialog/asset-property-grid-group-builder.ts +++ b/src/app/component-library/catalog/asset-detail-dialog/asset-property-grid-group-builder.ts @@ -295,7 +295,7 @@ export class AssetPropertyGridGroupBuilder { tooltip: contractAgreement.statusTooltipText, textIconAfter: contractAgreement.statusTooltipText ? 'help' : null, text: contractAgreement.statusText, - additionalClasses: 'text-warn', + additionalClasses: contractAgreement.canTransfer ? '' : 'text-warn', }); } diff --git a/src/app/core/services/asset-properties.ts b/src/app/core/services/asset-properties.ts index e69c31d65..a8b39f642 100644 --- a/src/app/core/services/asset-properties.ts +++ b/src/app/core/services/asset-properties.ts @@ -29,6 +29,9 @@ export const AssetProperties = { geoReferenceMethod: 'http://w3id.org/mds#geoReferenceMethod', transportMode: 'http://w3id.org/mds#transportMode', + hasAssetParameterizationHints: + 'asset:prop:datasource:hints:hasParameterizationHints', + /** * Whether this asset supports HTTP Method parameterization * diff --git a/src/app/core/services/http-params-mapper.service.ts b/src/app/core/services/http-params-mapper.service.ts index 9badf5594..a4f388322 100644 --- a/src/app/core/services/http-params-mapper.service.ts +++ b/src/app/core/services/http-params-mapper.service.ts @@ -33,12 +33,21 @@ export class HttpRequestParamsMapper { const body = value.httpProxiedBody?.trim() ?? ''; const contentType = value.httpProxiedBodyContentType?.trim() ?? ''; + let proxyMethod = + value.showAllHttpParameterizationFields || asset.httpProxyMethod; + let proxyPath = + value.showAllHttpParameterizationFields || asset.httpProxyPath; + let proxyQueryParams = + value.showAllHttpParameterizationFields || asset.httpProxyQueryParams; + let proxyBody = + value.showAllHttpParameterizationFields || asset.httpProxyBody; + return removeNullValues({ - method: asset.httpProxyMethod ? method : null, - pathSegments: asset.httpProxyPath ? pathSegments : null, - queryParams: asset.httpProxyQueryParams ? queryParams : null, - body: asset.httpProxyBody ? body : null, - mediaType: asset.httpProxyBody ? contentType : null, + method: proxyMethod ? method : null, + pathSegments: proxyPath ? pathSegments : null, + queryParams: proxyQueryParams ? queryParams : null, + body: proxyBody ? body : null, + mediaType: proxyBody ? contentType : null, }); } diff --git a/src/app/routes/connector-ui/contract-agreement-page/contract-agreement-transfer-dialog/contract-agreement-transfer-dialog-form-model.ts b/src/app/routes/connector-ui/contract-agreement-page/contract-agreement-transfer-dialog/contract-agreement-transfer-dialog-form-model.ts index 07faaad45..84cc72c72 100644 --- a/src/app/routes/connector-ui/contract-agreement-page/contract-agreement-transfer-dialog/contract-agreement-transfer-dialog-form-model.ts +++ b/src/app/routes/connector-ui/contract-agreement-page/contract-agreement-transfer-dialog/contract-agreement-transfer-dialog-form-model.ts @@ -31,6 +31,8 @@ export interface ContractAgreementTransferDialogFormModel { httpUrl: FormControl; httpMethod: FormControl; + showAllHttpParameterizationFields: FormControl; + httpAuthHeaderType: FormControl; httpAuthHeaderName: FormControl; httpAuthHeaderValue: FormControl; diff --git a/src/app/routes/connector-ui/contract-agreement-page/contract-agreement-transfer-dialog/contract-agreement-transfer-dialog-form.ts b/src/app/routes/connector-ui/contract-agreement-page/contract-agreement-transfer-dialog/contract-agreement-transfer-dialog-form.ts index 37b68bff3..4dcd91335 100644 --- a/src/app/routes/connector-ui/contract-agreement-page/contract-agreement-transfer-dialog/contract-agreement-transfer-dialog-form.ts +++ b/src/app/routes/connector-ui/contract-agreement-page/contract-agreement-transfer-dialog/contract-agreement-transfer-dialog-form.ts @@ -55,6 +55,8 @@ export class ContractAgreementTransferDialogForm { new Array>(), ), + showAllHttpParameterizationFields: [false], + httpProxiedPath: [''], httpProxiedMethod: ['GET'], httpProxiedQueryParams: this.formBuilder.array( @@ -96,6 +98,8 @@ export class ContractAgreementTransferDialogForm { httpHeaders: http, + showAllHttpParameterizationFields: !customTransferProcessRequest, + httpProxiedPath: !customTransferProcessRequest, httpProxiedMethod: !customTransferProcessRequest, httpProxiedQueryParams: !customTransferProcessRequest, diff --git a/src/app/routes/connector-ui/contract-agreement-page/contract-agreement-transfer-dialog/contract-agreement-transfer-dialog.component.html b/src/app/routes/connector-ui/contract-agreement-page/contract-agreement-transfer-dialog/contract-agreement-transfer-dialog.component.html index 5e84887e4..901dc4f03 100644 --- a/src/app/routes/connector-ui/contract-agreement-page/contract-agreement-transfer-dialog/contract-agreement-transfer-dialog.component.html +++ b/src/app/routes/connector-ui/contract-agreement-page/contract-agreement-transfer-dialog/contract-agreement-transfer-dialog.component.html @@ -203,11 +203,27 @@

Initiate Transfer

-
Datasource Parameterization
+ *ngIf="form.dataAddressType !== 'Custom-Transfer-Process-Request'"> +
HTTP Datasource Parameterization
+ +
+ When the data offer on the provider side is of the type + HttpData and certain data source fields are set, certain parts + of the request to the data source can be customized from the consumer + side and will be passed to the other connector when initiating the + transfer. This allows an asset to contain more than just one kind of + data, allowing additional filtering or even sharing of entire APIs + with multiple data sets via a single asset and a single contract. +
+ +
+ The resulting URL will look like + {{ + '{baseUrl}{customSubPath}?{baseQueryParams}&{customQueryParams}' + }} +
Initiate Transfer - Method + Custom Method Initiate Transfer - Custom Path Segment + Custom Subpath - Will be added to Base URL. Default: + Default: {{ data.asset.httpDefaultPath ?? 'Unknown' }} @@ -258,7 +274,7 @@

Initiate Transfer

class="flex flex-row space-x-[10px]"> - Query Param Name + Custom Query Param Name Initiate Transfer mat-button color="primary" (click)="form.onHttpQueryParamsAddClick()"> - Add Query Param + Add Custom Query Param
@@ -301,7 +317,7 @@

Initiate Transfer

- Content Type + Custom Request Body Content Type Initiate Transfer - Body + Custom Request Body + + +
+ +
diff --git a/src/app/routes/connector-ui/contract-agreement-page/contract-agreement-transfer-dialog/contract-agreement-transfer-dialog.component.ts b/src/app/routes/connector-ui/contract-agreement-page/contract-agreement-transfer-dialog/contract-agreement-transfer-dialog.component.ts index 3c615aa4a..ea20e0346 100644 --- a/src/app/routes/connector-ui/contract-agreement-page/contract-agreement-transfer-dialog/contract-agreement-transfer-dialog.component.ts +++ b/src/app/routes/connector-ui/contract-agreement-page/contract-agreement-transfer-dialog/contract-agreement-transfer-dialog.component.ts @@ -26,19 +26,44 @@ export class ContractAgreementTransferDialogComponent implements OnDestroy { dataSourceMethods = ['GET', ...this.dataSinkMethods]; get proxyMethod(): boolean { - return this.data.asset.httpProxyMethod == true; + return ( + this.showAllHttpParameterizationFields || + this.data.asset.httpProxyMethod == true + ); } get proxyPath(): boolean { - return this.data.asset.httpProxyPath == true; + return ( + this.showAllHttpParameterizationFields || + this.data.asset.httpProxyPath == true + ); } get proxyQueryParams(): boolean { - return this.data.asset.httpProxyQueryParams == true; + return ( + this.showAllHttpParameterizationFields || + this.data.asset.httpProxyQueryParams == true + ); } get proxyBody(): boolean { - return this.data.asset.httpProxyBody == true; + return ( + this.showAllHttpParameterizationFields || + this.data.asset.httpProxyBody == true + ); + } + + get showHttpParameterizationToggleButton(): boolean { + return ( + this.data.asset.httpProxyMethod !== true || + this.data.asset.httpProxyPath !== true || + this.data.asset.httpProxyQueryParams !== true || + this.data.asset.httpProxyBody !== true + ); + } + + get showAllHttpParameterizationFields(): boolean { + return this.form.all.controls.showAllHttpParameterizationFields.value; } constructor( @@ -50,7 +75,18 @@ export class ContractAgreementTransferDialogComponent implements OnDestroy { private httpRequestParamsMapper: HttpRequestParamsMapper, private dataAddressMapper: DataAddressMapper, @Inject(MAT_DIALOG_DATA) public data: ContractAgreementTransferDialogData, - ) {} + ) { + if (data.asset.httpDefaultMethod) { + this.form.all.controls.httpProxiedMethod.setValue( + data.asset.httpDefaultMethod, + ); + } + if (data.asset.httpDefaultPath) { + this.form.all.controls.httpProxiedPath.setValue( + data.asset.httpDefaultPath, + ); + } + } onSave() { if (this.loading && !this.form.all.valid) {