);
}
return undefined;
},
};
}
getExtraQueryBuilderPropagateExecutionContextChangeHelper?(): QueryBuilderPropagateExecutionContextChangeHelper[] {
return [
(
queryBuilderState: QueryBuilderState,
isGraphBuildingNotRequired?: boolean,
): (() => Promise) | undefined => {
/**
* Propagation after changing the execution context:
* - The mapping will be updated to the mapping of the execution context
* - The runtime will be updated to the default runtime of the execution context
* - If no class is chosen, try to choose a compatible class
* - If the chosen class is compatible with the new selected execution context mapping, do nothing, otherwise, try to choose a compatible class
*/
const propagateExecutionContextChange = async (): Promise => {
const dataSpaceQueryBuilderState = guaranteeType(
queryBuilderState,
DataSpaceQueryBuilderState,
);
const mapping =
dataSpaceQueryBuilderState.executionContext.mapping.value;
const mappingModelCoverageAnalysisResult =
dataSpaceQueryBuilderState.dataSpaceAnalysisResult?.mappingToMappingCoverageResult?.get(
mapping.path,
);
const editorStore = (
queryBuilderState.workflowState
.actionConfig as QueryBuilderActionConfig_QueryApplication
).editorStore;
if (
dataSpaceQueryBuilderState.dataSpaceAnalysisResult &&
mappingModelCoverageAnalysisResult
) {
if (
!isGraphBuildingNotRequired &&
dataSpaceQueryBuilderState.isLightGraphEnabled
) {
const supportBuildMinimalGraph =
editorStore.applicationStore.config.options
.TEMPORARY__enableMinimalGraph;
if (
editorStore.enableMinialGraphForDataSpaceLoadingPerformance &&
supportBuildMinimalGraph
) {
try {
const stopWatch = new StopWatch();
const graph =
dataSpaceQueryBuilderState.graphManagerState.createNewGraph();
const graph_buildReport = createGraphBuilderReport();
const graphManager = guaranteeType(
dataSpaceQueryBuilderState.graphManagerState.graphManager,
V1_PureGraphManager,
);
// Create dummy mappings and runtimes
// TODO?: these stubbed mappings and runtimes are not really useful that useful, so either we should
// simplify the model here or potentially refactor the backend analytics endpoint to return these as model
const mappingModels = uniq(
Array.from(
dataSpaceQueryBuilderState.dataSpaceAnalysisResult.executionContextsIndex.values(),
).map((context) => context.mapping),
).map((m) => {
const _mapping = new V1_Mapping();
const [packagePath, name] =
resolvePackagePathAndElementName(m.path);
_mapping.package = packagePath;
_mapping.name = name;
return graphManager.elementProtocolToEntity(_mapping);
});
const runtimeModels = uniq(
Array.from(
dataSpaceQueryBuilderState.dataSpaceAnalysisResult.executionContextsIndex.values(),
)
.map((context) => context.defaultRuntime)
.concat(
Array.from(
dataSpaceQueryBuilderState.dataSpaceAnalysisResult.executionContextsIndex.values(),
).flatMap((val) => val.compatibleRuntimes),
),
).map((r) => {
const runtime = new V1_PackageableRuntime();
const [packagePath, name] =
resolvePackagePathAndElementName(r.path);
runtime.package = packagePath;
runtime.name = name;
runtime.runtimeValue = new V1_EngineRuntime();
return graphManager.elementProtocolToEntity(runtime);
});
// The Data Product entity is excluded from AnalyticsResult.Json to reduce the JSON size
// because all its information can be found in V1_DataSpaceAnalysisResult.
// Therefore, we are building a simple v1_DataSpace entity based on V1_DataSpaceAnalysisResult.
const dataspaceProtocol = new V1_DataSpace();
dataspaceProtocol.name =
dataSpaceQueryBuilderState.dataSpaceAnalysisResult.name;
dataspaceProtocol.package =
dataSpaceQueryBuilderState.dataSpaceAnalysisResult.package;
dataspaceProtocol.supportInfo =
dataSpaceQueryBuilderState.dataSpaceAnalysisResult.supportInfo;
dataspaceProtocol.executionContexts = Array.from(
dataSpaceQueryBuilderState.dataSpaceAnalysisResult
.executionContextsIndex,
).map(([key, execContext]) => {
const contextProtocol = new V1_DataSpaceExecutionContext();
contextProtocol.name = execContext.name;
contextProtocol.title = execContext.title;
contextProtocol.description = execContext.description;
contextProtocol.mapping = new V1_PackageableElementPointer(
PackageableElementPointerType.MAPPING,
execContext.mapping.path,
);
contextProtocol.defaultRuntime =
new V1_PackageableElementPointer(
PackageableElementPointerType.RUNTIME,
execContext.defaultRuntime.path,
);
return contextProtocol;
});
dataspaceProtocol.defaultExecutionContext =
dataSpaceQueryBuilderState.dataSpaceAnalysisResult.defaultExecutionContext.name;
dataspaceProtocol.title =
dataSpaceQueryBuilderState.dataSpaceAnalysisResult.title;
dataspaceProtocol.description =
dataSpaceQueryBuilderState.dataSpaceAnalysisResult.description;
const dataspaceEntity =
graphManager.elementProtocolToEntity(dataspaceProtocol);
const graphEntities = guaranteeNonNullable(
mappingModelCoverageAnalysisResult.entities,
)
.concat(mappingModels)
.concat(runtimeModels)
.concat(dataspaceEntity)
// NOTE: if an element could be found in the graph already it means it comes from system
// so we could rid of it
.filter(
(el) =>
!graph.getNullableElement(el.path, false) &&
!el.path.startsWith('meta::'),
);
let option;
if (
dataSpaceQueryBuilderState instanceof
LegendQueryDataSpaceQueryBuilderState
) {
option = dataSpaceQueryBuilderState.sdlc;
}
await dataSpaceQueryBuilderState.graphManagerState.graphManager.buildGraph(
graph,
graphEntities,
ActionState.create(),
option
? {
origin: option,
}
: {},
graph_buildReport,
);
dataSpaceQueryBuilderState.graphManagerState.graph = graph;
const dependency_buildReport = createGraphBuilderReport();
// report
stopWatch.record(
GRAPH_MANAGER_EVENT.INITIALIZE_GRAPH__SUCCESS,
);
const graphBuilderReportData = {
timings:
dataSpaceQueryBuilderState.applicationStore.timeService.finalizeTimingsRecord(
stopWatch,
),
dependencies: dependency_buildReport,
dependenciesCount:
dataSpaceQueryBuilderState.graphManagerState.graph
.dependencyManager.numberOfDependencies,
graph: graph_buildReport,
};
editorStore.logBuildGraphMetrics(graphBuilderReportData);
dataSpaceQueryBuilderState.applicationStore.logService.info(
LogEvent.create(
GRAPH_MANAGER_EVENT.INITIALIZE_GRAPH__SUCCESS,
),
graphBuilderReportData,
);
} catch (error) {
assertErrorThrown(error);
editorStore.applicationStore.logService.error(
LogEvent.create(LEGEND_QUERY_APP_EVENT.GENERIC_FAILURE),
error,
);
editorStore.graphManagerState.graph =
editorStore.graphManagerState.createNewGraph();
await flowResult(editorStore.buildFullGraph());
}
} else {
editorStore.graphManagerState.graph =
editorStore.graphManagerState.createNewGraph();
await flowResult(editorStore.buildFullGraph());
}
}
dataSpaceQueryBuilderState.explorerState.mappingModelCoverageAnalysisResult =
mappingModelCoverageAnalysisResult;
}
const compatibleClasses = resolveUsableDataSpaceClasses(
dataSpaceQueryBuilderState.dataSpace,
mapping,
dataSpaceQueryBuilderState.graphManagerState,
dataSpaceQueryBuilderState,
);
dataSpaceQueryBuilderState.changeMapping(mapping);
dataSpaceQueryBuilderState.changeRuntime(
new RuntimePointer(
dataSpaceQueryBuilderState.executionContext.defaultRuntime,
),
);
// if there is no chosen class or the chosen one is not compatible
// with the mapping then pick a compatible class if possible
if (
!dataSpaceQueryBuilderState.sourceClass ||
!compatibleClasses.includes(dataSpaceQueryBuilderState.sourceClass)
) {
const possibleNewClass = compatibleClasses[0];
if (possibleNewClass) {
dataSpaceQueryBuilderState.changeSourceElement(possibleNewClass);
}
}
dataSpaceQueryBuilderState.explorerState.refreshTreeData();
};
if (
queryBuilderState instanceof DataSpaceQueryBuilderState &&
queryBuilderState.workflowState.actionConfig instanceof
QueryBuilderActionConfig_QueryApplication
) {
return propagateExecutionContextChange;
}
return undefined;
},
];
}
// TODO: create plugin for DataProducts
getExtraTemplateQueryPanelContentRenderer(): TemplateQueryPanelContentRenderer[] {
return [
(queryBuilderState: QueryBuilderState): React.ReactNode => {
if (
queryBuilderState instanceof LegendQueryDataProductQueryBuilderState
) {
return renderDataProductSampleQueryPanelContent(queryBuilderState);
}
return undefined;
},
];
}
}