From 447542abed74c2d39029092e919fbc6479d0fb0b Mon Sep 17 00:00:00 2001
From: efiege <105237007+efiege@users.noreply.github.com>
Date: Tue, 30 Aug 2022 11:37:03 +0200
Subject: [PATCH] Add functionality for EDC Demo (#9)
* ci: Added support for building images on tag on main branch. Renamed action.
* feature: Added support for catalog. Added possibility to create assets with arbitrary dataDestinations. Added possibility to start data transfers to arbitrary dataDestinations. Transfer Hirstory entries will be sorted by createDate now.
---
.../workflows/build-and-release-image.yaml | 1 +
.../asset-editor-dialog.component.html | 32 +++---
.../asset-editor-dialog.component.ts | 22 ++--
...log-browser-transfer-dialog.component.html | 30 +++--
...talog-browser-transfer-dialog.component.ts | 4 +-
.../catalog-browser.component.ts | 2 +-
.../contract-viewer.component.ts | 20 +---
.../transfer-history-viewer.component.ts | 106 ++++++++++--------
.../models/contract-offer-response.ts | 6 +
.../services/catalog-browser.service.ts | 5 +-
10 files changed, 112 insertions(+), 116 deletions(-)
create mode 100644 src/modules/edc-demo/models/contract-offer-response.ts
diff --git a/.github/workflows/build-and-release-image.yaml b/.github/workflows/build-and-release-image.yaml
index 24f132e7b..5c10a9f4f 100644
--- a/.github/workflows/build-and-release-image.yaml
+++ b/.github/workflows/build-and-release-image.yaml
@@ -43,6 +43,7 @@ jobs:
tags: |
type=semver,pattern={{version}},enable=${{ github.ref == format('refs/heads/{0}', 'main') }}
type=raw,value=latest,enable={{is_default_branch}}
+ type=sha
- name: Build EDC-UI image
uses: docker/build-push-action@v2
diff --git a/src/modules/edc-demo/components/asset-editor-dialog/asset-editor-dialog.component.html b/src/modules/edc-demo/components/asset-editor-dialog/asset-editor-dialog.component.html
index d46bcab78..b10624366 100644
--- a/src/modules/edc-demo/components/asset-editor-dialog/asset-editor-dialog.component.html
+++ b/src/modules/edc-demo/components/asset-editor-dialog/asset-editor-dialog.component.html
@@ -22,28 +22,24 @@
-
- Destination
-
-
- {{storageType.name}}
-
-
+
+ Type
+
-
- Account
-
+
+ Description
+
-
-
- Container
-
+
+
+
+ Originator
+
-
-
- Blob Name
-
+
+ Data Destination (JSON)
+
diff --git a/src/modules/edc-demo/components/asset-editor-dialog/asset-editor-dialog.component.ts b/src/modules/edc-demo/components/asset-editor-dialog/asset-editor-dialog.component.ts
index e95f54e04..00175e3c1 100644
--- a/src/modules/edc-demo/components/asset-editor-dialog/asset-editor-dialog.component.ts
+++ b/src/modules/edc-demo/components/asset-editor-dialog/asset-editor-dialog.component.ts
@@ -15,11 +15,10 @@ export class AssetEditorDialog implements OnInit {
version: string = '';
name: string = '';
contenttype: string = '';
-
- storageTypeId: string = 'AzureStorage';
- account: string = '';
- container: string = 'src-container';
- blobname: string = '';
+ type: string = '';
+ description: string = '';
+ originator: string = '';
+ dataDestination: string = '';
constructor(private assetService: AssetService, private dialogRef: MatDialogRef,
@Inject('STORAGE_TYPES') public storageTypes: StorageType[]) {
@@ -36,17 +35,12 @@ export class AssetEditorDialog implements OnInit {
"asset:prop:version": this.version,
"asset:prop:id": this.id,
"asset:prop:contenttype": this.contenttype,
+ "asset:prop:type": this.type,
+ "asset:prop:description": this.description,
+ "asset:prop:originator": this.originator,
}
},
- dataAddress: {
- properties: {
- "type": this.storageTypeId,
- "account": this.account,
- "container": this.container,
- "blobname": this.blobname,
- "keyName": `${this.account}-key1`
- },
- }
+ dataAddress: JSON.parse(this.dataDestination)
};
this.dialogRef.close({ assetEntryDto });
diff --git a/src/modules/edc-demo/components/catalog-browser-transfer-dialog/catalog-browser-transfer-dialog.component.html b/src/modules/edc-demo/components/catalog-browser-transfer-dialog/catalog-browser-transfer-dialog.component.html
index be3be07a4..a6d64eaa2 100644
--- a/src/modules/edc-demo/components/catalog-browser-transfer-dialog/catalog-browser-transfer-dialog.component.html
+++ b/src/modules/edc-demo/components/catalog-browser-transfer-dialog/catalog-browser-transfer-dialog.component.html
@@ -1,26 +1,24 @@
-
- Destination
-
-
- {{storageType.name}}
-
-
-
+
+ Data Destination (JSON)
+
+
-
+
-
-
-
+
+
+
diff --git a/src/modules/edc-demo/components/catalog-browser-transfer-dialog/catalog-browser-transfer-dialog.component.ts b/src/modules/edc-demo/components/catalog-browser-transfer-dialog/catalog-browser-transfer-dialog.component.ts
index 9555bcf04..0f24956ef 100644
--- a/src/modules/edc-demo/components/catalog-browser-transfer-dialog/catalog-browser-transfer-dialog.component.ts
+++ b/src/modules/edc-demo/components/catalog-browser-transfer-dialog/catalog-browser-transfer-dialog.component.ts
@@ -11,7 +11,7 @@ import {StorageType} from '../../models/storage-type';
export class CatalogBrowserTransferDialog implements OnInit {
name: string = '';
- storageTypeId = '';
+ dataDestination: string = '';
constructor(@Inject('STORAGE_TYPES') public storageTypes: StorageType[],
private dialogRef: MatDialogRef,
@@ -23,7 +23,7 @@ export class CatalogBrowserTransferDialog implements OnInit {
onTransfer() {
- this.dialogRef.close({storageTypeId: this.storageTypeId});
+ this.dialogRef.close({dataDestination: this.dataDestination});
}
}
diff --git a/src/modules/edc-demo/components/catalog-browser/catalog-browser.component.ts b/src/modules/edc-demo/components/catalog-browser/catalog-browser.component.ts
index bcc06c844..09be30c95 100644
--- a/src/modules/edc-demo/components/catalog-browser/catalog-browser.component.ts
+++ b/src/modules/edc-demo/components/catalog-browser/catalog-browser.component.ts
@@ -63,7 +63,7 @@ export class CatalogBrowserComponent implements OnInit {
assetId: contractOffer.asset.id,
policy: contractOffer.policy,
},
- connectorId: 'yomama',
+ connectorId: 'my-connector',
protocol: 'ids-multipart'
};
diff --git a/src/modules/edc-demo/components/contract-viewer/contract-viewer.component.ts b/src/modules/edc-demo/components/contract-viewer/contract-viewer.component.ts
index 3d1e4865e..4ba838034 100644
--- a/src/modules/edc-demo/components/contract-viewer/contract-viewer.component.ts
+++ b/src/modules/edc-demo/components/contract-viewer/contract-viewer.component.ts
@@ -75,12 +75,8 @@ export class ContractViewerComponent implements OnInit {
const dialogRef = this.dialog.open(CatalogBrowserTransferDialog);
dialogRef.afterClosed().pipe(first()).subscribe(result => {
- const storageTypeId: string = result.storageTypeId;
- if (storageTypeId !== 'AzureStorage') {
- this.notificationService.showError("Only storage type \"AzureStorage\" is implemented currently!")
- return;
- }
- this.createTransferRequest(contract, storageTypeId)
+ const dataDestination: string = result.dataDestination;
+ this.createTransferRequest(contract, dataDestination)
.pipe(switchMap(trq => this.transferService.initiateTransfer(trq)))
.subscribe(transferId => {
this.startPolling(transferId, contract.id!);
@@ -95,20 +91,14 @@ export class ContractViewerComponent implements OnInit {
return !!this.runningTransfers.find(rt => rt.contractId === contractId);
}
- private createTransferRequest(contract: ContractAgreementDto, storageTypeId: string): Observable {
+ private createTransferRequest(contract: ContractAgreementDto, dataDestination: string): Observable {
return this.getOfferedAssetForId(contract.assetId!).pipe(map(offeredAsset => {
return {
assetId: offeredAsset.id,
contractId: contract.id,
connectorId: "consumer", //doesn't matter, but cannot be null
- dataDestination: {
- properties: {
- "type": storageTypeId,
- account: this.homeConnectorStorageAccount, // CAUTION: hardcoded value for AzureBlob
- // container: omitted, so it will be auto-assigned by the EDC runtime
- }
- },
- managedResources: true,
+ dataDestination: JSON.parse(dataDestination),
+ managedResources: false,
transferType: {isFinite: true}, //must be there, otherwise NPE on backend
connectorAddress: offeredAsset.originator,
protocol: 'ids-multipart'
diff --git a/src/modules/edc-demo/components/transfer-history/transfer-history-viewer.component.ts b/src/modules/edc-demo/components/transfer-history/transfer-history-viewer.component.ts
index bbde4a5eb..1a8e4bf95 100644
--- a/src/modules/edc-demo/components/transfer-history/transfer-history-viewer.component.ts
+++ b/src/modules/edc-demo/components/transfer-history/transfer-history-viewer.component.ts
@@ -2,58 +2,68 @@ import {Component, OnInit} from '@angular/core';
import {Observable, of} from 'rxjs';
import {TransferProcessDto, TransferProcessService} from "../../../edc-dmgmt-client";
import {AppConfigService} from "../../../app/app-config.service";
-import {ConfirmationDialogComponent, ConfirmDialogModel} from "../confirmation-dialog/confirmation-dialog.component";
+import {
+ ConfirmationDialogComponent,
+ ConfirmDialogModel
+} from "../confirmation-dialog/confirmation-dialog.component";
import {MatDialog} from "@angular/material/dialog";
+import {map} from "rxjs/operators";
@Component({
- selector: 'edc-demo-transfer-history',
- templateUrl: './transfer-history-viewer.component.html',
- styleUrls: ['./transfer-history-viewer.component.scss']
+ selector: 'edc-demo-transfer-history',
+ templateUrl: './transfer-history-viewer.component.html',
+ styleUrls: ['./transfer-history-viewer.component.scss']
})
export class TransferHistoryViewerComponent implements OnInit {
- columns: string[] = ['id', 'creationDate', 'state', 'lastUpdated', 'connectorId', 'assetId', 'contractId', 'action'];
- transferProcesses$: Observable = of([]);
- storageExplorerLinkTemplate: string | undefined;
-
- constructor(private transferProcessService: TransferProcessService,
- private dialog : MatDialog,
- private appConfigService: AppConfigService) {
- }
-
- ngOnInit(): void {
- this.loadTransferProcesses();
- this.storageExplorerLinkTemplate = this.appConfigService.getConfig()?.storageExplorerLinkTemplate
- }
-
- onDeprovision(transferProcess: TransferProcessDto): void {
-
- const dialogData = new ConfirmDialogModel("Confirm deprovision", `Deprovisioning resources for transfer [${transferProcess.id}] will take some time and once started, it cannot be stopped.`)
- dialogData.confirmColor = "warn";
- dialogData.confirmText = "Confirm";
- dialogData.cancelText = "Abort";
- const ref = this.dialog.open(ConfirmationDialogComponent, {maxWidth: '20%', data: dialogData});
-
- ref.afterClosed().subscribe(res => {
- if (res) {
- this.transferProcessService.deprovisionTransferProcess(transferProcess.id).subscribe(() => this.loadTransferProcesses());
- }
- });
- }
-
- showStorageExplorerLink(transferProcess: TransferProcessDto) {
- return transferProcess.dataDestination?.properties?.type === 'AzureStorage' && transferProcess.state === 'COMPLETED';
- }
-
- showDeprovisionButton(transferProcess: TransferProcessDto) {
- return ['COMPLETED', 'PROVISIONED', 'REQUESTED', 'REQUESTED_ACK', 'IN_PROGRESS', 'STREAMING'].includes(transferProcess.state);
- }
-
- loadTransferProcesses() {
- this.transferProcesses$ = this.transferProcessService.getAllTransferProcesses();
- }
-
- asDate(epochMillis?: number) {
- return epochMillis ? new Date(epochMillis).toLocaleDateString() : '';
- }
+ columns: string[] = ['id', 'creationDate', 'state', 'lastUpdated', 'connectorId', 'assetId', 'contractId', 'action'];
+ transferProcesses$: Observable = of([]);
+ storageExplorerLinkTemplate: string | undefined;
+
+ constructor(private transferProcessService: TransferProcessService,
+ private dialog: MatDialog,
+ private appConfigService: AppConfigService) {
+ }
+
+ ngOnInit(): void {
+ this.loadTransferProcesses();
+ this.storageExplorerLinkTemplate = this.appConfigService.getConfig()?.storageExplorerLinkTemplate
+ }
+
+ onDeprovision(transferProcess: TransferProcessDto): void {
+
+ const dialogData = new ConfirmDialogModel("Confirm deprovision", `Deprovisioning resources for transfer [${transferProcess.id}] will take some time and once started, it cannot be stopped.`)
+ dialogData.confirmColor = "warn";
+ dialogData.confirmText = "Confirm";
+ dialogData.cancelText = "Abort";
+ const ref = this.dialog.open(ConfirmationDialogComponent, {
+ maxWidth: '20%',
+ data: dialogData
+ });
+
+ ref.afterClosed().subscribe(res => {
+ if (res) {
+ this.transferProcessService.deprovisionTransferProcess(transferProcess.id).subscribe(() => this.loadTransferProcesses());
+ }
+ });
+ }
+
+ showStorageExplorerLink(transferProcess: TransferProcessDto) {
+ return transferProcess.dataDestination?.properties?.type === 'AzureStorage' && transferProcess.state === 'COMPLETED';
+ }
+
+ showDeprovisionButton(transferProcess: TransferProcessDto) {
+ return ['COMPLETED', 'PROVISIONED', 'REQUESTED', 'REQUESTED_ACK', 'IN_PROGRESS', 'STREAMING'].includes(transferProcess.state);
+ }
+
+ loadTransferProcesses() {
+ this.transferProcesses$ = this.transferProcessService.getAllTransferProcesses()
+ .pipe(map(transferProcesses => transferProcesses.sort(function (a, b) {
+ return b.createdTimestamp?.valueOf()!-a.createdTimestamp?.valueOf()!;
+ })));
+ }
+
+ asDate(epochMillis?: number) {
+ return epochMillis ? new Date(epochMillis).toLocaleDateString() : '';
+ }
}
diff --git a/src/modules/edc-demo/models/contract-offer-response.ts b/src/modules/edc-demo/models/contract-offer-response.ts
new file mode 100644
index 000000000..6b6b2875e
--- /dev/null
+++ b/src/modules/edc-demo/models/contract-offer-response.ts
@@ -0,0 +1,6 @@
+import {ContractOffer} from "./contract-offer";
+
+export interface ContractOfferResponse {
+ id: string;
+ contractOffers: ContractOffer[];
+}
diff --git a/src/modules/edc-demo/services/catalog-browser.service.ts b/src/modules/edc-demo/services/catalog-browser.service.ts
index df30e8f15..f3366014e 100644
--- a/src/modules/edc-demo/services/catalog-browser.service.ts
+++ b/src/modules/edc-demo/services/catalog-browser.service.ts
@@ -16,6 +16,7 @@ import {
TransferProcessService,
TransferRequestDto
} from "../../edc-dmgmt-client";
+import {ContractOfferResponse} from "../models/contract-offer-response";
/**
@@ -34,8 +35,8 @@ export class CatalogBrowserService {
}
getContractOffers(): Observable {
- return this.post(this.catalogApiUrl)
- .pipe(map(contractOffers => contractOffers.map(contractOffer => {
+ return this.httpClient.get(this.catalogApiUrl)
+ .pipe(map(contractOfferResponse => contractOfferResponse.contractOffers.map(contractOffer => {
contractOffer.asset = new Asset(contractOffer.asset.properties)
return contractOffer;
})));