@finos/legend-extension-dsl-data-quality
Version:
Legend extension for Data Quality
397 lines (382 loc) • 14.3 kB
text/typescript
/**
* Copyright (c) 2020-present, Goldman Sachs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { V1_DataQualityPropertyGraphFetchTree } from '../model/graphFetch/V1_DataQualityPropertyGraphFetchTree.js';
import {
at,
guaranteeNonNullable,
UnsupportedOperationError,
} from '@finos/legend-shared';
import { V1_DataQualityRootGraphFetchTree } from '../model/graphFetch/V1_DataQualityRootGraphFetchTree.js';
import {
DataQualityPropertyGraphFetchTree,
DataQualityRootGraphFetchTree,
} from '../../../../../graph/metamodel/pure/packageableElements/data-quality/DataQualityGraphFetchTree.js';
import {
type V1_DataQualityExecutionContext,
type V1_DataQualityClassValidationsConfiguration,
type V1_DataQualityRelationValidation,
type V1_DataQualityRelationValidationsConfiguration,
type V1_DataQualityServiceValidationsConfiguration,
type V1_DataQualityRelationComparisonConfiguration,
V1_DataSpaceDataQualityExecutionContext,
V1_MappingAndRuntimeDataQualityExecutionContext,
V1_MD5HashStrategy,
} from '../V1_DataQualityValidationConfiguration.js';
import {
type DataQualityExecutionContext,
DataQualityRelationQueryLambda,
DataQualityRelationValidation,
DataSpaceDataQualityExecutionContext,
MappingAndRuntimeDataQualityExecutionContext,
MD5HashStrategy,
} from '../../../../../graph/metamodel/pure/packageableElements/data-quality/DataQualityValidationConfiguration.js';
import {
type V1_GraphBuilderContext,
type Class,
type GraphFetchTree,
type Mapping,
type PackageableElementImplicitReference,
type PackageableRuntime,
type PropertyGraphFetchTree,
type RootGraphFetchTree,
type V1_GraphFetchTree,
type V1_PropertyGraphFetchTree,
type V1_RootGraphFetchTree,
V1_ProcessingContext,
V1_buildPropertyGraphFetchTree,
V1_buildRootGraphFetchTree,
V1_buildRawLambdaWithResolvedPaths,
V1_buildFullPath,
V1_buildVariable,
} from '@finos/legend-graph';
import type { DataSpace } from '@finos/legend-extension-dsl-data-space/graph';
import {
getOwnDataQualityClassValidationsConfiguration,
getOwnDataQualityServiceValidationsConfiguration,
getOwnDataQualityRelationValidationsConfiguration,
getOwnDataQualityRelationComparisonConfiguration,
} from '../../../../DSL_DataQuality_GraphManagerHelper.js';
export function V1_buildDataQualityExecutionContext(
dataQualityExecutionContext: V1_DataQualityExecutionContext,
graphContext: V1_GraphBuilderContext,
): DataQualityExecutionContext {
if (
dataQualityExecutionContext instanceof
V1_DataSpaceDataQualityExecutionContext
) {
const dataSpaceExecutionContext =
new DataSpaceDataQualityExecutionContext();
dataSpaceExecutionContext.context = dataQualityExecutionContext.context;
dataSpaceExecutionContext.dataSpace = graphContext.resolveElement(
dataQualityExecutionContext.dataSpace.path,
false,
) as PackageableElementImplicitReference<DataSpace>;
return dataSpaceExecutionContext;
} else if (
dataQualityExecutionContext instanceof
V1_MappingAndRuntimeDataQualityExecutionContext
) {
const mappingAndRuntimeExecutionContext =
new MappingAndRuntimeDataQualityExecutionContext();
mappingAndRuntimeExecutionContext.mapping = graphContext.resolveElement(
dataQualityExecutionContext.mapping.path,
false,
) as PackageableElementImplicitReference<Mapping>;
mappingAndRuntimeExecutionContext.runtime = graphContext.resolveElement(
dataQualityExecutionContext.runtime.path,
false,
) as PackageableElementImplicitReference<PackageableRuntime>;
return mappingAndRuntimeExecutionContext;
}
throw new UnsupportedOperationError(
`Can't build data quality execution context`,
dataQualityExecutionContext,
);
}
export function V1_buildGraphFetchTree(
graphFetchTree: V1_GraphFetchTree,
context: V1_GraphBuilderContext,
parentClass: Class | undefined,
openVariables: string[],
processingContext: V1_ProcessingContext,
canResolveLocalProperty?: boolean | undefined,
): GraphFetchTree {
if (graphFetchTree instanceof V1_DataQualityPropertyGraphFetchTree) {
return V1_buildPropertyGraphFetchTree(
graphFetchTree,
context,
guaranteeNonNullable(parentClass),
openVariables,
processingContext,
canResolveLocalProperty,
);
}
if (graphFetchTree instanceof V1_DataQualityRootGraphFetchTree) {
return V1_buildRootGraphFetchTree(
graphFetchTree,
context,
openVariables,
processingContext,
canResolveLocalProperty,
);
}
throw new UnsupportedOperationError(
`Can't build graph fetch tree`,
graphFetchTree,
);
}
export function V1_buildDataQualityGraphFetchTree(
graphFetchTree: V1_GraphFetchTree,
context: V1_GraphBuilderContext,
parentClass: Class | undefined,
openVariables: string[],
processingContext: V1_ProcessingContext,
canResolveLocalProperty?: boolean | undefined,
): GraphFetchTree {
const _graphFetchTree = V1_buildGraphFetchTree(
graphFetchTree,
context,
parentClass,
openVariables,
processingContext,
canResolveLocalProperty,
);
return transformGraphFetchTreeToDataQualityGraphFetchTree(
_graphFetchTree,
graphFetchTree,
);
}
export function V1_buildDataQualityRelationValidation(
validation: V1_DataQualityRelationValidation,
context: V1_GraphBuilderContext,
): DataQualityRelationValidation {
const _validation = new DataQualityRelationValidation(
validation.name,
V1_buildRawLambdaWithResolvedPaths(
validation.assertion.parameters,
validation.assertion.body,
context,
),
);
_validation.description = validation.description;
if (validation.type) {
_validation.type = validation.type;
}
return _validation;
}
function transformGraphFetchTreeToDataQualityGraphFetchTree(
graphFetchTree: GraphFetchTree,
V1_graphFetchTree: V1_GraphFetchTree,
): GraphFetchTree {
if (V1_graphFetchTree instanceof V1_DataQualityRootGraphFetchTree) {
return transformRootGraphFetchTreeToDataQualityRootGraphFetchTree(
graphFetchTree as RootGraphFetchTree,
V1_graphFetchTree,
);
} else if (
V1_graphFetchTree instanceof V1_DataQualityPropertyGraphFetchTree
) {
return transformPropertyGraphFetchTreeToDataQualityPropertyGraphFetchTree(
graphFetchTree as PropertyGraphFetchTree,
V1_graphFetchTree,
);
}
throw new UnsupportedOperationError(
`Can't transform graph fetch tree to data quality graph fetch tree`,
V1_graphFetchTree,
);
}
function transformRootGraphFetchTreeToDataQualityRootGraphFetchTree(
rootGraphFetchTree: RootGraphFetchTree,
V1_rootGraphFetchTree: V1_DataQualityRootGraphFetchTree,
): DataQualityRootGraphFetchTree {
const dataQualityRootGraphFetchTree = new DataQualityRootGraphFetchTree(
rootGraphFetchTree.class,
);
dataQualityRootGraphFetchTree.constraints = V1_rootGraphFetchTree.constraints;
dataQualityRootGraphFetchTree.subTrees = rootGraphFetchTree.subTrees.map(
(_propertyTree, index) =>
transformGraphFetchTreeToDataQualityGraphFetchTree(
_propertyTree,
at(V1_rootGraphFetchTree.subTrees, index),
),
);
return dataQualityRootGraphFetchTree;
}
function transformPropertyGraphFetchTreeToDataQualityPropertyGraphFetchTree(
propertyGraphFetchTree: PropertyGraphFetchTree,
V1_propertyGraphFetchTree: V1_DataQualityPropertyGraphFetchTree,
): DataQualityPropertyGraphFetchTree {
const dataQualityPropertyGraphFetchTree =
new DataQualityPropertyGraphFetchTree(
propertyGraphFetchTree.property,
propertyGraphFetchTree.subType,
);
dataQualityPropertyGraphFetchTree.alias = propertyGraphFetchTree.alias;
dataQualityPropertyGraphFetchTree.parameters =
propertyGraphFetchTree.parameters;
dataQualityPropertyGraphFetchTree.subTrees =
propertyGraphFetchTree.subTrees.map((_propertyTree, index) =>
transformGraphFetchTreeToDataQualityGraphFetchTree(
_propertyTree,
at(V1_propertyGraphFetchTree.subTrees, index),
),
);
dataQualityPropertyGraphFetchTree.constraints =
V1_propertyGraphFetchTree.constraints;
return dataQualityPropertyGraphFetchTree;
}
export function V1_transformRootGraphFetchTreeToDataQualityRootGraphFetchTree(
rootGraphFetchTree: V1_RootGraphFetchTree,
): V1_DataQualityRootGraphFetchTree {
const dataQualityRootGraphFetchTree = new V1_DataQualityRootGraphFetchTree();
dataQualityRootGraphFetchTree.class = rootGraphFetchTree.class;
dataQualityRootGraphFetchTree.subTrees = rootGraphFetchTree.subTrees.map(
(_propertyTree) =>
V1_transformPropertyGraphFetchTreeToDataQualityPropertyGraphFetchTree(
_propertyTree as V1_PropertyGraphFetchTree,
),
);
return dataQualityRootGraphFetchTree;
}
function V1_transformPropertyGraphFetchTreeToDataQualityPropertyGraphFetchTree(
graphFetchTree: V1_PropertyGraphFetchTree,
): V1_DataQualityPropertyGraphFetchTree {
const dataQualityPropertyGraphFetchTree =
new V1_DataQualityPropertyGraphFetchTree();
dataQualityPropertyGraphFetchTree.property = graphFetchTree.property;
dataQualityPropertyGraphFetchTree.parameters = graphFetchTree.parameters;
dataQualityPropertyGraphFetchTree.subTrees = graphFetchTree.subTrees.map(
(_propertyTree) =>
V1_transformPropertyGraphFetchTreeToDataQualityPropertyGraphFetchTree(
_propertyTree as V1_PropertyGraphFetchTree,
),
);
return dataQualityPropertyGraphFetchTree;
}
export function V1_buildDataQualityClassValidationConfiguration(
elementProtocol: V1_DataQualityClassValidationsConfiguration,
context: V1_GraphBuilderContext,
): void {
const path = V1_buildFullPath(elementProtocol.package, elementProtocol.name);
const element = getOwnDataQualityClassValidationsConfiguration(
path,
context.currentSubGraph,
);
element.context = V1_buildDataQualityExecutionContext(
elementProtocol.context,
context,
);
element.dataQualityRootGraphFetchTree =
elementProtocol.dataQualityRootGraphFetchTree
? (V1_buildDataQualityGraphFetchTree(
elementProtocol.dataQualityRootGraphFetchTree,
context,
undefined,
[],
new V1_ProcessingContext(''),
true,
) as DataQualityRootGraphFetchTree)
: undefined;
element.filter = elementProtocol.filter
? V1_buildRawLambdaWithResolvedPaths(
elementProtocol.filter.parameters,
elementProtocol.filter.body,
context,
)
: undefined;
}
export function V1_buildDataQualityRelationValidationConfiguration(
elementProtocol: V1_DataQualityRelationValidationsConfiguration,
context: V1_GraphBuilderContext,
): void {
const path = V1_buildFullPath(elementProtocol.package, elementProtocol.name);
const element = getOwnDataQualityRelationValidationsConfiguration(
path,
context.currentSubGraph,
);
element.query = new DataQualityRelationQueryLambda();
element.query.body = elementProtocol.query.body;
element.query.parameters = elementProtocol.query.parameters.map((param) =>
V1_buildVariable(param, context),
);
element.validations = elementProtocol.validations.map((validation) =>
V1_buildDataQualityRelationValidation(validation, context),
);
element.runtime = elementProtocol.runtime
? (context.resolveElement(
elementProtocol.runtime.path,
false,
) as PackageableElementImplicitReference<PackageableRuntime>)
: undefined;
}
export function V1_buildDataQualityServiceValidationConfiguration(
elementProtocol: V1_DataQualityServiceValidationsConfiguration,
context: V1_GraphBuilderContext,
): void {
const path = V1_buildFullPath(elementProtocol.package, elementProtocol.name);
const element = getOwnDataQualityServiceValidationsConfiguration(
path,
context.currentSubGraph,
);
element.contextName = elementProtocol.contextName;
element.serviceName = elementProtocol.serviceName;
element.dataQualityRootGraphFetchTree =
elementProtocol.dataQualityRootGraphFetchTree
? (V1_buildDataQualityGraphFetchTree(
elementProtocol.dataQualityRootGraphFetchTree,
context,
undefined,
[],
new V1_ProcessingContext(''),
true,
) as DataQualityRootGraphFetchTree)
: undefined;
}
export function V1_buildDataQualityRelationComparisonConfiguration(
elementProtocol: V1_DataQualityRelationComparisonConfiguration,
context: V1_GraphBuilderContext,
): void {
const path = V1_buildFullPath(elementProtocol.package, elementProtocol.name);
const element = getOwnDataQualityRelationComparisonConfiguration(
path,
context.currentSubGraph,
);
element.source = new DataQualityRelationQueryLambda();
element.source.body = elementProtocol.source.body;
element.source.parameters = elementProtocol.source.parameters.map((param) =>
V1_buildVariable(param, context),
);
element.target = new DataQualityRelationQueryLambda();
element.target.body = elementProtocol.target.body;
element.target.parameters = elementProtocol.target.parameters.map((param) =>
V1_buildVariable(param, context),
);
element.keys = elementProtocol.keys;
element.columnsToCompare = elementProtocol.columnsToCompare;
if (elementProtocol.strategy instanceof V1_MD5HashStrategy) {
const strategy = new MD5HashStrategy();
strategy.sourceHashColumn = elementProtocol.strategy.sourceHashColumn;
strategy.targetHashColumn = elementProtocol.strategy.targetHashColumn;
strategy.aggregatedHash = elementProtocol.strategy.aggregatedHash;
element.strategy = strategy;
} else {
throw new UnsupportedOperationError(
`Can't build recon strategy: unsupported type`,
);
}
element.expectedMatch = elementProtocol.expectedMatch;
}