@twin.org/dataspace-control-plane-service 0.0.3-next.48 → 0.0.3-next.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/dataspaceControlPlaneService.js +31 -20
- package/dist/es/dataspaceControlPlaneService.js.map +1 -1
- package/dist/es/models/IDataspaceControlPlaneServiceConstructorOptions.js.map +1 -1
- package/dist/types/dataspaceControlPlaneService.d.ts +8 -8
- package/dist/types/models/IDataspaceControlPlaneServiceConstructorOptions.d.ts +4 -0
- package/docs/changelog.md +15 -0
- package/docs/reference/interfaces/IDataspaceControlPlaneServiceConstructorOptions.md +8 -0
- package/locales/en.json +1 -1
- package/package.json +3 -2
|
@@ -4,12 +4,13 @@ import { HttpContextIdKeys, HttpUrlHelper } from "@twin.org/api-models";
|
|
|
4
4
|
import { ContextIdHelper, ContextIdKeys, ContextIdStore } from "@twin.org/context";
|
|
5
5
|
import { AlreadyExistsError, ArrayHelper, BaseError, ComponentFactory, Converter, GeneralError, Guards, Is, NotFoundError, ObjectHelper, RandomHelper, StringHelper, UnauthorizedError, Url, Urn, ValidationError } from "@twin.org/core";
|
|
6
6
|
import { JsonLdHelper } from "@twin.org/data-json-ld";
|
|
7
|
-
import {
|
|
7
|
+
import { DataspaceControlPlaneMetricIds, DataspaceControlPlaneMetrics, DataspaceTransferFormat, TransferProcessRole, getJsonLdId, getJsonLdType } from "@twin.org/dataspace-models";
|
|
8
8
|
import { EngineCoreFactory } from "@twin.org/engine-models";
|
|
9
9
|
import { ComparisonOperator } from "@twin.org/entity";
|
|
10
10
|
import { EntityStorageConnectorFactory } from "@twin.org/entity-storage-models";
|
|
11
11
|
import { OdrlPolicyHelper, PolicyRequesterFactory } from "@twin.org/rights-management-models";
|
|
12
12
|
import { DataspaceProtocolContexts, DataspaceProtocolContractNegotiationTypes, DataspaceProtocolEndpointType, DataspaceProtocolHelper, DataspaceProtocolTransferProcessStateType, DataspaceProtocolTransferProcessTypes } from "@twin.org/standards-dataspace-protocol";
|
|
13
|
+
import { MetricHelper } from "@twin.org/telemetry-models";
|
|
13
14
|
import { TrustHelper } from "@twin.org/trust-models";
|
|
14
15
|
import { DataspaceControlPlanePolicyRequester } from "./dataspaceControlPlanePolicyRequester.js";
|
|
15
16
|
import { EndpointProperties } from "./models/endpointProperties.js";
|
|
@@ -120,6 +121,11 @@ export class DataspaceControlPlaneService {
|
|
|
120
121
|
* @internal
|
|
121
122
|
*/
|
|
122
123
|
_platformComponent;
|
|
124
|
+
/**
|
|
125
|
+
* The optional telemetry component for metrics.
|
|
126
|
+
* @internal
|
|
127
|
+
*/
|
|
128
|
+
_telemetryComponent;
|
|
123
129
|
/**
|
|
124
130
|
* Registered negotiation callbacks from upstream callers, keyed by registration key.
|
|
125
131
|
* @internal
|
|
@@ -169,6 +175,7 @@ export class DataspaceControlPlaneService {
|
|
|
169
175
|
: undefined;
|
|
170
176
|
this._taskScheduler = ComponentFactory.getIfExists(options?.taskSchedulerComponentType ?? "task-scheduler");
|
|
171
177
|
this._platformComponent = ComponentFactory.getIfExists(options?.platformComponentType ?? "platform");
|
|
178
|
+
this._telemetryComponent = ComponentFactory.getIfExists(options?.telemetryComponentType);
|
|
172
179
|
// Data plane component is optional and resolved lazily. The control plane is initialised
|
|
173
180
|
// BEFORE the data plane in engine startup order, so `getRegisteredInstanceTypeOptional`
|
|
174
181
|
// returns undefined when the engine constructs us — the wiring override can't fire here.
|
|
@@ -235,6 +242,7 @@ export class DataspaceControlPlaneService {
|
|
|
235
242
|
* @returns A promise that resolves when the federated catalogue is populated and the cleanup task is scheduled.
|
|
236
243
|
*/
|
|
237
244
|
async start(nodeLoggingComponentType) {
|
|
245
|
+
await MetricHelper.createMetrics(this._telemetryComponent, DataspaceControlPlaneMetrics);
|
|
238
246
|
const engine = EngineCoreFactory.getIfExists("engine");
|
|
239
247
|
// Skip if no engine exists OR if this is a clone instance
|
|
240
248
|
if (Is.empty(engine) || engine.isClone()) {
|
|
@@ -344,7 +352,7 @@ export class DataspaceControlPlaneService {
|
|
|
344
352
|
* @param options Request options.
|
|
345
353
|
* @param options.autoStart When true, the provider immediately starts the requested transfer (scheduled
|
|
346
354
|
* on the next tick); when omitted/false the provider start must be triggered explicitly.
|
|
347
|
-
* @param trustPayload Trust payload containing authorization information
|
|
355
|
+
* @param trustPayload Trust payload containing authorization information.
|
|
348
356
|
* @returns Transfer Process (DSP compliant) with state REQUESTED, or TransferError if the operation fails.
|
|
349
357
|
*
|
|
350
358
|
* Role Performed: Provider
|
|
@@ -377,14 +385,10 @@ export class DataspaceControlPlaneService {
|
|
|
377
385
|
ts: Date.now(),
|
|
378
386
|
message: "agreementNotFound",
|
|
379
387
|
data: {
|
|
380
|
-
|
|
381
|
-
hint: "Agreement must exist before transfer. Use contract negotiation to create agreement first."
|
|
388
|
+
notFoundId: request.agreementId
|
|
382
389
|
}
|
|
383
390
|
});
|
|
384
|
-
throw new NotFoundError(DataspaceControlPlaneService.CLASS_NAME, "agreementNotFound", request.agreementId
|
|
385
|
-
agreementId: request.agreementId,
|
|
386
|
-
hint: "Perform contract negotiation first to create an agreement"
|
|
387
|
-
});
|
|
391
|
+
throw new NotFoundError(DataspaceControlPlaneService.CLASS_NAME, "agreementNotFound", request.agreementId);
|
|
388
392
|
}
|
|
389
393
|
const assigneeIdentity = OdrlPolicyHelper.extractAssigneeIdentity(agreement);
|
|
390
394
|
const assigneeIds = ArrayHelper.fromObjectOrArray(assigneeIdentity);
|
|
@@ -453,6 +457,7 @@ export class DataspaceControlPlaneService {
|
|
|
453
457
|
await this.runProviderStart(consumerPid, contextIds?.[HttpContextIdKeys.PublicOrigin]);
|
|
454
458
|
}, 0);
|
|
455
459
|
}
|
|
460
|
+
await MetricHelper.metricIncrement(this._telemetryComponent, DataspaceControlPlaneMetricIds.TransfersRequested);
|
|
456
461
|
return {
|
|
457
462
|
"@context": [DataspaceProtocolContexts.Context],
|
|
458
463
|
"@type": DataspaceProtocolTransferProcessTypes.TransferProcess,
|
|
@@ -601,6 +606,7 @@ export class DataspaceControlPlaneService {
|
|
|
601
606
|
format
|
|
602
607
|
}
|
|
603
608
|
});
|
|
609
|
+
await MetricHelper.metricIncrement(this._telemetryComponent, DataspaceControlPlaneMetricIds.TransfersPrepared);
|
|
604
610
|
return { consumerPid };
|
|
605
611
|
}
|
|
606
612
|
// ----------------------------------------------------------------------------
|
|
@@ -610,7 +616,7 @@ export class DataspaceControlPlaneService {
|
|
|
610
616
|
* Start a Transfer Process.
|
|
611
617
|
* Transitions Transfer Process from REQUESTED to STARTED state or resumes from SUSPENDED state.
|
|
612
618
|
* @param message Transfer start message (DSP compliant).
|
|
613
|
-
* @param trustPayload Trust payload containing authorization information
|
|
619
|
+
* @param trustPayload Trust payload containing authorization information.
|
|
614
620
|
* @returns Transfer Start Message (DSP compliant) with dataAddress for PULL transfers, or TransferError if the operation fails.
|
|
615
621
|
*
|
|
616
622
|
* Role Performed: Provider / Consumer
|
|
@@ -668,6 +674,7 @@ export class DataspaceControlPlaneService {
|
|
|
668
674
|
});
|
|
669
675
|
await this._internalTransferCallback.onStateChanged(entity.consumerPid, DataspaceProtocolTransferProcessStateType.STARTED);
|
|
670
676
|
await this._internalTransferCallback.onStarted(entity.consumerPid, message);
|
|
677
|
+
await MetricHelper.metricIncrement(this._telemetryComponent, DataspaceControlPlaneMetricIds.TransfersStarted);
|
|
671
678
|
return message;
|
|
672
679
|
}
|
|
673
680
|
// PROVIDER-ACT (role === Provider): build the dataAddress, transition to STARTED, deliver below.
|
|
@@ -890,6 +897,7 @@ export class DataspaceControlPlaneService {
|
|
|
890
897
|
// Notify the consumer by POSTing the TransferStart (with its dataAddress) to the callback.
|
|
891
898
|
// Best-effort: a delivery failure must not roll back the STARTED transition.
|
|
892
899
|
await this.deliverToConsumerCallback(entity, "start", async (remoteControlPlane, token) => remoteControlPlane.startTransfer(response, token));
|
|
900
|
+
await MetricHelper.metricIncrement(this._telemetryComponent, DataspaceControlPlaneMetricIds.TransfersStarted);
|
|
893
901
|
return response;
|
|
894
902
|
}
|
|
895
903
|
catch (error) {
|
|
@@ -945,7 +953,7 @@ export class DataspaceControlPlaneService {
|
|
|
945
953
|
/**
|
|
946
954
|
* Complete a Transfer Process.
|
|
947
955
|
* @param message Transfer completion message (DSP compliant).
|
|
948
|
-
* @param trustPayload Trust payload containing authorization information
|
|
956
|
+
* @param trustPayload Trust payload containing authorization information.
|
|
949
957
|
* @returns Transfer Process (DSP compliant) with state COMPLETED, or TransferError if the operation fails.
|
|
950
958
|
*/
|
|
951
959
|
async completeTransfer(message, trustPayload) {
|
|
@@ -1025,6 +1033,7 @@ export class DataspaceControlPlaneService {
|
|
|
1025
1033
|
await this._internalTransferCallback.onStateChanged(entity.consumerPid, DataspaceProtocolTransferProcessStateType.COMPLETED);
|
|
1026
1034
|
await this._internalTransferCallback.onCompleted(entity.consumerPid);
|
|
1027
1035
|
}
|
|
1036
|
+
await MetricHelper.metricIncrement(this._telemetryComponent, DataspaceControlPlaneMetricIds.TransfersCompleted);
|
|
1028
1037
|
return {
|
|
1029
1038
|
"@context": [DataspaceProtocolContexts.Context],
|
|
1030
1039
|
"@type": DataspaceProtocolTransferProcessTypes.TransferProcess,
|
|
@@ -1040,7 +1049,7 @@ export class DataspaceControlPlaneService {
|
|
|
1040
1049
|
/**
|
|
1041
1050
|
* Suspend a Transfer Process.
|
|
1042
1051
|
* @param message Transfer suspension message (DSP compliant).
|
|
1043
|
-
* @param trustPayload Trust payload containing authorization information
|
|
1052
|
+
* @param trustPayload Trust payload containing authorization information.
|
|
1044
1053
|
* @returns Transfer Process (DSP compliant) with state SUSPENDED, or TransferError if the operation fails.
|
|
1045
1054
|
*/
|
|
1046
1055
|
async suspendTransfer(message, trustPayload) {
|
|
@@ -1127,6 +1136,7 @@ export class DataspaceControlPlaneService {
|
|
|
1127
1136
|
// PROVIDER-ACT: forward the suspension (with its reason) to the consumer callback.
|
|
1128
1137
|
await this.deliverToConsumerCallback(entity, "suspension", async (remoteControlPlane, token) => remoteControlPlane.suspendTransfer(message, token));
|
|
1129
1138
|
}
|
|
1139
|
+
await MetricHelper.metricIncrement(this._telemetryComponent, DataspaceControlPlaneMetricIds.TransfersSuspended);
|
|
1130
1140
|
return {
|
|
1131
1141
|
"@context": [DataspaceProtocolContexts.Context],
|
|
1132
1142
|
"@type": DataspaceProtocolTransferProcessTypes.TransferProcess,
|
|
@@ -1142,7 +1152,7 @@ export class DataspaceControlPlaneService {
|
|
|
1142
1152
|
/**
|
|
1143
1153
|
* Terminate a Transfer Process.
|
|
1144
1154
|
* @param message Transfer termination message (DSP compliant).
|
|
1145
|
-
* @param trustPayload Trust payload containing authorization information
|
|
1155
|
+
* @param trustPayload Trust payload containing authorization information.
|
|
1146
1156
|
* @returns Transfer Process (DSP compliant) with state TERMINATED, or TransferError if the operation fails.
|
|
1147
1157
|
*/
|
|
1148
1158
|
async terminateTransfer(message, trustPayload) {
|
|
@@ -1223,6 +1233,7 @@ export class DataspaceControlPlaneService {
|
|
|
1223
1233
|
// PROVIDER-ACT: forward the termination (with its reason) to the consumer callback.
|
|
1224
1234
|
await this.deliverToConsumerCallback(entity, "termination", async (remoteControlPlane, token) => remoteControlPlane.terminateTransfer(message, token));
|
|
1225
1235
|
}
|
|
1236
|
+
await MetricHelper.metricIncrement(this._telemetryComponent, DataspaceControlPlaneMetricIds.TransfersTerminated);
|
|
1226
1237
|
return {
|
|
1227
1238
|
"@context": [DataspaceProtocolContexts.Context],
|
|
1228
1239
|
"@type": DataspaceProtocolTransferProcessTypes.TransferProcess,
|
|
@@ -1238,7 +1249,7 @@ export class DataspaceControlPlaneService {
|
|
|
1238
1249
|
/**
|
|
1239
1250
|
* Get Transfer Process state.
|
|
1240
1251
|
* @param pid Process ID (consumerPid or providerPid).
|
|
1241
|
-
* @param trustPayload Trust payload containing authorization information
|
|
1252
|
+
* @param trustPayload Trust payload containing authorization information.
|
|
1242
1253
|
* @returns Transfer Process (DSP compliant) with current state, or TransferError if the operation fails.
|
|
1243
1254
|
*/
|
|
1244
1255
|
async getTransferProcess(pid, trustPayload) {
|
|
@@ -1372,6 +1383,7 @@ export class DataspaceControlPlaneService {
|
|
|
1372
1383
|
});
|
|
1373
1384
|
}
|
|
1374
1385
|
this._policyRequester.trackNegotiation(negotiationId);
|
|
1386
|
+
await MetricHelper.metricIncrement(this._telemetryComponent, DataspaceControlPlaneMetricIds.NegotiationsInitiated);
|
|
1375
1387
|
await this._loggingComponent?.log({
|
|
1376
1388
|
level: "info",
|
|
1377
1389
|
source: DataspaceControlPlaneService.CLASS_NAME,
|
|
@@ -1464,7 +1476,7 @@ export class DataspaceControlPlaneService {
|
|
|
1464
1476
|
/**
|
|
1465
1477
|
* Resolve consumerPid to Transfer Context.
|
|
1466
1478
|
* @param consumerPid Consumer Process ID.
|
|
1467
|
-
* @param trustPayload Trust payload containing authorization information
|
|
1479
|
+
* @param trustPayload Trust payload containing authorization information.
|
|
1468
1480
|
* @returns Transfer Context with Agreement, datasetId, and Transfer Process metadata.
|
|
1469
1481
|
*/
|
|
1470
1482
|
async resolveConsumerPid(consumerPid, trustPayload) {
|
|
@@ -1521,7 +1533,7 @@ export class DataspaceControlPlaneService {
|
|
|
1521
1533
|
/**
|
|
1522
1534
|
* Resolve providerPid to Transfer Context.
|
|
1523
1535
|
* @param providerPid Provider Process ID.
|
|
1524
|
-
* @param trustPayload Trust payload containing authorization information
|
|
1536
|
+
* @param trustPayload Trust payload containing authorization information.
|
|
1525
1537
|
* @returns Transfer Context with Agreement, datasetId, and Transfer Process metadata.
|
|
1526
1538
|
*/
|
|
1527
1539
|
async resolveProviderPid(providerPid, trustPayload) {
|
|
@@ -1631,6 +1643,7 @@ export class DataspaceControlPlaneService {
|
|
|
1631
1643
|
// Side effect first, primary storage last
|
|
1632
1644
|
await this.publishAppDataset(entity);
|
|
1633
1645
|
await this._dataspaceAppDatasetStorage.set(entity);
|
|
1646
|
+
await MetricHelper.metricIncrement(this._telemetryComponent, DataspaceControlPlaneMetricIds.AppDatasetsCreated);
|
|
1634
1647
|
return resolvedId;
|
|
1635
1648
|
}
|
|
1636
1649
|
/**
|
|
@@ -1709,6 +1722,7 @@ export class DataspaceControlPlaneService {
|
|
|
1709
1722
|
// Side effect first, primary storage last
|
|
1710
1723
|
await this.publishAppDataset(updated);
|
|
1711
1724
|
await this._dataspaceAppDatasetStorage.set(updated);
|
|
1725
|
+
await MetricHelper.metricIncrement(this._telemetryComponent, DataspaceControlPlaneMetricIds.AppDatasetsUpdated);
|
|
1712
1726
|
}
|
|
1713
1727
|
/**
|
|
1714
1728
|
* Delete a dataspace app dataset owned by the calling organization.
|
|
@@ -1735,6 +1749,7 @@ export class DataspaceControlPlaneService {
|
|
|
1735
1749
|
});
|
|
1736
1750
|
}
|
|
1737
1751
|
await this._dataspaceAppDatasetStorage.remove(id);
|
|
1752
|
+
await MetricHelper.metricIncrement(this._telemetryComponent, DataspaceControlPlaneMetricIds.AppDatasetsDeleted);
|
|
1738
1753
|
}
|
|
1739
1754
|
// ============================================================================
|
|
1740
1755
|
// PRIVATE HELPER METHODS
|
|
@@ -2438,12 +2453,8 @@ export class DataspaceControlPlaneService {
|
|
|
2438
2453
|
const contextIds = await ContextIdStore.getContextIds();
|
|
2439
2454
|
const tenantContextIds = { ...contextIds, [ContextIdKeys.Tenant]: appDataset.tenantId };
|
|
2440
2455
|
await ContextIdStore.run(tenantContextIds, async () => {
|
|
2441
|
-
const app = DataspaceAppFactory.get(appDataset.appId);
|
|
2442
2456
|
const datasetPayload = this.restampDatasetId(appDataset.dataset, appDataset.id);
|
|
2443
|
-
const
|
|
2444
|
-
const rawDatasets = overrideHandler
|
|
2445
|
-
? await overrideHandler(datasetPayload)
|
|
2446
|
-
: [datasetPayload];
|
|
2457
|
+
const rawDatasets = [datasetPayload];
|
|
2447
2458
|
const datasets = await Promise.all(rawDatasets.map(async (d) => this.populateDefaults(d)));
|
|
2448
2459
|
for (const dataset of datasets) {
|
|
2449
2460
|
const publishResult = await this._federatedCatalogueComponent.set(dataset, localTrustPayload);
|