@finos/legend-extension-dsl-data-quality 2.0.174 → 2.1.1

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 (24) hide show
  1. package/lib/components/DataQualityRelationValidationConfigurationEditor.d.ts.map +1 -1
  2. package/lib/components/DataQualityRelationValidationConfigurationEditor.js +27 -13
  3. package/lib/components/DataQualityRelationValidationConfigurationEditor.js.map +1 -1
  4. package/lib/components/states/DataQualityRelationResultState.js +1 -1
  5. package/lib/components/states/DataQualityRelationResultState.js.map +1 -1
  6. package/lib/components/states/DataQualityRelationValidationConfigurationState.d.ts +14 -10
  7. package/lib/components/states/DataQualityRelationValidationConfigurationState.d.ts.map +1 -1
  8. package/lib/components/states/DataQualityRelationValidationConfigurationState.js +64 -55
  9. package/lib/components/states/DataQualityRelationValidationConfigurationState.js.map +1 -1
  10. package/lib/graph-manager/protocol/pure/DSL_DataQuality_PureGraphManagerExtension.d.ts +2 -0
  11. package/lib/graph-manager/protocol/pure/DSL_DataQuality_PureGraphManagerExtension.d.ts.map +1 -1
  12. package/lib/graph-manager/protocol/pure/DSL_DataQuality_PureGraphManagerExtension.js.map +1 -1
  13. package/lib/graph-manager/protocol/pure/v1/V1_DSL_Data_Quality_PureGraphManagerExtension.d.ts +3 -0
  14. package/lib/graph-manager/protocol/pure/v1/V1_DSL_Data_Quality_PureGraphManagerExtension.d.ts.map +1 -1
  15. package/lib/graph-manager/protocol/pure/v1/V1_DSL_Data_Quality_PureGraphManagerExtension.js +45 -0
  16. package/lib/graph-manager/protocol/pure/v1/V1_DSL_Data_Quality_PureGraphManagerExtension.js.map +1 -1
  17. package/lib/index.css +1 -1
  18. package/lib/package.json +1 -1
  19. package/package.json +11 -11
  20. package/src/components/DataQualityRelationValidationConfigurationEditor.tsx +53 -19
  21. package/src/components/states/DataQualityRelationResultState.ts +1 -1
  22. package/src/components/states/DataQualityRelationValidationConfigurationState.ts +81 -71
  23. package/src/graph-manager/protocol/pure/DSL_DataQuality_PureGraphManagerExtension.ts +12 -0
  24. package/src/graph-manager/protocol/pure/v1/V1_DSL_Data_Quality_PureGraphManagerExtension.ts +111 -0
@@ -79,6 +79,11 @@ export enum DATA_QUALITY_RELATION_VALIDATION_EDITOR_TAB {
79
79
  TRIAL_RUN = 'Trial Run',
80
80
  }
81
81
 
82
+ export enum EXECUTION_TYPE {
83
+ EXECUTION = 'EXECUTION',
84
+ PROFILING = 'PROFILING',
85
+ }
86
+
82
87
  export class RelationFunctionDefinitionEditorState extends LambdaEditorState {
83
88
  readonly editorStore: EditorStore;
84
89
  readonly relationValidationElement: DataQualityRelationValidationConfiguration;
@@ -211,15 +216,11 @@ export class RelationDefinitionParameterState extends LambdaParametersState {
211
216
  relationValidationConfigurationState;
212
217
  }
213
218
 
214
- openModal(lambda: RawLambda, runLambdaWithConstraints: boolean): void {
219
+ openModal(lambda: RawLambda, onSubmit: () => GeneratorFn<void>): void {
215
220
  this.parameterStates = this.build(lambda);
216
221
  this.parameterValuesEditorState.open(
217
222
  (): Promise<void> =>
218
- flowResult(
219
- runLambdaWithConstraints
220
- ? this.relationValidationConfigurationState.resultState.runValidation()
221
- : this.relationValidationConfigurationState.runValidation(),
222
- ).catch(
223
+ flowResult(onSubmit()).catch(
223
224
  this.relationValidationConfigurationState.editorStore.applicationStore
224
225
  .alertUnhandledError,
225
226
  ),
@@ -258,10 +259,11 @@ export class DataQualityRelationValidationConfigurationState extends ElementEdit
258
259
  readonly exportState = ActionState.create();
259
260
  selectedTab: DATA_QUALITY_RELATION_VALIDATION_EDITOR_TAB;
260
261
 
261
- isRunningValidation = false;
262
+ lastExecutionType: EXECUTION_TYPE | undefined = undefined;
263
+ currentExecutionType: EXECUTION_TYPE | undefined = undefined;
262
264
  isGeneratingPlan = false;
263
- validationRunPromise: Promise<ExecutionResult> | undefined = undefined;
264
- executionResult?: ExecutionResult | undefined; // NOTE: stored as lossless JSON string
265
+ runPromise: Promise<ExecutionResult> | undefined = undefined;
266
+ executionResult?: ExecutionResult | undefined;
265
267
  executionPlanState: ExecutionPlanState;
266
268
  validationStates: DataQualityRelationValidationState[] = [];
267
269
  parametersState: RelationDefinitionParameterState;
@@ -278,14 +280,15 @@ export class DataQualityRelationValidationConfigurationState extends ElementEdit
278
280
 
279
281
  makeObservable(this, {
280
282
  selectedTab: observable,
281
- isRunningValidation: observable,
282
- validationRunPromise: observable,
283
+ currentExecutionType: observable,
284
+ runPromise: observable,
283
285
  executionResult: observable,
284
286
  resultState: observable,
285
287
  executionDuration: observable,
286
288
  latestRunHashCode: observable,
289
+ lastExecutionType: observable,
287
290
  setSelectedTab: action,
288
- setValidationRunPromise: action,
291
+ setRunPromise: action,
289
292
  setExecutionResult: action,
290
293
  addValidationState: action,
291
294
  resetResultState: action,
@@ -293,13 +296,15 @@ export class DataQualityRelationValidationConfigurationState extends ElementEdit
293
296
  validationElement: computed,
294
297
  relationValidationOptions: computed,
295
298
  checkForStaleResults: computed,
296
- runValidation: flow,
297
- handleRunValidation: flow,
299
+ isRunning: computed,
300
+ run: flow,
301
+ handleRun: flow,
302
+ exportData: flow,
298
303
  convertValidationLambdaObjects: flow,
299
- cancelValidationRun: flow,
304
+ cancelRun: flow,
300
305
  generatePlan: flow,
301
- exportData: flow,
302
306
  });
307
+
303
308
  assertType(
304
309
  element,
305
310
  DataQualityRelationValidationConfiguration,
@@ -378,6 +383,10 @@ export class DataQualityRelationValidationConfigurationState extends ElementEdit
378
383
  return false;
379
384
  }
380
385
 
386
+ get isRunning(): boolean {
387
+ return this.currentExecutionType !== undefined;
388
+ }
389
+
381
390
  setExecutionDuration(val: number | undefined): void {
382
391
  this.executionDuration = val;
383
392
  }
@@ -407,30 +416,32 @@ export class DataQualityRelationValidationConfigurationState extends ElementEdit
407
416
  }
408
417
  }
409
418
 
410
- setValidationRunPromise = (
411
- promise: Promise<ExecutionResult> | undefined,
412
- ): void => {
413
- this.validationRunPromise = promise;
419
+ setRunPromise = (promise: Promise<ExecutionResult> | undefined): void => {
420
+ this.runPromise = promise;
414
421
  };
415
422
 
416
423
  setSelectedTab(tab: DATA_QUALITY_RELATION_VALIDATION_EDITOR_TAB): void {
417
424
  this.selectedTab = tab;
418
425
  }
419
426
 
420
- setExecutionResult = (executionResult: ExecutionResult | undefined): void => {
427
+ setExecutionResult = (
428
+ executionResult: ExecutionResult | undefined,
429
+ type: EXECUTION_TYPE,
430
+ ): void => {
431
+ this.lastExecutionType = type;
421
432
  this.executionResult = executionResult;
422
433
  };
423
434
 
424
- *handleRunValidation(): GeneratorFn<void> {
425
- if (this.isRunningValidation) {
435
+ *handleRun(type: EXECUTION_TYPE): GeneratorFn<void> {
436
+ if (this.isRunning) {
426
437
  return;
427
438
  }
428
439
  const queryLambda = this.bodyExpressionSequence;
429
440
  const parameters = (queryLambda.parameters ?? []) as object[];
430
441
  if (parameters.length) {
431
- this.parametersState.openModal(queryLambda, false);
442
+ this.parametersState.openModal(queryLambda, () => this.run(type));
432
443
  } else {
433
- flowResult(this.runValidation()).catch(
444
+ flowResult(this.run(type)).catch(
434
445
  this.editorStore.applicationStore.alertUnhandledError,
435
446
  );
436
447
  }
@@ -484,41 +495,45 @@ export class DataQualityRelationValidationConfigurationState extends ElementEdit
484
495
  );
485
496
  }
486
497
 
487
- setIsRunningValidation(val: boolean): void {
488
- this.isRunningValidation = val;
489
- }
490
-
491
- *runValidation(): GeneratorFn<void> {
492
- let promise;
498
+ *run(type: EXECUTION_TYPE): GeneratorFn<void> {
499
+ let promise: Promise<ExecutionResult> | undefined = undefined;
500
+ const stopWatch = new StopWatch();
493
501
  try {
494
- this.setIsRunningValidation(true);
502
+ this.currentExecutionType = type;
495
503
  const currentHashCode = this.hashCode;
496
504
  const packagePath = this.validationElement.path;
497
505
  const model = this.editorStore.graphManagerState.graph;
498
- const stopWatch = new StopWatch();
499
-
500
- promise = getDataQualityPureGraphManagerExtension(
506
+ const extension = getDataQualityPureGraphManagerExtension(
501
507
  this.editorStore.graphManagerState.graphManager,
502
- ).execute(model, packagePath, {
503
- runQuery: true,
508
+ );
509
+
510
+ const options = {
504
511
  lambdaParameterValues: buildExecutionParameterValues(
505
512
  this.parametersState.parameterStates,
506
513
  this.editorStore.graphManagerState,
507
514
  ),
508
- });
515
+ };
516
+
517
+ promise =
518
+ type === EXECUTION_TYPE.PROFILING
519
+ ? extension.runDataProfiling(model, packagePath, options)
520
+ : extension.execute(model, packagePath, {
521
+ ...options,
522
+ runQuery: true,
523
+ });
509
524
 
510
- this.setValidationRunPromise(promise);
525
+ this.setRunPromise(promise);
511
526
  const result = (yield promise) as ExecutionResult;
512
527
 
513
- if (this.validationRunPromise === promise) {
514
- this.setExecutionResult(result);
528
+ if (this.runPromise === promise) {
529
+ this.setExecutionResult(result, type);
515
530
  this.latestRunHashCode = currentHashCode;
516
531
  this.setExecutionDuration(stopWatch.elapsed);
517
532
  }
518
533
  } catch (error) {
519
- if (this.validationRunPromise === promise) {
534
+ if (this.runPromise === promise) {
520
535
  assertErrorThrown(error);
521
- this.setExecutionResult(undefined);
536
+ this.setExecutionResult(undefined, type);
522
537
  this.editorStore.applicationStore.logService.error(
523
538
  LogEvent.create(GRAPH_MANAGER_EVENT.EXECUTION_FAILURE),
524
539
  error,
@@ -528,13 +543,13 @@ export class DataQualityRelationValidationConfigurationState extends ElementEdit
528
543
  );
529
544
  }
530
545
  } finally {
531
- this.setIsRunningValidation(false);
546
+ this.currentExecutionType = undefined;
532
547
  }
533
548
  }
534
549
 
535
- *cancelValidationRun(): GeneratorFn<void> {
536
- this.setIsRunningValidation(false);
537
- this.setValidationRunPromise(undefined);
550
+ *cancelRun(): GeneratorFn<void> {
551
+ this.currentExecutionType = undefined;
552
+ this.setRunPromise(undefined);
538
553
  try {
539
554
  yield this.editorStore.graphManagerState.graphManager.cancelUserExecutions(
540
555
  true,
@@ -600,6 +615,7 @@ export class DataQualityRelationValidationConfigurationState extends ElementEdit
600
615
  *exportData(format: string): GeneratorFn<void> {
601
616
  try {
602
617
  this.exportState.inProgress();
618
+ const type = this.lastExecutionType;
603
619
  const packagePath = this.validationElement.path;
604
620
  const model = this.editorStore.graphManagerState.graph;
605
621
  this.editorStore.applicationStore.notificationService.notifySuccess(
@@ -608,16 +624,30 @@ export class DataQualityRelationValidationConfigurationState extends ElementEdit
608
624
  const exportData = this.resultState.getExportDataInfo(format);
609
625
  const contentType = exportData.contentType;
610
626
  const serializationFormat = exportData.serializationFormat;
611
- const result = (yield getDataQualityPureGraphManagerExtension(
627
+ const extension = getDataQualityPureGraphManagerExtension(
612
628
  this.editorStore.graphManagerState.graphManager,
613
- ).exportData(model, packagePath, {
629
+ );
630
+
631
+ const options = {
614
632
  serializationFormat,
615
- runQuery: true,
616
633
  lambdaParameterValues: buildExecutionParameterValues(
617
634
  this.parametersState.parameterStates,
618
635
  this.editorStore.graphManagerState,
619
636
  ),
620
- })) as Response;
637
+ };
638
+
639
+ const result =
640
+ type === EXECUTION_TYPE.PROFILING
641
+ ? ((yield extension.exportDataProfiling(
642
+ model,
643
+ packagePath,
644
+ options,
645
+ )) as Response)
646
+ : ((yield extension.exportData(model, packagePath, {
647
+ ...options,
648
+ runQuery: true,
649
+ })) as Response);
650
+
621
651
  if (result.headers.get(V1_DELEGATED_EXPORT_HEADER) === 'true') {
622
652
  if (result.status === 200) {
623
653
  this.exportState.pass();
@@ -645,26 +675,6 @@ export class DataQualityRelationValidationConfigurationState extends ElementEdit
645
675
  }
646
676
  }
647
677
 
648
- handleExport(format: string) {
649
- const queryLambda = this.bodyExpressionSequence;
650
- const parameters = (queryLambda.parameters ?? []) as object[];
651
- if (parameters.length) {
652
- this.parametersState.parameterStates =
653
- this.parametersState.build(queryLambda);
654
- this.parametersState.parameterValuesEditorState.open(
655
- (): Promise<void> =>
656
- flowResult(this.exportData(format)).catch(
657
- this.editorStore.applicationStore.alertUnhandledError,
658
- ),
659
- PARAMETER_SUBMIT_ACTION.EXPORT,
660
- );
661
- } else {
662
- flowResult(this.exportData(format)).catch(
663
- this.editorStore.applicationStore.alertUnhandledError,
664
- );
665
- }
666
- }
667
-
668
678
  get hashCode(): string {
669
679
  return hashArray([
670
680
  DATA_QUALITY_HASH_STRUCTURE.DATA_QUALITY_RELATION_VALIDATION,
@@ -32,6 +32,18 @@ export abstract class DSL_DataQuality_PureGraphManagerExtension extends Abstract
32
32
  options: DQExecuteInputOptions,
33
33
  ): Promise<RawExecutionPlan>;
34
34
 
35
+ abstract runDataProfiling(
36
+ graph: PureModel,
37
+ packagePath: string,
38
+ options: DQExecuteInputOptions,
39
+ ): Promise<ExecutionResult>;
40
+
41
+ abstract exportDataProfiling(
42
+ graph: PureModel,
43
+ packagePath: string,
44
+ options: DQExecuteInputOptions,
45
+ ): Promise<Response>;
46
+
35
47
  abstract execute(
36
48
  graph: PureModel,
37
49
  packagePath: string,
@@ -388,4 +388,115 @@ export class V1_DSL_Data_Quality_PureGraphManagerExtension extends DSL_DataQuali
388
388
  true,
389
389
  ) as DataQualityRootGraphFetchTree;
390
390
  };
391
+
392
+ private executeDataProfiling = (
393
+ input: PlainObject<V1_DQExecuteInput>,
394
+ options?: {
395
+ returnAsResponse?: boolean;
396
+ serializationFormat?: EXECUTION_SERIALIZATION_FORMAT | undefined;
397
+ },
398
+ ): Promise<PlainObject<V1_ExecutionResult> | Response> => {
399
+ const engineServerClient = guaranteeType(
400
+ this.graphManager.engine,
401
+ V1_RemoteEngine,
402
+ 'executeDataProfiling is only supported by remote engine',
403
+ ).getEngineServerClient();
404
+ return engineServerClient.postWithTracing(
405
+ engineServerClient.getTraceData(DQ_GENERATE_EXECUTION_PLAN),
406
+ `${engineServerClient._pure()}/dataquality/profile`,
407
+ input,
408
+ {},
409
+ undefined,
410
+ {
411
+ serializationFormat: options?.serializationFormat
412
+ ? V1_getEngineSerializationFormat(options.serializationFormat)
413
+ : undefined,
414
+ },
415
+ { enableCompression: true },
416
+ {
417
+ skipProcessing: Boolean(options?.returnAsResponse),
418
+ },
419
+ );
420
+ };
421
+
422
+ runDataProfiling = async (
423
+ graph: PureModel,
424
+ packagePath: string,
425
+ options: DQExecuteInputOptions,
426
+ ): Promise<ExecutionResult> => {
427
+ const input = this.createExecutionInput(
428
+ graph,
429
+ packagePath,
430
+ new V1_DQExecuteInput(),
431
+ options,
432
+ );
433
+
434
+ try {
435
+ const profilingResult = (await this.executeDataProfiling(
436
+ V1_DQExecuteInput.serialization.toJson(input),
437
+ {
438
+ returnAsResponse: true,
439
+ },
440
+ )) as Response;
441
+
442
+ const profilingResultInText = await profilingResult.text();
443
+
444
+ const rawExecutionResult =
445
+ returnUndefOnError(() =>
446
+ this.graphManager.engine.parseExecutionResults(
447
+ profilingResultInText,
448
+ undefined,
449
+ ),
450
+ ) ?? profilingResultInText;
451
+
452
+ const v1_executionResult =
453
+ V1_deserializeExecutionResult(rawExecutionResult);
454
+ return V1_buildExecutionResult(v1_executionResult);
455
+ } catch (error) {
456
+ assertErrorThrown(error);
457
+ if (error instanceof NetworkClientError) {
458
+ throw V1_buildExecutionError(
459
+ V1_ExecutionError.serialization.fromJson(
460
+ error.payload as PlainObject<V1_ExecutionError>,
461
+ ),
462
+ );
463
+ }
464
+ throw error;
465
+ }
466
+ };
467
+
468
+ exportDataProfiling = async (
469
+ graph: PureModel,
470
+ packagePath: string,
471
+ options: DQExecuteInputOptions,
472
+ ): Promise<Response> => {
473
+ const input = this.createExecutionInput(
474
+ graph,
475
+ packagePath,
476
+ new V1_DQExecuteInput(),
477
+ options,
478
+ );
479
+
480
+ try {
481
+ return guaranteeNonNullable(
482
+ (await this.executeDataProfiling(
483
+ V1_DQExecuteInput.serialization.toJson(input),
484
+ {
485
+ serializationFormat: options.serializationFormat,
486
+ returnAsResponse: true,
487
+ },
488
+ )) as Response,
489
+ );
490
+ } catch (error) {
491
+ assertErrorThrown(error);
492
+ if (error instanceof NetworkClientError) {
493
+ throw V1_buildExecutionError(
494
+ V1_ExecutionError.serialization.fromJson(
495
+ error.payload as PlainObject<V1_ExecutionError>,
496
+ ),
497
+ );
498
+ }
499
+ throw error;
500
+ }
501
+ };
391
502
  }