You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by nf...@apache.org on 2021/07/06 15:28:45 UTC
[camel-kamelets] branch main updated: chore(validator): additional
checks on kamelets and fix infinispan source
This is an automated email from the ASF dual-hosted git repository.
nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-kamelets.git
The following commit(s) were added to refs/heads/main by this push:
new d3d82d9 chore(validator): additional checks on kamelets and fix infinispan source
d3d82d9 is described below
commit d3d82d90a96d8fabe2ffc481b5e5ea3d6e4ff2cd
Author: nicolaferraro <ni...@gmail.com>
AuthorDate: Tue Jul 6 17:18:41 2021 +0200
chore(validator): additional checks on kamelets and fix infinispan source
---
infinispan-source.kamelet.yaml | 6 ++-
script/validator/validator.go | 94 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 99 insertions(+), 1 deletion(-)
diff --git a/infinispan-source.kamelet.yaml b/infinispan-source.kamelet.yaml
index aaf6f50..7ea50c2 100644
--- a/infinispan-source.kamelet.yaml
+++ b/infinispan-source.kamelet.yaml
@@ -25,12 +25,16 @@ spec:
description: |-
Get Events from an Infinispan cache
required:
+ - cacheName
- hosts
- username
- password
- - hosts
type: object
properties:
+ cacheName:
+ title: Cache Name
+ description: The name of the Infinispan cache to use
+ type: String
hosts:
title: Hosts
description: Specifies the host of the cache on Infinispan instance
diff --git a/script/validator/validator.go b/script/validator/validator.go
index 4d6ebcf..a224957 100644
--- a/script/validator/validator.go
+++ b/script/validator/validator.go
@@ -6,6 +6,7 @@ import (
"os"
"path"
"path/filepath"
+ "regexp"
"sort"
"strings"
@@ -29,6 +30,8 @@ import (
var (
// Needed until this is fixed: https://issues.apache.org/jira/browse/CAMEL-16788
forbiddenParameterNames = []string{"home", "hostname", "language", "lang", "namespace", "path", "podname", "pod-name", "port", "pwd", "shell", "term"}
+
+ paramRegexp = regexp.MustCompile(`{{[?]?([A-Za-z0-9-._]+)(?:[:][^}]*)?}}`)
)
func main() {
@@ -49,6 +52,7 @@ func main() {
errors = append(errors, verifyDescriptors(kamelets)...)
errors = append(errors, verifyDuplicates(kamelets)...)
errors = append(errors, verifyMissingDependencies(kamelets)...)
+ errors = append(errors, verifyUsedParams(kamelets)...)
for _, err := range errors {
fmt.Printf("ERROR: %v\n", err)
@@ -203,6 +207,13 @@ func verifyParameters(kamelets []KameletInfo) (errors []error) {
errors = append(errors, fmt.Errorf("kamelet %q does not contain the JSON schema definition", kamelet.Name))
continue
}
+ requiredCheck := make(map[string]bool)
+ for _, p := range kamelet.Spec.Definition.Required {
+ if requiredCheck[p] {
+ errors = append(errors, fmt.Errorf("required kamelet property %q is listed twice in kamelet %q", p, kamelet.Name))
+ }
+ requiredCheck[p] = true
+ }
if kamelet.Spec.Definition.Title == "" {
errors = append(errors, fmt.Errorf("kamelet %q does not contain title", kamelet.Name))
} else {
@@ -359,6 +370,89 @@ func listKamelets(dir string) []KameletInfo {
return kamelets
}
+func verifyUsedParams(kamelets []KameletInfo) (errors []error) {
+ for _, k := range kamelets {
+ used := getUsedParams(k.Kamelet)
+ declared := getDeclaredParams(k.Kamelet)
+ for p := range used {
+ if _, ok := declared[p]; !ok {
+ errors = append(errors, fmt.Errorf("parameter %q is not declared in the definition of kamelet %q", p, k.Kamelet.Name))
+ }
+ }
+ for p := range declared {
+ if _, ok := used[p]; !ok {
+ errors = append(errors, fmt.Errorf("parameter %q is declared in kamelet %q but never used", p, k.Kamelet.Name))
+ }
+ }
+ }
+ return errors
+}
+
+func getDeclaredParams(k camelapi.Kamelet) map[string]bool {
+ res := make(map[string]bool)
+ if k.Spec.Definition != nil {
+ for p := range k.Spec.Definition.Properties {
+ res[p] = true
+ }
+ }
+ // include beans
+ var flowData interface{}
+ if err := json.Unmarshal(k.Spec.Flow.RawMessage, &flowData); err != nil {
+ handleGeneralError("cannot unmarshal flow", err)
+ }
+ if fd, ok := flowData.(map[string]interface{}); ok {
+ beans := fd["beans"]
+ if bl, ok := beans.([]interface{}); ok {
+ for _, bdef := range bl {
+ if bmap, ok := bdef.(map[string]interface{}); ok {
+ beanName := bmap["name"]
+ if beanNameStr, ok := beanName.(string); ok {
+ res[beanNameStr] = true
+ }
+ }
+ }
+ }
+ }
+ return res
+}
+
+func getUsedParams(k camelapi.Kamelet) map[string]bool {
+ if k.Spec.Flow != nil {
+ var flowData interface{}
+ if err := json.Unmarshal(k.Spec.Flow.RawMessage, &flowData); err != nil {
+ handleGeneralError("cannot unmarshal flow", err)
+ }
+ params := make(map[string]bool)
+ inspectFlowParams(flowData, params)
+ return params
+ }
+ return nil
+}
+
+func inspectFlowParams(v interface{}, params map[string]bool) {
+ switch val := v.(type) {
+ case string:
+ res := paramRegexp.FindAllStringSubmatch(val, -1)
+ for _, m := range res {
+ if len(m) > 1 {
+ params[m[1]] = true
+ }
+ }
+ case []interface{}:
+ for _, c := range val {
+ inspectFlowParams(c, params)
+ }
+ case map[string]interface{}:
+ for _, c := range val {
+ inspectFlowParams(c, params)
+ }
+ case map[interface{}]interface{}:
+ for _, c := range val {
+ inspectFlowParams(c, params)
+ }
+ }
+}
+
type KameletInfo struct {
camelapi.Kamelet
FileName string