diff --git a/.github/workflows/night.yaml b/.github/workflows/night.yaml index 74139aabe1..24444653a3 100644 --- a/.github/workflows/night.yaml +++ b/.github/workflows/night.yaml @@ -108,7 +108,7 @@ jobs: - name: (DOCKER) Ensure Vintner can be executed run: docker exec vintner vintner --version - - name: (DOCKER) Ensure Vintner can be executed + - name: (DOCKER) Ensure Vintner version in Docker container and binary match run: | DOCKER_VERSION=$(docker exec vintner vintner --version) echo "Docker version: $DOCKER_VERSION}" diff --git a/docs/docs/variability4tosca/specification/index.md b/docs/docs/variability4tosca/specification/index.md index 9854d126df..fe821cf9ae 100644 --- a/docs/docs/variability4tosca/specification/index.md +++ b/docs/docs/variability4tosca/specification/index.md @@ -1112,6 +1112,7 @@ export type TechnologyPluginBuilder = { export type TechnologyPlugin = { assign: (node: Node) => {[technology: string]: TechnologyTemplate}[] implement: (name: string, type: NodeType) => NodeTypeMap + uses: (artifact: Artifact) => Technology[] } ``` diff --git a/src/enricher/elements.ts b/src/enricher/elements.ts index b24e35a44e..bbecca8e32 100644 --- a/src/enricher/elements.ts +++ b/src/enricher/elements.ts @@ -26,7 +26,7 @@ export class ElementEnricher { private getTechnologyCandidates(node: Node) { const candidates: TechnologyTemplateMap[] = [] - for (const plugin of this.graph.plugins.technology) { + for (const plugin of this.graph.plugins.technology.filter(it => it.backwards())) { candidates.push(...plugin.assign(node)) } return candidates @@ -39,7 +39,7 @@ export class ElementEnricher { */ private enrichImplementations() { // for backwards compatibility and testing purposed, continue if, e.g., no rules at all exists - if (utils.isEmpty(this.graph.plugins.technology)) return + if (utils.isEmpty(this.graph.plugins.technology.filter(it => it.backwards()))) return for (const node of this.graph.nodes.filter(it => it.managed).filter(it => utils.isPopulated(it.technologies))) { // Do not override manual assigned technologies but enrich them with an implementation diff --git a/src/graph/populator.ts b/src/graph/populator.ts index d803baa66b..0e3e7b1671 100644 --- a/src/graph/populator.ts +++ b/src/graph/populator.ts @@ -92,9 +92,7 @@ export class Populator { * Technology Rule Plugin */ const technologyRulePlugin = new TechnologyRulePluginBuilder().build(this.graph) - if (technologyRulePlugin.hasRules()) { - this.graph.plugins.technology.push(technologyRulePlugin) - } + this.graph.plugins.technology.push(technologyRulePlugin) /** * Imported plugins diff --git a/src/resolver/solver.ts b/src/resolver/solver.ts index 9911938c92..17a1f0bb24 100644 --- a/src/resolver/solver.ts +++ b/src/resolver/solver.ts @@ -3,12 +3,12 @@ import * as check from '#check' import Element from '#graph/element' import Graph from '#graph/graph' import Property from '#graph/property' +import Technology from '#graph/technology' import {andify} from '#graph/utils' import Optimizer from '#resolver/optimizer' import {Result, ResultMap} from '#resolver/result' import {InputAssignmentMap, InputAssignmentValue} from '#spec/topology-template' import {LogicExpression, ValueExpression, VariabilityDefinition, VariabilityExpression} from '#spec/variability' -import {destructImplementationName} from '#technologies/utils' import * as utils from '#utils' import day from '#utils/day' import {UnexpectedError} from '#utils/error' @@ -629,11 +629,12 @@ export default class Solver { */ if (check.isDefined(expression.is_managed)) { const artifact = this.graph.getArtifact(expression.is_managed, {element, cached}) - const technologies = artifact.container.technologies.filter(it => { - const deconstructed = destructImplementationName(it.assign) - if (check.isUndefined(deconstructed.artifact)) return false - return artifact.getType().isA(deconstructed.artifact) - }) + + const technologies: Technology[] = [] + for (const plugin of this.graph.plugins.technology) { + technologies.push(...plugin.uses(artifact)) + } + return MiniSat.or(technologies.map(it => it.id)) } diff --git a/src/technologies/plugins/rules/index.ts b/src/technologies/plugins/rules/index.ts index 577436ee73..cb8a140d2a 100644 --- a/src/technologies/plugins/rules/index.ts +++ b/src/technologies/plugins/rules/index.ts @@ -1,7 +1,9 @@ import * as assert from '#assert' import * as check from '#check' +import Artifact from '#graph/artifact' import Graph from '#graph/graph' import Node from '#graph/node' +import Technology from '#graph/technology' import {NodeType, NodeTypeMap} from '#spec/node-type' import {TechnologyTemplateMap} from '#spec/technology-template' import {LogicExpression} from '#spec/variability' @@ -9,7 +11,12 @@ import std from '#std' import Registry from '#technologies/plugins/rules/registry' import {ASTERISK, METADATA} from '#technologies/plugins/rules/types' import {TechnologyPlugin, TechnologyPluginBuilder} from '#technologies/types' -import {constructImplementationName, constructRuleName, isGenerated} from '#technologies/utils' +import { + constructImplementationName, + constructRuleName, + destructImplementationName, + isGenerated, +} from '#technologies/utils' import * as utils from '#utils' export class TechnologyRulePluginBuilder implements TechnologyPluginBuilder { @@ -32,10 +39,22 @@ export class TechnologyRulePlugin implements TechnologyPlugin { return rules } + backwards() { + return this.hasRules() + } + hasRules() { return utils.isPopulated(this.getRules()) } + uses(artifact: Artifact): Technology[] { + return artifact.container.technologies.filter(it => { + const deconstructed = destructImplementationName(it.assign) + if (check.isUndefined(deconstructed.artifact)) return false + return artifact.getType().isA(deconstructed.artifact) + }) + } + implement(name: string, type: NodeType): NodeTypeMap { const rules = this.getRules() if (utils.isEmpty(rules)) return {} diff --git a/src/technologies/types.ts b/src/technologies/types.ts index 91e3d7dcd8..a4625b2b8e 100644 --- a/src/technologies/types.ts +++ b/src/technologies/types.ts @@ -1,5 +1,7 @@ +import Artifact from '#graph/artifact' import Graph from '#graph/graph' import Node from '#graph/node' +import Technology from '#graph/technology' import {NodeType, NodeTypeMap} from '#spec/node-type' import {TechnologyTemplateMap} from '#spec/technology-template' @@ -8,7 +10,11 @@ export type TechnologyPluginBuilder = { } export type TechnologyPlugin = { + // for backwards compatibility and testing purposed, continue if, e.g., no rules at all exists + backwards: () => Boolean + // TODO: must assign technology.assign! assign: (node: Node) => TechnologyTemplateMap[] implement: (name: string, type: NodeType) => NodeTypeMap + uses: (artifact: Artifact) => Technology[] } diff --git a/tests/enricher/technology-plugin-loader-default/plugins/technology/terraform/index.js b/tests/enricher/technology-plugin-loader-default/plugins/technology/terraform/index.js index af9cab67b1..35ee3972cc 100644 --- a/tests/enricher/technology-plugin-loader-default/plugins/technology/terraform/index.js +++ b/tests/enricher/technology-plugin-loader-default/plugins/technology/terraform/index.js @@ -5,6 +5,7 @@ const technology = require("technology"); module.exports = { build: (graph) => { return { + backwards: () => true, assign: (node) => { return [{ [technology.name()]: { assign: "this-is-assigned" } }]; } diff --git a/tests/enricher/technology-plugin-loader-file/plugin/index.js b/tests/enricher/technology-plugin-loader-file/plugin/index.js index af9cab67b1..35ee3972cc 100644 --- a/tests/enricher/technology-plugin-loader-file/plugin/index.js +++ b/tests/enricher/technology-plugin-loader-file/plugin/index.js @@ -5,6 +5,7 @@ const technology = require("technology"); module.exports = { build: (graph) => { return { + backwards: () => true, assign: (node) => { return [{ [technology.name()]: { assign: "this-is-assigned" } }]; }