This is an automated email from the ASF dual-hosted git repository. heneveld pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/brooklyn-ui.git
commit 0456306abca63ae1b69962d0f340b7febe23ace6 Author: Alex Heneveld <[email protected]> AuthorDate: Mon Apr 26 19:29:28 2021 +0100 set from key or parameter working, with root or anywhere (optionally with type) or ancestors (optionally with type) --- docs/basic-with-constraint.bom | 17 +-- .../app/components/quick-fix/quick-fix.js | 166 ++++++++++++++------- .../app/components/util/model/entity.model.js | 10 ++ 3 files changed, 130 insertions(+), 63 deletions(-) diff --git a/docs/basic-with-constraint.bom b/docs/basic-with-constraint.bom index 3ca3e3c..0f1a2db 100644 --- a/docs/basic-with-constraint.bom +++ b/docs/basic-with-constraint.bom @@ -37,21 +37,20 @@ brooklyn.catalog: message-regex: cannot both be set - key: post_code - fix: set_from_parameter + fix: set_from_key message-regex: required - source-mode: suggested + source-key: postal_code source-hierarchy: root - source-types: [ org.apache.brooklyn.api.entity.Application ] - source-parameter: postal_code - source-constraints: - - required + source-key-createable: true + source-key-parameter-definition: + constraints: + - required - key: post_code - fix: set_from_config_key + fix: set_from_key message-regex: required - source-mode: enforced - source-types: [ basic-with-constraint ] source-key: post_code source-hierarchy: anywhere + source-types: [ basic-with-constraint ] diff --git a/ui-modules/blueprint-composer/app/components/quick-fix/quick-fix.js b/ui-modules/blueprint-composer/app/components/quick-fix/quick-fix.js index 049a713..d703f11 100644 --- a/ui-modules/blueprint-composer/app/components/quick-fix/quick-fix.js +++ b/ui-modules/blueprint-composer/app/components/quick-fix/quick-fix.js @@ -90,76 +90,134 @@ const QUICK_FIX_PROPOSERS = { proposals.clear_config.issues.push(issue); }, }, - set_from_parameter: { - propose: proposeSetFrom('parameter') - - // - key: post_code - // fix: set_from_parameter - // message-regex: required - // source-mode: suggested - // source-hierarchy: root - // source-types: [ org.apache.brooklyn.api.entity.Application ] - // source-parameter: postal_code - // source-constraints: - // - required - - }, - set_from_config_key: { - propose: proposeSetFrom('config') - + set_from_key: { + propose: proposeSetFrom() // - key: post_code - // fix: set_from_config_key + // fix: set_from_key // message-regex: required - // source-mode: enforced - // source-types: [ basic-with-constraint ] - // source-key: post_code - // source-hierarchy: anywhere + // + // source-key: postal_code # required, custom + // + // source-hierarchy: root # optional, root|anywhere|ancestors -- default is root if no source-types given, anywhere if source-types are given + // source-types: [ org.apache.brooklyn.api.entity.Application ] # types to filter by + // + // source-key-createable: true # whether a parameter can be created or a key/param must already exist there (default the latter, ie false) + // source-key-parameter-definition: # if createable and did not exist, extra things to add to definition + // constraints: + // - required + + // source-mode: suggested | enforced # (enhancement, not supported) could allow user to pick the type and/or key/param name - } + }, }; -function proposeSetFrom(sourceType) { +function proposeSetFrom() { return function (qfdef, issue, entity, proposals) { if (!issue.ref) return; + + let ckey = qfdef['source-key']; + if (!ckey) { + console.warn("Missing required 'source-key' on hint", qfdef); + return; + } + if (!proposals) proposals = {}; - let sourceNode = { - id: 'root', - name: 'the application root node', - entity: entity.getApplication(), - }; + let createable = qfdef['source-key-createable']; - if (sourceType === 'parameter') { - let params = sourceNode.entity.getParametersAsArray(); - console.log("params", params); - } + // TODO if root param is required, show error + // TODO make default id containts type name + // TODO show default id if no id present + // TODO if id is changed, update all refs + // TODO allow graphically selectable + + let considerNode = (sourceNode) => { + if (qfdef['source-types']) { + // TODO would be nice to store super-types of entity in miscData and filter based on those + if (!qfdef['source-types'].includes(sourceNode.entity.type)) { + // wrong type + return; + } + } + + if (sourceNode.entity._id === entity._id && ckey === issue.ref) { + // skip proposal for recursive definition + return; + } - let key = 'set_from_'+sourceType+'_'+sourceNode.id; - if (!proposals[key]) { - proposals[key] = { - text: "Set from a new "+sourceType+" on "+sourceNode.name, - tooltip: "This will create a "+sourceType+" on "+sourceNode.name+" and fix this error by setting it equal to that "+sourceType, - issues: [], - apply: (issue, entity) => { - entity = (entity || issue.entity); - console.log("TODO do this; NB issue invoked wrt", entity, qfdef); - if (sourceType === 'parameter') { - if (!sourceNode.entity.getParameterNamed(qfdef['source-parameter'])) { - sourceNode.entity.addParameter({ - name: qfdef['source-parameter'], - constraints: qfdef['source-constraints'] - }); + let hasKey = sourceNode.entity.config[ckey] || (sourceNode.entity.miscData.get("config") || []).find(c => c && c.name === ckey); + let hasParam = sourceNode.entity.getParameterNamed(ckey); + + let existing = hasKey || hasParam; + let create = !existing && createable; + + if (!existing && !create) { + // no proposal available (cannot create) + return; + } + + sourceNode.id = sourceNode.id || sourceNode.entity.id || sourceNode.entity._id; + sourceNode.name = sourceNode.name || sourceNode.entity.name || + ((sourceNode.entity.type || "Unnamed item") + " " + "(" + (sourceNode.entity.id || sourceNode.entity._id) +")"); + + let pkey = 'set_from_' + sourceNode.id + '_' + ckey; + if (!proposals[pkey]) { + if (sourceNode.create_key) { + proposals[pkey] = { + text: "Set from new parameter '" + ckey + "' on " + sourceNode.name, + tooltip: "This will fix the error by setting the value here equal to the value of a new parameter '" + ckey + "' created on " + sourceNode.name + + ". The value of that parameter may need to be set in order to deploy this.", + }; + } else { + proposals[pkey] = { + text: "Set from '" + ckey + "' on " + sourceNode.name, + tooltip: "This will fix the error by setting the value here equal to the value of " + + sourceNode.target_mode + + " '" + ckey + "' on " + sourceNode.name, + }; + } + + Object.assign(proposals[pkey], { + issues: [], + apply: (issue, entity) => { + if (sourceNode.create_key) { + // check again so we only create once + let hasParam = sourceNode.entity.getParameterNamed(ckey); + if (!hasParam) { + sourceNode.entity.addParameter(Object.assign( + {name: ckey,}, + qfdef['source-key-parameter-definition'] || {} + )); + } } if (!sourceNode.entity.id) { - // TODO - sourceNode.entity.id = 'id_XXX'; + sourceNode.entity.id = sourceNode.entity._id; } - entity.addConfig(issue.ref, '$brooklyn:component("'+sourceNode.entity.id+'").config("'+qfdef['source-parameter']+'")'); + + entity = (entity || issue.entity); + entity.addConfig(issue.ref, '$brooklyn:component("' + sourceNode.entity.id + '").config("' + ckey + '")'); } - } - }; + }); + } + if (proposals[pkey]) { + proposals[pkey].issues.push(issue); + } + }; + + if (qfdef['source-hierarchy']=='root' || (!qfdef['source-hierarchy'] && !qfdef['source-types'])) { + considerNode({ + id: 'root', + name: 'the application root node', + entity: entity.getApplication(), + }); + } else if (qfdef['source-hierarchy']=='anywhere' || (!qfdef['source-hierarchy'] && qfdef['source-types'])) { + entity.getApplication().visitWithDescendants(entity => considerNode({ entity })); + } else if (qfdef['source-hierarchy']=='ancestors') { + entity.visitWithAncestors(entity => considerNode({ entity })); + } else { + console.warn("Unsupported source-hierarchy in quick-fix", qfdef); } - proposals[key].issues.push(issue); + }; } diff --git a/ui-modules/blueprint-composer/app/components/util/model/entity.model.js b/ui-modules/blueprint-composer/app/components/util/model/entity.model.js index f8afc28..b844450 100644 --- a/ui-modules/blueprint-composer/app/components/util/model/entity.model.js +++ b/ui-modules/blueprint-composer/app/components/util/model/entity.model.js @@ -563,6 +563,16 @@ export class Entity { toString() { return 'Entity :: id = [' + this._id + ']' + (this.hasType() ? ' type = [' + this.type + ']' : ''); } + + visitWithDescendants(fn) { + fn(this); + this.children.forEach(c => c.visitWithDescendants(fn)); + } + + visitWithAncestors(fn) { + fn(this); + if (this.parent) this.parent.visitWithAncestors(fn); + } } Entity.prototype.setEntityFromJson = setEntityFromJson;
