@finos/legend-graph 32.5.2 → 32.6.0

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.
Files changed (94) hide show
  1. package/lib/graph/Core_HashUtils.d.ts +2 -0
  2. package/lib/graph/Core_HashUtils.d.ts.map +1 -1
  3. package/lib/graph/Core_HashUtils.js +2 -0
  4. package/lib/graph/Core_HashUtils.js.map +1 -1
  5. package/lib/graph/metamodel/pure/dataProduct/DataProduct.d.ts +10 -0
  6. package/lib/graph/metamodel/pure/dataProduct/DataProduct.d.ts.map +1 -1
  7. package/lib/graph/metamodel/pure/dataProduct/DataProduct.js +16 -0
  8. package/lib/graph/metamodel/pure/dataProduct/DataProduct.js.map +1 -1
  9. package/lib/graph/metamodel/pure/packageableElements/ingest/IngestDefinition.d.ts +11 -2
  10. package/lib/graph/metamodel/pure/packageableElements/ingest/IngestDefinition.d.ts.map +1 -1
  11. package/lib/graph/metamodel/pure/packageableElements/ingest/IngestDefinition.js +17 -0
  12. package/lib/graph/metamodel/pure/packageableElements/ingest/IngestDefinition.js.map +1 -1
  13. package/lib/graph-manager/AbstractPureGraphManager.d.ts +1 -0
  14. package/lib/graph-manager/AbstractPureGraphManager.d.ts.map +1 -1
  15. package/lib/graph-manager/AbstractPureGraphManager.js.map +1 -1
  16. package/lib/graph-manager/action/analytics/data-product/DataProductAnalysis.d.ts +4 -4
  17. package/lib/graph-manager/action/analytics/data-product/DataProductAnalysis.d.ts.map +1 -1
  18. package/lib/graph-manager/action/analytics/data-product/DataProductAnalysis.js.map +1 -1
  19. package/lib/graph-manager/action/changeDetection/DataProductObserveHelper.d.ts +4 -1
  20. package/lib/graph-manager/action/changeDetection/DataProductObserveHelper.d.ts.map +1 -1
  21. package/lib/graph-manager/action/changeDetection/DataProductObserveHelper.js +25 -1
  22. package/lib/graph-manager/action/changeDetection/DataProductObserveHelper.js.map +1 -1
  23. package/lib/graph-manager/action/query/Query.d.ts +2 -0
  24. package/lib/graph-manager/action/query/Query.d.ts.map +1 -1
  25. package/lib/graph-manager/action/query/Query.js +2 -0
  26. package/lib/graph-manager/action/query/Query.js.map +1 -1
  27. package/lib/graph-manager/protocol/pure/v1/V1_PureGraphManager.d.ts +9 -0
  28. package/lib/graph-manager/protocol/pure/v1/V1_PureGraphManager.d.ts.map +1 -1
  29. package/lib/graph-manager/protocol/pure/v1/V1_PureGraphManager.js +90 -25
  30. package/lib/graph-manager/protocol/pure/v1/V1_PureGraphManager.js.map +1 -1
  31. package/lib/graph-manager/protocol/pure/v1/engine/V1_EngineHelper.d.ts.map +1 -1
  32. package/lib/graph-manager/protocol/pure/v1/engine/V1_EngineHelper.js +3 -0
  33. package/lib/graph-manager/protocol/pure/v1/engine/V1_EngineHelper.js.map +1 -1
  34. package/lib/graph-manager/protocol/pure/v1/engine/V1_EngineServerClient.d.ts +1 -0
  35. package/lib/graph-manager/protocol/pure/v1/engine/V1_EngineServerClient.d.ts.map +1 -1
  36. package/lib/graph-manager/protocol/pure/v1/engine/V1_EngineServerClient.js +2 -0
  37. package/lib/graph-manager/protocol/pure/v1/engine/V1_EngineServerClient.js.map +1 -1
  38. package/lib/graph-manager/protocol/pure/v1/engine/V1_GraphManagerEngine.d.ts +1 -0
  39. package/lib/graph-manager/protocol/pure/v1/engine/V1_GraphManagerEngine.d.ts.map +1 -1
  40. package/lib/graph-manager/protocol/pure/v1/engine/V1_RemoteEngine.d.ts +1 -0
  41. package/lib/graph-manager/protocol/pure/v1/engine/V1_RemoteEngine.d.ts.map +1 -1
  42. package/lib/graph-manager/protocol/pure/v1/engine/V1_RemoteEngine.js +3 -0
  43. package/lib/graph-manager/protocol/pure/v1/engine/V1_RemoteEngine.js.map +1 -1
  44. package/lib/graph-manager/protocol/pure/v1/engine/query/V1_Query.d.ts +2 -1
  45. package/lib/graph-manager/protocol/pure/v1/engine/query/V1_Query.d.ts.map +1 -1
  46. package/lib/graph-manager/protocol/pure/v1/engine/query/V1_Query.js +3 -1
  47. package/lib/graph-manager/protocol/pure/v1/engine/query/V1_Query.js.map +1 -1
  48. package/lib/graph-manager/protocol/pure/v1/lakehouse/entitlements/V1_CoreEntitlements.d.ts +6 -10
  49. package/lib/graph-manager/protocol/pure/v1/lakehouse/entitlements/V1_CoreEntitlements.d.ts.map +1 -1
  50. package/lib/graph-manager/protocol/pure/v1/lakehouse/entitlements/V1_CoreEntitlements.js +11 -8
  51. package/lib/graph-manager/protocol/pure/v1/lakehouse/entitlements/V1_CoreEntitlements.js.map +1 -1
  52. package/lib/graph-manager/protocol/pure/v1/model/packageableElements/dataProduct/V1_DataProduct.d.ts +13 -2
  53. package/lib/graph-manager/protocol/pure/v1/model/packageableElements/dataProduct/V1_DataProduct.d.ts.map +1 -1
  54. package/lib/graph-manager/protocol/pure/v1/model/packageableElements/dataProduct/V1_DataProduct.js +19 -2
  55. package/lib/graph-manager/protocol/pure/v1/model/packageableElements/dataProduct/V1_DataProduct.js.map +1 -1
  56. package/lib/graph-manager/protocol/pure/v1/transformation/pureGraph/from/V1_DataProductTransformer.d.ts.map +1 -1
  57. package/lib/graph-manager/protocol/pure/v1/transformation/pureGraph/from/V1_DataProductTransformer.js +22 -2
  58. package/lib/graph-manager/protocol/pure/v1/transformation/pureGraph/from/V1_DataProductTransformer.js.map +1 -1
  59. package/lib/graph-manager/protocol/pure/v1/transformation/pureGraph/to/V1_ElementSecondPassBuilder.d.ts.map +1 -1
  60. package/lib/graph-manager/protocol/pure/v1/transformation/pureGraph/to/V1_ElementSecondPassBuilder.js +4 -1
  61. package/lib/graph-manager/protocol/pure/v1/transformation/pureGraph/to/V1_ElementSecondPassBuilder.js.map +1 -1
  62. package/lib/graph-manager/protocol/pure/v1/transformation/pureGraph/to/helpers/V1_DataProductBuilder.d.ts +3 -2
  63. package/lib/graph-manager/protocol/pure/v1/transformation/pureGraph/to/helpers/V1_DataProductBuilder.d.ts.map +1 -1
  64. package/lib/graph-manager/protocol/pure/v1/transformation/pureGraph/to/helpers/V1_DataProductBuilder.js +22 -2
  65. package/lib/graph-manager/protocol/pure/v1/transformation/pureGraph/to/helpers/V1_DataProductBuilder.js.map +1 -1
  66. package/lib/graph-manager/protocol/pure/v1/transformation/pureProtocol/serializationHelpers/V1_DataProductSerializationHelper.d.ts.map +1 -1
  67. package/lib/graph-manager/protocol/pure/v1/transformation/pureProtocol/serializationHelpers/V1_DataProductSerializationHelper.js +21 -1
  68. package/lib/graph-manager/protocol/pure/v1/transformation/pureProtocol/serializationHelpers/V1_DataProductSerializationHelper.js.map +1 -1
  69. package/lib/index.d.ts +2 -2
  70. package/lib/index.d.ts.map +1 -1
  71. package/lib/index.js +2 -2
  72. package/lib/index.js.map +1 -1
  73. package/lib/package.json +1 -1
  74. package/package.json +1 -1
  75. package/src/graph/Core_HashUtils.ts +2 -0
  76. package/src/graph/metamodel/pure/dataProduct/DataProduct.ts +22 -0
  77. package/src/graph/metamodel/pure/packageableElements/ingest/IngestDefinition.ts +20 -2
  78. package/src/graph-manager/AbstractPureGraphManager.ts +4 -0
  79. package/src/graph-manager/action/analytics/data-product/DataProductAnalysis.ts +11 -4
  80. package/src/graph-manager/action/changeDetection/DataProductObserveHelper.ts +31 -0
  81. package/src/graph-manager/action/query/Query.ts +2 -0
  82. package/src/graph-manager/protocol/pure/v1/V1_PureGraphManager.ts +219 -32
  83. package/src/graph-manager/protocol/pure/v1/engine/V1_EngineHelper.ts +3 -0
  84. package/src/graph-manager/protocol/pure/v1/engine/V1_EngineServerClient.ts +12 -0
  85. package/src/graph-manager/protocol/pure/v1/engine/V1_GraphManagerEngine.ts +5 -0
  86. package/src/graph-manager/protocol/pure/v1/engine/V1_RemoteEngine.ts +10 -0
  87. package/src/graph-manager/protocol/pure/v1/engine/query/V1_Query.ts +3 -1
  88. package/src/graph-manager/protocol/pure/v1/lakehouse/entitlements/V1_CoreEntitlements.ts +19 -11
  89. package/src/graph-manager/protocol/pure/v1/model/packageableElements/dataProduct/V1_DataProduct.ts +25 -4
  90. package/src/graph-manager/protocol/pure/v1/transformation/pureGraph/from/V1_DataProductTransformer.ts +24 -0
  91. package/src/graph-manager/protocol/pure/v1/transformation/pureGraph/to/V1_ElementSecondPassBuilder.ts +4 -0
  92. package/src/graph-manager/protocol/pure/v1/transformation/pureGraph/to/helpers/V1_DataProductBuilder.ts +30 -0
  93. package/src/graph-manager/protocol/pure/v1/transformation/pureProtocol/serializationHelpers/V1_DataProductSerializationHelper.ts +34 -0
  94. package/src/index.ts +5 -0
@@ -15,6 +15,7 @@
15
15
  */
16
16
 
17
17
  import type {
18
+ LakehouseAccessPoint,
18
19
  ModelAccessPointGroup,
19
20
  NativeModelExecutionContext,
20
21
  } from '../../../../graph/metamodel/pure/dataProduct/DataProduct.js';
@@ -31,14 +32,20 @@ export class DataProductAnalysis {
31
32
  }
32
33
 
33
34
  export class DataProductAnalysisQueryResult {
34
- targetMappingPath: string;
35
+ targetMappingPath: string | undefined;
35
36
  dataProductAnalysis: DataProductAnalysis;
36
- targetExecState: NativeModelExecutionContext | ModelAccessPointGroup;
37
+ targetExecState:
38
+ | NativeModelExecutionContext
39
+ | ModelAccessPointGroup
40
+ | LakehouseAccessPoint;
37
41
 
38
42
  constructor(
39
- targetMappingPath: string,
43
+ targetMappingPath: string | undefined,
40
44
  dataProductAnalysis: DataProductAnalysis,
41
- targetExecState: NativeModelExecutionContext | ModelAccessPointGroup,
45
+ targetExecState:
46
+ | NativeModelExecutionContext
47
+ | ModelAccessPointGroup
48
+ | LakehouseAccessPoint,
42
49
  ) {
43
50
  this.targetMappingPath = targetMappingPath;
44
51
  this.dataProductAnalysis = dataProductAnalysis;
@@ -33,7 +33,9 @@ import {
33
33
  UnknownDataProductIcon,
34
34
  type Expertise,
35
35
  type DataProductOperationalMetadata,
36
+ AppDirOwner,
36
37
  } from '../../../graph/metamodel/pure/dataProduct/DataProduct.js';
38
+ import { type AppDirNode } from '../../../graph/metamodel/pure/packageableElements/ingest/IngestDefinition.js';
37
39
  import {
38
40
  observe_Abstract_PackageableElement,
39
41
  observe_PackageableElementReference,
@@ -225,6 +227,31 @@ export const observe_DataProductIcon = skipObserved(
225
227
  },
226
228
  );
227
229
 
230
+ export const observe_AppDirNode = skipObserved(
231
+ (metamodel: AppDirNode): AppDirNode => {
232
+ makeObservable(metamodel, {
233
+ appDirId: observable,
234
+ });
235
+ return metamodel;
236
+ },
237
+ );
238
+
239
+ export const observe_AppDirOwner = skipObserved(
240
+ (metamodel: AppDirOwner): AppDirOwner => {
241
+ makeObservable(metamodel, {
242
+ production: observable,
243
+ prodParallel: observable,
244
+ });
245
+ if (metamodel.production) {
246
+ observe_AppDirNode(metamodel.production);
247
+ }
248
+ if (metamodel.prodParallel) {
249
+ observe_AppDirNode(metamodel.prodParallel);
250
+ }
251
+ return metamodel;
252
+ },
253
+ );
254
+
228
255
  export const observe_DataProduct = skipObserved(
229
256
  (metamodel: DataProduct): DataProduct => {
230
257
  observe_Abstract_PackageableElement(metamodel);
@@ -238,6 +265,7 @@ export const observe_DataProduct = skipObserved(
238
265
  icon: observable,
239
266
  type: observable,
240
267
  operationalMetadata: observable,
268
+ owner: observable,
241
269
  });
242
270
 
243
271
  if (metamodel.supportInfo) {
@@ -249,6 +277,9 @@ export const observe_DataProduct = skipObserved(
249
277
  if (metamodel.operationalMetadata) {
250
278
  observe_OperationalMetadata(metamodel.operationalMetadata);
251
279
  }
280
+ if (metamodel.owner instanceof AppDirOwner) {
281
+ observe_AppDirOwner(metamodel.owner);
282
+ }
252
283
  metamodel.accessPointGroups.forEach(observe_APG);
253
284
  return metamodel;
254
285
  },
@@ -60,6 +60,7 @@ export class QueryDataProductModelAccessExecutionContext extends QueryDataProduc
60
60
 
61
61
  export class QueryDataProductLakehouseExecutionContext extends QueryDataProductExecutionContext {
62
62
  accessPointId!: string;
63
+ accessGroupId!: string;
63
64
  }
64
65
 
65
66
  export interface QueryGridConfig {
@@ -184,6 +185,7 @@ export class QueryDataProductModelAccessExecutionContextInfo extends QueryExecut
184
185
  export class QueryDataProductLakehouseExecutionContextInfo extends QueryExecutionContextInfo {
185
186
  dataProductPath!: string;
186
187
  accessPointId!: string;
188
+ accessGroupId!: string;
187
189
  }
188
190
 
189
191
  export interface QueryInfo {
@@ -381,8 +381,10 @@ import {
381
381
  DataProductAnalysis,
382
382
  } from '../../../action/analytics/data-product/DataProductAnalysis.js';
383
383
  import {
384
+ AccessPointGroup,
384
385
  DataProductAccessType,
385
386
  DataProductElementScope,
387
+ LakehouseAccessPoint,
386
388
  ModelAccessPointGroup,
387
389
  NativeModelAccess,
388
390
  NativeModelExecutionContext,
@@ -3760,46 +3762,222 @@ export class V1_PureGraphManager extends AbstractPureGraphManager {
3760
3762
  dataProductAccessType: DataProductAccessType,
3761
3763
  projectInfo: ProjectGAVCoordinates,
3762
3764
  graphReport?: GraphManagerOperationReport,
3765
+ ): Promise<DataProductAnalysisQueryResult> {
3766
+ switch (dataProductAccessType) {
3767
+ case DataProductAccessType.MODEL:
3768
+ return this.buildModelAccessDataProductAnalysis(
3769
+ artifact,
3770
+ dataProductPath,
3771
+ pureGraph,
3772
+ accessPointId,
3773
+ projectInfo,
3774
+ graphReport,
3775
+ );
3776
+ case DataProductAccessType.NATIVE:
3777
+ return this.buildNativeAccessDataProductAnalysis(
3778
+ artifact,
3779
+ dataProductPath,
3780
+ pureGraph,
3781
+ accessPointId,
3782
+ projectInfo,
3783
+ graphReport,
3784
+ );
3785
+ case DataProductAccessType.LAKEHOUSE:
3786
+ return this.buildLakehouseAccessDataProductAnalysis(
3787
+ artifact,
3788
+ dataProductPath,
3789
+ pureGraph,
3790
+ accessPointId,
3791
+ projectInfo,
3792
+ graphReport,
3793
+ );
3794
+ default:
3795
+ throw new UnsupportedOperationError(
3796
+ `Unsupported data product access type: '${dataProductAccessType}'`,
3797
+ );
3798
+ }
3799
+ }
3800
+
3801
+ private async buildModelAccessDataProductAnalysis(
3802
+ artifact: V1_DataProductArtifact,
3803
+ dataProductPath: string,
3804
+ pureGraph: PureModel,
3805
+ accessPointId: string,
3806
+ projectInfo: ProjectGAVCoordinates,
3807
+ graphReport?: GraphManagerOperationReport,
3763
3808
  ): Promise<DataProductAnalysisQueryResult> {
3764
3809
  const modelAccessPointGroups = artifact.accessPointGroups.filter(
3765
3810
  (group): group is V1_ModelAccessPointGroupInfo =>
3766
3811
  group instanceof V1_ModelAccessPointGroupInfo,
3767
3812
  );
3768
-
3769
- // Resolve the target access group and mapping path
3770
- let mappingPath: string | undefined;
3771
- let accessGroup:
3772
- | V1_ModelAccessPointGroupInfo
3773
- | V1_NativeModelExecutionContextInfo
3774
- | undefined = undefined;
3775
- if (dataProductAccessType === DataProductAccessType.MODEL) {
3776
- const group = modelAccessPointGroups.find((g) => g.id === accessPointId);
3777
- if (group) {
3778
- mappingPath = group.mappingGeneration.path;
3779
- accessGroup = group;
3780
- }
3781
- } else if (dataProductAccessType === DataProductAccessType.NATIVE) {
3782
- const nativeCtx =
3783
- artifact.nativeModelAccess?.nativeModelExecutionContexts.find(
3784
- (ctx) => ctx.key === accessPointId,
3785
- );
3786
- if (nativeCtx) {
3787
- mappingPath = nativeCtx.mapping;
3788
- accessGroup = nativeCtx;
3789
- }
3790
- }
3813
+ const accessGroup = modelAccessPointGroups.find(
3814
+ (g) => g.id === accessPointId,
3815
+ );
3791
3816
  if (!accessGroup) {
3792
3817
  throw new Error(
3793
- `Can't resolve access point '${accessPointId}' (type: ${dataProductAccessType}) in data product '${dataProductPath}'`,
3818
+ `Can't resolve access point '${accessPointId}' (type: ${DataProductAccessType.MODEL}) in data product '${dataProductPath}'`,
3819
+ );
3820
+ }
3821
+ const mappingPath = accessGroup.mappingGeneration.path;
3822
+
3823
+ return this.buildDataProductAnalysisCore(
3824
+ artifact,
3825
+ dataProductPath,
3826
+ pureGraph,
3827
+ mappingPath,
3828
+ accessGroup,
3829
+ undefined, // no resolved runtime path for MODEL access
3830
+ projectInfo,
3831
+ graphReport,
3832
+ );
3833
+ }
3834
+
3835
+ private async buildNativeAccessDataProductAnalysis(
3836
+ artifact: V1_DataProductArtifact,
3837
+ dataProductPath: string,
3838
+ pureGraph: PureModel,
3839
+ accessPointId: string,
3840
+ projectInfo: ProjectGAVCoordinates,
3841
+ graphReport?: GraphManagerOperationReport,
3842
+ ): Promise<DataProductAnalysisQueryResult> {
3843
+ const nativeCtx =
3844
+ artifact.nativeModelAccess?.nativeModelExecutionContexts.find(
3845
+ (ctx) => ctx.key === accessPointId,
3846
+ );
3847
+ if (!nativeCtx) {
3848
+ throw new Error(
3849
+ `Can't resolve access point '${accessPointId}' (type: ${DataProductAccessType.NATIVE}) in data product '${dataProductPath}'`,
3794
3850
  );
3795
3851
  }
3852
+ const mappingPath = nativeCtx.mapping;
3796
3853
  if (!mappingPath) {
3797
3854
  throw new Error(
3798
- `Can't resolve mapping path '${mappingPath}' for access point '${accessPointId}' (type: ${dataProductAccessType}) in data product '${dataProductPath}'`,
3855
+ `Can't resolve mapping path for access point '${accessPointId}' (type: ${DataProductAccessType.NATIVE}) in data product '${dataProductPath}'`,
3799
3856
  );
3800
3857
  }
3801
3858
 
3802
- // prevent refetching artifact
3859
+ // Resolve runtime path for the native context
3860
+ const resolvedRuntimePath = nativeCtx.runtimeGeneration?.path;
3861
+
3862
+ return this.buildDataProductAnalysisCore(
3863
+ artifact,
3864
+ dataProductPath,
3865
+ pureGraph,
3866
+ mappingPath,
3867
+ nativeCtx,
3868
+ resolvedRuntimePath,
3869
+ projectInfo,
3870
+ graphReport,
3871
+ );
3872
+ }
3873
+
3874
+ private async buildLakehouseAccessDataProductAnalysis(
3875
+ artifact: V1_DataProductArtifact,
3876
+ dataProductPath: string,
3877
+ pureGraph: PureModel,
3878
+ accessPointId: string,
3879
+ projectInfo: ProjectGAVCoordinates,
3880
+ graphReport?: GraphManagerOperationReport,
3881
+ ): Promise<DataProductAnalysisQueryResult> {
3882
+ // Create a dummy data product element
3883
+ const dummyDataProduct = new V1_DataProduct();
3884
+ dummyDataProduct.package =
3885
+ extractPackagePathFromPath(dataProductPath) ?? '';
3886
+ dummyDataProduct.name = extractElementNameFromPath(dataProductPath);
3887
+ dummyDataProduct.title = artifact.dataProduct.title;
3888
+ dummyDataProduct.description = artifact.dataProduct.description;
3889
+
3890
+ // Build graph with only the data product
3891
+ const graphEntities = [dummyDataProduct]
3892
+ .filter((el) => !pureGraph.getNullableElement(el.path, false))
3893
+ .map((el) => this.elementProtocolToEntity(el));
3894
+ await this.buildGraph(
3895
+ pureGraph,
3896
+ graphEntities,
3897
+ ActionState.create(),
3898
+ {
3899
+ origin: new LegendSDLC(
3900
+ projectInfo.groupId,
3901
+ projectInfo.artifactId,
3902
+ projectInfo.versionId,
3903
+ ),
3904
+ },
3905
+ graphReport,
3906
+ );
3907
+
3908
+ const data = pureGraph.getDataProduct(dataProductPath);
3909
+
3910
+ // Create access point groups with LakehouseAccessPoints from artifact data
3911
+ data.accessPointGroups = artifact.accessPointGroups
3912
+ .filter(
3913
+ (groupInfo) => !(groupInfo instanceof V1_ModelAccessPointGroupInfo),
3914
+ )
3915
+ .map((groupInfo) => {
3916
+ const apGroup = new AccessPointGroup();
3917
+ apGroup.id = groupInfo.id;
3918
+ apGroup.description = groupInfo.description;
3919
+ apGroup.accessPoints = groupInfo.accessPointImplementations.map(
3920
+ (apImpl) => {
3921
+ const lakehouseAP = new LakehouseAccessPoint(
3922
+ apImpl.id,
3923
+ '', // targetEnvironment is not available in the artifact
3924
+ new RawLambda(undefined, undefined),
3925
+ apGroup,
3926
+ );
3927
+ lakehouseAP.description = apImpl.description;
3928
+ return lakehouseAP;
3929
+ },
3930
+ );
3931
+ return apGroup;
3932
+ });
3933
+
3934
+ // Find the lakehouse access point matching the requested id
3935
+ const lakehouseResult = data.accessPointGroups
3936
+ .flatMap((group) => group.accessPoints)
3937
+ .find(
3938
+ (ap): ap is LakehouseAccessPoint =>
3939
+ ap instanceof LakehouseAccessPoint && ap.id === accessPointId,
3940
+ );
3941
+ if (!lakehouseResult) {
3942
+ throw new Error(
3943
+ `Can't resolve lakehouse access point '${accessPointId}' in data product '${dataProductPath}'`,
3944
+ );
3945
+ }
3946
+
3947
+ const result = new DataProductAnalysis();
3948
+ result.path = dataProductPath;
3949
+ result.title = artifact.dataProduct.title;
3950
+ result.description = artifact.dataProduct.description;
3951
+
3952
+ return new DataProductAnalysisQueryResult(
3953
+ undefined,
3954
+ result,
3955
+ lakehouseResult,
3956
+ );
3957
+ }
3958
+
3959
+ /**
3960
+ * Shared core logic for building data product analysis after the access type
3961
+ * specific resolution has been performed.
3962
+ */
3963
+ private async buildDataProductAnalysisCore(
3964
+ artifact: V1_DataProductArtifact,
3965
+ dataProductPath: string,
3966
+ pureGraph: PureModel,
3967
+ mappingPath: string,
3968
+ accessGroup:
3969
+ | V1_ModelAccessPointGroupInfo
3970
+ | V1_NativeModelExecutionContextInfo,
3971
+ resolvedRuntimePath: string | undefined,
3972
+ projectInfo: ProjectGAVCoordinates,
3973
+ graphReport?: GraphManagerOperationReport,
3974
+ ): Promise<DataProductAnalysisQueryResult> {
3975
+ const modelAccessPointGroups = artifact.accessPointGroups.filter(
3976
+ (group): group is V1_ModelAccessPointGroupInfo =>
3977
+ group instanceof V1_ModelAccessPointGroupInfo,
3978
+ );
3979
+
3980
+ // Collect mapping generation infos from all sources
3803
3981
  const includedGenInfos = new Map<string, V1_MappingGenerationInfo>();
3804
3982
 
3805
3983
  if (artifact.nativeModelAccess?.mappingGenerations) {
@@ -3834,10 +4012,6 @@ export class V1_PureGraphManager extends AbstractPureGraphManager {
3834
4012
  resolvedMappingStub.name = extractElementNameFromPath(mappingPath);
3835
4013
 
3836
4014
  // Only add a runtime stub for the resolved native context (if applicable)
3837
- const resolvedRuntimePath =
3838
- dataProductAccessType === DataProductAccessType.NATIVE
3839
- ? nativeRuntimePaths.get(accessPointId)
3840
- : undefined;
3841
4015
  let resolvedRuntimeStub: V1_PackageableRuntime | undefined;
3842
4016
  if (resolvedRuntimePath) {
3843
4017
  resolvedRuntimeStub = new V1_PackageableRuntime();
@@ -3848,8 +4022,6 @@ export class V1_PureGraphManager extends AbstractPureGraphManager {
3848
4022
  resolvedRuntimeStub.runtimeValue = new V1_EngineRuntime();
3849
4023
  }
3850
4024
 
3851
- // Create a dummy data product element
3852
-
3853
4025
  // Create a dummy data product element
3854
4026
  const dummyDataProduct = new V1_DataProduct();
3855
4027
  dummyDataProduct.package =
@@ -4499,6 +4671,21 @@ export class V1_PureGraphManager extends AbstractPureGraphManager {
4499
4671
  );
4500
4672
  }
4501
4673
 
4674
+ async checkServiceRegisteredByPattern(
4675
+ serviceServerUrl: string,
4676
+ servicePattern: string,
4677
+ ): Promise<boolean> {
4678
+ try {
4679
+ await this.engine.getServiceMetadataByPattern(
4680
+ serviceServerUrl,
4681
+ servicePattern,
4682
+ );
4683
+ return true;
4684
+ } catch {
4685
+ return false;
4686
+ }
4687
+ }
4688
+
4502
4689
  async runServicePostValidations(
4503
4690
  service: Service,
4504
4691
  graph: PureModel,
@@ -229,6 +229,7 @@ export const V1_buildExecutionContext = (
229
229
  const exec = new QueryDataProductLakehouseExecutionContext();
230
230
  exec.dataProductPath = protocolExecContext.dataProductPath;
231
231
  exec.accessPointId = protocolExecContext.accessPointId;
232
+ exec.accessGroupId = protocolExecContext.accessGroupId;
232
233
  return exec;
233
234
  }
234
235
  throw new UnsupportedOperationError('Unsupported query execution context');
@@ -279,6 +280,7 @@ export const V1_buildExecutionContextInfo = (
279
280
  const exec = new QueryDataProductLakehouseExecutionContextInfo();
280
281
  exec.dataProductPath = v1_execContext.dataProductPath;
281
282
  exec.accessPointId = v1_execContext.accessPointId;
283
+ exec.accessGroupId = v1_execContext.accessGroupId;
282
284
  return exec;
283
285
  }
284
286
  throw new UnsupportedOperationError('Unsupported query execution context');
@@ -403,6 +405,7 @@ export const V1_transformQueryExecutionContext = (
403
405
  const protocol = new V1_DataProductLakehouseExecutionContext();
404
406
  protocol.dataProductPath = execContext.dataProductPath;
405
407
  protocol.accessPointId = execContext.accessPointId;
408
+ protocol.accessGroupId = execContext.accessGroupId;
406
409
  return protocol;
407
410
  }
408
411
  throw new UnsupportedOperationError('Unsupported query execution context');
@@ -121,6 +121,7 @@ enum CORE_ENGINE_ACTIVITY_TRACE {
121
121
  REGISTER_SERVICE = 'register service',
122
122
  GET_SERVICE_VERSION = 'get service version',
123
123
  ACTIVATE_SERVICE_GENERATION_ID = 'activate service generation id',
124
+ GET_SERVICE_METADATA = 'get service metadata',
124
125
  VALIDATE_SERVICE_ASSERTION_ID = 'validate service assertion id',
125
126
  RUN_SERVICE_TESTS = 'run service tests',
126
127
  GENERATE_TEST_DATA_WITH_DEFAULT_SEED = 'generate test data with default seed',
@@ -1240,6 +1241,17 @@ export class V1_EngineServerClient extends AbstractServerClient {
1240
1241
  request,
1241
1242
  );
1242
1243
 
1244
+ getServiceMetadataByPattern = (
1245
+ serviceServerUrl: string,
1246
+ servicePattern: string,
1247
+ ): Promise<PlainObject> =>
1248
+ this.getWithTracing(
1249
+ this.getTraceData(CORE_ENGINE_ACTIVITY_TRACE.GET_SERVICE_METADATA),
1250
+ `${this._service(
1251
+ this.baseUrlForServiceRegistration ?? serviceServerUrl,
1252
+ )}/serviceMetadata/${encodeURIComponent(servicePattern)}`,
1253
+ );
1254
+
1243
1255
  // ------------------------------------------- Legend Services List -------------------------------------------
1244
1256
 
1245
1257
  private readonly getServicesDetailsFromCache = (): Promise<PlainObject[]> =>
@@ -328,6 +328,11 @@ export interface V1_GraphManagerEngine {
328
328
  generationId: string,
329
329
  ) => Promise<void>;
330
330
 
331
+ getServiceMetadataByPattern: (
332
+ serviceServerUrl: string,
333
+ servicePattern: string,
334
+ ) => Promise<PlainObject>;
335
+
331
336
  runServicePostVal: (
332
337
  servicePath: string,
333
338
  input: V1_PureModelContext,
@@ -1142,6 +1142,16 @@ export class V1_RemoteEngine implements V1_GraphManagerEngine {
1142
1142
  );
1143
1143
  }
1144
1144
 
1145
+ async getServiceMetadataByPattern(
1146
+ serviceServerUrl: string,
1147
+ servicePattern: string,
1148
+ ): Promise<PlainObject> {
1149
+ return this.engineServerClient.getServiceMetadataByPattern(
1150
+ serviceServerUrl,
1151
+ servicePattern,
1152
+ );
1153
+ }
1154
+
1145
1155
  async runServicePostVal(
1146
1156
  servicePath: string,
1147
1157
  input: V1_PureModelContext,
@@ -67,7 +67,7 @@ export enum V1_QueryExecutionContextType {
67
67
  QUERY_DATASAPCE_EXECUTION_CONTEXT = 'dataSpaceExecutionContext',
68
68
  QUERY_DATAPRODUCT_NATIVE_EXECUTION_CONTEXT = 'dataProductNativeExecutionContext',
69
69
  QUERY_DATAPRODUCT_MODEL_ACCESS_EXECUTION_CONTEXT = 'dataProductModelAccessExecutionContext',
70
- QUERY_DATAPRODUCT_LAKEHOUSE_EXECUTION_CONTEXT = 'dataProductLakehouseExecutionContext',
70
+ QUERY_DATAPRODUCT_LAKEHOUSE_EXECUTION_CONTEXT = 'dataProductLakehouseAccessExecutionContext',
71
71
  }
72
72
 
73
73
  export class V1_QueryExplicitExecutionContext extends V1_QueryExecutionContext {
@@ -146,6 +146,7 @@ export class V1_DataProductModelAccessExecutionContext extends V1_QueryDataProdu
146
146
 
147
147
  export class V1_DataProductLakehouseExecutionContext extends V1_QueryDataProductExecutionContext {
148
148
  accessPointId!: string;
149
+ accessGroupId!: string;
149
150
 
150
151
  static readonly serialization = new SerializationFactory(
151
152
  createModelSchema(V1_DataProductLakehouseExecutionContext, {
@@ -154,6 +155,7 @@ export class V1_DataProductLakehouseExecutionContext extends V1_QueryDataProduct
154
155
  ),
155
156
  dataProductPath: primitive(),
156
157
  accessPointId: primitive(),
158
+ accessGroupId: primitive(),
157
159
  }),
158
160
  {
159
161
  deserializeNullAsUndefined: true,
@@ -14,8 +14,16 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import type { PlainObject } from '@finos/legend-shared';
17
+ import {
18
+ hashArray,
19
+ type Hashable,
20
+ type PlainObject,
21
+ } from '@finos/legend-shared';
18
22
  import type { V1_StereotypePtr } from '../../model/packageableElements/domain/V1_StereotypePtr.js';
23
+ import { AppDirLevel } from '../../../../../../graph/metamodel/pure/packageableElements/ingest/IngestDefinition.js';
24
+ import { CORE_HASH_STRUCTURE } from '../../../../../../graph/Core_HashUtils.js';
25
+
26
+ export { AppDirLevel as V1_AppDirLevel };
19
27
 
20
28
  // ---------------------------------------- Users & App Directory --------------------------------------
21
29
 
@@ -29,17 +37,17 @@ export enum V1_UserType {
29
37
  SYSTEM_ACCOUNT = 'SYSTEM_ACCOUNT',
30
38
  }
31
39
 
32
- export class V1_AppDirNode {
40
+ export class V1_AppDirNode implements Hashable {
33
41
  appDirId!: number;
34
- level!: V1_AppDirLevel;
35
- }
36
-
37
- export enum V1_AppDirLevel {
38
- BUSINESS_UNIT = 'BUSINESS_UNIT',
39
- SUB_BUSINESS_UNIT = 'SUB_BUSINESS_UNIT',
40
- FAMILY = 'FAMILY',
41
- APPLICATION = 'APPLICATION',
42
- DEPLOYMENT = 'DEPLOYMENT',
42
+ level!: AppDirLevel;
43
+
44
+ get hashCode(): string {
45
+ return hashArray([
46
+ CORE_HASH_STRUCTURE.APP_DIR_NODE,
47
+ this.appDirId.toString(),
48
+ this.level,
49
+ ]);
50
+ }
43
51
  }
44
52
 
45
53
  // -------------------------------------------- Pagination ---------------------------------------------
@@ -33,6 +33,7 @@ import {
33
33
  import type { V1_StereotypePtr } from '../domain/V1_StereotypePtr.js';
34
34
  import type { V1_TaggedValue } from '../domain/V1_TaggedValue.js';
35
35
  import type { V1_EmbeddedData } from '../../data/V1_EmbeddedData.js';
36
+ import type { V1_AppDirNode } from '../../../lakehouse/entitlements/V1_CoreEntitlements.js';
36
37
 
37
38
  export const V1_DATA_PRODUCT_ELEMENT_PROTOCOL_TYPE = 'dataProduct';
38
39
 
@@ -369,12 +370,9 @@ export abstract class V1_DataProductType implements Hashable {
369
370
  }
370
371
  }
371
372
 
372
- export class V1_InternalDataProductType extends V1_DataProductType {
373
- _type = V1_DataProductTypeValue.INTERNAL;
374
- }
373
+ export class V1_InternalDataProductType extends V1_DataProductType {}
375
374
 
376
375
  export class V1_ExternalDataProductType extends V1_DataProductType {
377
- _type = V1_DataProductTypeValue.EXTERNAL;
378
376
  link!: V1_DataProductLink;
379
377
 
380
378
  override get hashCode(): string {
@@ -409,6 +407,27 @@ export class V1_DataProductOperationalMetadata implements Hashable {
409
407
  }
410
408
  }
411
409
 
410
+ export enum V1_DataProductOwnerType {
411
+ APP_DIR = 'appDir',
412
+ }
413
+
414
+ export abstract class V1_DataProductOwner implements Hashable {
415
+ abstract get hashCode(): string;
416
+ }
417
+
418
+ export class V1_AppDirOwner extends V1_DataProductOwner implements Hashable {
419
+ production: V1_AppDirNode | undefined;
420
+ prodParallel: V1_AppDirNode | undefined;
421
+
422
+ override get hashCode(): string {
423
+ return hashArray([
424
+ CORE_HASH_STRUCTURE.DATA_PRODUCT_OWNER,
425
+ this.production?.hashCode ?? '',
426
+ this.prodParallel?.hashCode ?? '',
427
+ ]);
428
+ }
429
+ }
430
+
412
431
  export class V1_DataProduct extends V1_PackageableElement implements Hashable {
413
432
  title: string | undefined;
414
433
  description: string | undefined;
@@ -421,6 +440,7 @@ export class V1_DataProduct extends V1_PackageableElement implements Hashable {
421
440
  taggedValues: V1_TaggedValue[] = [];
422
441
  sampleValues: V1_EmbeddedData[] | undefined;
423
442
  operationalMetadata: V1_DataProductOperationalMetadata | undefined;
443
+ owner: V1_DataProductOwner | undefined;
424
444
 
425
445
  override get hashCode(): string {
426
446
  return hashArray([
@@ -436,6 +456,7 @@ export class V1_DataProduct extends V1_PackageableElement implements Hashable {
436
456
  hashArray(this.taggedValues),
437
457
  hashArray(this.sampleValues ?? []),
438
458
  this.operationalMetadata ?? '',
459
+ this.owner ?? '',
439
460
  ]);
440
461
  }
441
462
 
@@ -30,6 +30,7 @@ import {
30
30
  FunctionAccessPoint,
31
31
  PackageableElementSampleQuery,
32
32
  InLineSampleQuery,
33
+ AppDirOwner,
33
34
  } from '../../../../../../../graph/metamodel/pure/dataProduct/DataProduct.js';
34
35
  import {
35
36
  type V1_AccessPoint,
@@ -57,6 +58,7 @@ import {
57
58
  V1_PackageableElementSampleQuery,
58
59
  V1_InLineSampleQuery,
59
60
  V1_NativeModelExecutionContext,
61
+ V1_AppDirOwner,
60
62
  } from '../../../model/packageableElements/dataProduct/V1_DataProduct.js';
61
63
  import { V1_initPackageableElement } from './V1_CoreTransformerHelper.js';
62
64
  import { V1_transformRawLambda } from './V1_RawValueSpecificationTransformer.js';
@@ -69,6 +71,7 @@ import { V1_PackageableElementPointer } from '../../../model/packageableElements
69
71
  import { V1_transformEmbeddedData } from './V1_DataElementTransformer.js';
70
72
  import { ConcreteFunctionDefinition } from '../../../../../../../graph/metamodel/pure/packageableElements/function/ConcreteFunctionDefinition.js';
71
73
  import { generateFunctionPrettyName } from '../../../../../../../graph/helpers/PureLanguageHelper.js';
74
+ import { V1_AppDirNode } from '../../../lakehouse/entitlements/V1_CoreEntitlements.js';
72
75
 
73
76
  const transformAccessPoint = (
74
77
  ap: AccessPoint,
@@ -343,5 +346,26 @@ export const V1_transformDataProduct = (
343
346
  V1_transformTaggedValue(taggedValue),
344
347
  );
345
348
 
349
+ if (element.owner instanceof AppDirOwner) {
350
+ const v1Owner = new V1_AppDirOwner();
351
+ if (element.owner.production) {
352
+ const v1Node = new V1_AppDirNode();
353
+ v1Node.appDirId = element.owner.production.appDirId;
354
+ v1Node.level = element.owner.production.level;
355
+ v1Owner.production = v1Node;
356
+ }
357
+ if (element.owner.prodParallel) {
358
+ const v1Node = new V1_AppDirNode();
359
+ v1Node.appDirId = element.owner.prodParallel.appDirId;
360
+ v1Node.level = element.owner.prodParallel.level;
361
+ v1Owner.prodParallel = v1Node;
362
+ }
363
+ product.owner = v1Owner;
364
+ } else if (element.owner !== undefined) {
365
+ throw new UnsupportedOperationError(
366
+ `Unable to transform data product owner`,
367
+ );
368
+ }
369
+
346
370
  return product;
347
371
  };