This is an automated email from the ASF dual-hosted git repository. nferraro pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 11ca9c6b20ea200a5179db649190b0c7ae930382 Author: lburgazzoli <lburgazz...@gmail.com> AuthorDate: Thu Dec 20 23:02:31 2018 +0100 inspect xml source code using streaming parser --- pkg/metadata/metadata.go | 5 +- pkg/metadata/uris.go | 239 ------------------------------- pkg/util/source/inspector.go | 89 ++++++++++++ pkg/util/source/inspector_groovy.go | 50 +++++++ pkg/util/source/inspector_java_script.go | 50 +++++++ pkg/util/source/inspector_java_source.go | 46 ++++++ pkg/util/source/inspector_kotlin.go | 46 ++++++ pkg/util/source/inspector_xml.go | 89 ++++++++++++ pkg/util/source/inspector_yaml_flow.go | 67 +++++++++ 9 files changed, 440 insertions(+), 241 deletions(-) diff --git a/pkg/metadata/metadata.go b/pkg/metadata/metadata.go index a696f99..4f7d980 100644 --- a/pkg/metadata/metadata.go +++ b/pkg/metadata/metadata.go @@ -21,6 +21,7 @@ import ( "sort" "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" + src "github.com/apache/camel-k/pkg/util/source" ) // ExtractAll returns metadata information from all listed source codes @@ -71,9 +72,9 @@ func merge(m1 IntegrationMetadata, m2 IntegrationMetadata) IntegrationMetadata { func Extract(source v1alpha1.SourceSpec) IntegrationMetadata { language := discoverLanguage(source) // TODO: handle error - fromURIs, _ := GetInspectorForLanguage(language).FromURIs(source) + fromURIs, _ := src.InspectorForLanguage(language).FromURIs(source) // TODO:: handle error - toURIs, _ := GetInspectorForLanguage(language).ToURIs(source) + toURIs, _ := src.InspectorForLanguage(language).ToURIs(source) dependencies := discoverDependencies(source, fromURIs, toURIs) requiresHTTPService := requiresHTTPService(source, fromURIs) passiveEndpoints := hasOnlyPassiveEndpoints(source, fromURIs) diff --git a/pkg/metadata/uris.go b/pkg/metadata/uris.go deleted file mode 100644 index c267cfa..0000000 --- a/pkg/metadata/uris.go +++ /dev/null @@ -1,239 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one or more -contributor license agreements. See the NOTICE file distributed with -this work for additional information regarding copyright ownership. -The ASF licenses this file to You 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. -*/ - -package metadata - -import ( - "regexp" - - "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" - yaml "gopkg.in/yaml.v2" -) - -var ( - singleQuotedFrom = regexp.MustCompile(`from\s*\(\s*'([a-z0-9-]+:[^']+)'\s*\)`) - doubleQuotedFrom = regexp.MustCompile(`from\s*\(\s*"([a-z0-9-]+:[^"]+)"\s*\)`) - singleQuotedTo = regexp.MustCompile(`\.to\s*\(\s*'([a-z0-9-]+:[^']+)'\s*\)`) - singleQuotedToD = regexp.MustCompile(`\.toD\s*\(\s*'([a-z0-9-]+:[^']+)'\s*\)`) - singleQuotedToF = regexp.MustCompile(`\.toF\s*\(\s*'([a-z0-9-]+:[^']+)'[^)]*\)`) - doubleQuotedTo = regexp.MustCompile(`\.to\s*\(\s*"([a-z0-9-]+:[^"]+)"\s*\)`) - doubleQuotedToD = regexp.MustCompile(`\.toD\s*\(\s*"([a-z0-9-]+:[^"]+)"\s*\)`) - doubleQuotedToF = regexp.MustCompile(`\.toF\s*\(\s*"([a-z0-9-]+:[^"]+)"[^)]*\)`) - xmlTagFrom = regexp.MustCompile(`<\s*from\s+[^>]*uri\s*=\s*"([a-z0-9-]+:[^"]+)"[^>]*>`) - xmlTagTo = regexp.MustCompile(`<\s*to\s+[^>]*uri\s*=\s*"([a-z0-9-]+:[^"]+)"[^>]*>`) - xmlTagToD = regexp.MustCompile(`<\s*toD\s+[^>]*uri\s*=\s*"([a-z0-9-]+:[^"]+)"[^>]*>`) -) - -// LanguageInspector -- -type LanguageInspector interface { - FromURIs(v1alpha1.SourceSpec) ([]string, error) - ToURIs(v1alpha1.SourceSpec) ([]string, error) -} - -type languageInspector struct { - from func(v1alpha1.SourceSpec) ([]string, error) - to func(v1alpha1.SourceSpec) ([]string, error) -} - -func (i languageInspector) FromURIs(source v1alpha1.SourceSpec) ([]string, error) { - return i.from(source) -} -func (i languageInspector) ToURIs(source v1alpha1.SourceSpec) ([]string, error) { - return i.to(source) -} - -// GetInspectorForLanguage -- -func GetInspectorForLanguage(language v1alpha1.Language) LanguageInspector { - switch language { - case v1alpha1.LanguageJavaSource: - return &languageInspector{ - from: func(source v1alpha1.SourceSpec) ([]string, error) { - answer := findAllDistinctStringSubmatch( - source.Content, - doubleQuotedFrom, - ) - - return answer, nil - }, - to: func(source v1alpha1.SourceSpec) ([]string, error) { - answer := findAllDistinctStringSubmatch( - source.Content, - doubleQuotedTo, - doubleQuotedToD, - doubleQuotedToF, - ) - - return answer, nil - }, - } - case v1alpha1.LanguageXML: - return &languageInspector{ - from: func(source v1alpha1.SourceSpec) ([]string, error) { - answer := findAllDistinctStringSubmatch( - source.Content, - xmlTagFrom, - ) - - return answer, nil - }, - to: func(source v1alpha1.SourceSpec) ([]string, error) { - answer := findAllDistinctStringSubmatch( - source.Content, - xmlTagTo, - xmlTagToD, - ) - - return answer, nil - }, - } - case v1alpha1.LanguageGroovy: - return &languageInspector{ - from: func(source v1alpha1.SourceSpec) ([]string, error) { - answer := findAllDistinctStringSubmatch( - source.Content, - singleQuotedFrom, - doubleQuotedFrom, - ) - - return answer, nil - }, - to: func(source v1alpha1.SourceSpec) ([]string, error) { - answer := findAllDistinctStringSubmatch( - source.Content, - singleQuotedTo, - doubleQuotedTo, - singleQuotedToD, - doubleQuotedToD, - singleQuotedToF, - doubleQuotedToF, - ) - - return answer, nil - }, - } - case v1alpha1.LanguageJavaScript: - return &languageInspector{ - from: func(source v1alpha1.SourceSpec) ([]string, error) { - answer := findAllDistinctStringSubmatch( - source.Content, - singleQuotedFrom, - doubleQuotedFrom, - ) - - return answer, nil - }, - to: func(source v1alpha1.SourceSpec) ([]string, error) { - answer := findAllDistinctStringSubmatch( - source.Content, - singleQuotedTo, - doubleQuotedTo, - singleQuotedToD, - doubleQuotedToD, - singleQuotedToF, - doubleQuotedToF, - ) - - return answer, nil - }, - } - case v1alpha1.LanguageKotlin: - return &languageInspector{ - from: func(source v1alpha1.SourceSpec) ([]string, error) { - answer := findAllDistinctStringSubmatch( - source.Content, - doubleQuotedFrom, - ) - - return answer, nil - }, - to: func(source v1alpha1.SourceSpec) ([]string, error) { - answer := findAllDistinctStringSubmatch( - source.Content, - doubleQuotedTo, - doubleQuotedToD, - doubleQuotedToF, - ) - - return answer, nil - }, - } - case v1alpha1.LanguageYamlFlow: - var flows []v1alpha1.Flow - - return &languageInspector{ - from: func(source v1alpha1.SourceSpec) ([]string, error) { - if err := yaml.Unmarshal([]byte(source.Content), &flows); err != nil { - return []string{}, nil - } - - uris := make([]string, 0) - - for _, flow := range flows { - if flow.Steps[0].URI != "" { - uris = append(uris, flow.Steps[0].URI) - } - - } - return uris, nil - }, - to: func(source v1alpha1.SourceSpec) ([]string, error) { - if err := yaml.Unmarshal([]byte(source.Content), &flows); err != nil { - return []string{}, nil - } - - uris := make([]string, 0) - - for _, flow := range flows { - for i := 1; i < len(flow.Steps); i++ { - if flow.Steps[i].URI != "" { - uris = append(uris, flow.Steps[i].URI) - } - } - } - - return uris, nil - }, - } - } - return &languageInspector{ - from: func(source v1alpha1.SourceSpec) ([]string, error) { - return []string{}, nil - }, - to: func(source v1alpha1.SourceSpec) ([]string, error) { - return []string{}, nil - }, - } -} - -func findAllDistinctStringSubmatch(data string, regexps ...*regexp.Regexp) []string { - candidates := make([]string, 0) - alreadyFound := make(map[string]bool) - for _, reg := range regexps { - hits := reg.FindAllStringSubmatch(data, -1) - for _, hit := range hits { - if len(hit) > 1 { - for _, match := range hit[1:] { - if _, ok := alreadyFound[match]; !ok { - alreadyFound[match] = true - candidates = append(candidates, match) - } - } - } - } - } - return candidates -} diff --git a/pkg/util/source/inspector.go b/pkg/util/source/inspector.go new file mode 100644 index 0000000..db76c49 --- /dev/null +++ b/pkg/util/source/inspector.go @@ -0,0 +1,89 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/ + +package source + +import ( + "regexp" + + "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" +) + +var ( + singleQuotedFrom = regexp.MustCompile(`from\s*\(\s*'([a-z0-9-]+:[^']+)'\s*\)`) + doubleQuotedFrom = regexp.MustCompile(`from\s*\(\s*"([a-z0-9-]+:[^"]+)"\s*\)`) + singleQuotedTo = regexp.MustCompile(`\.to\s*\(\s*'([a-z0-9-]+:[^']+)'\s*\)`) + singleQuotedToD = regexp.MustCompile(`\.toD\s*\(\s*'([a-z0-9-]+:[^']+)'\s*\)`) + singleQuotedToF = regexp.MustCompile(`\.toF\s*\(\s*'([a-z0-9-]+:[^']+)'[^)]*\)`) + doubleQuotedTo = regexp.MustCompile(`\.to\s*\(\s*"([a-z0-9-]+:[^"]+)"\s*\)`) + doubleQuotedToD = regexp.MustCompile(`\.toD\s*\(\s*"([a-z0-9-]+:[^"]+)"\s*\)`) + doubleQuotedToF = regexp.MustCompile(`\.toF\s*\(\s*"([a-z0-9-]+:[^"]+)"[^)]*\)`) +) + +// Inspector -- +type Inspector interface { + FromURIs(v1alpha1.SourceSpec) ([]string, error) + ToURIs(v1alpha1.SourceSpec) ([]string, error) +} + +// InspectorForLanguage -- +func InspectorForLanguage(language v1alpha1.Language) Inspector { + switch language { + case v1alpha1.LanguageJavaSource: + return &JavaSourceInspector{} + case v1alpha1.LanguageXML: + return &XMLInspector{} + case v1alpha1.LanguageGroovy: + return &GroovyInspector{} + case v1alpha1.LanguageJavaScript: + return &JavaScriptInspector{} + case v1alpha1.LanguageKotlin: + return &KotlinInspector{} + case v1alpha1.LanguageYamlFlow: + return &YAMLFlowInspector{} + } + return &noInspector{} +} + +func findAllDistinctStringSubmatch(data string, regexps ...*regexp.Regexp) []string { + candidates := make([]string, 0) + alreadyFound := make(map[string]bool) + for _, reg := range regexps { + hits := reg.FindAllStringSubmatch(data, -1) + for _, hit := range hits { + if len(hit) > 1 { + for _, match := range hit[1:] { + if _, ok := alreadyFound[match]; !ok { + alreadyFound[match] = true + candidates = append(candidates, match) + } + } + } + } + } + return candidates +} + +type noInspector struct { +} + +func (i noInspector) FromURIs(source v1alpha1.SourceSpec) ([]string, error) { + return []string{}, nil +} +func (i noInspector) ToURIs(source v1alpha1.SourceSpec) ([]string, error) { + return []string{}, nil +} diff --git a/pkg/util/source/inspector_groovy.go b/pkg/util/source/inspector_groovy.go new file mode 100644 index 0000000..ddcd874 --- /dev/null +++ b/pkg/util/source/inspector_groovy.go @@ -0,0 +1,50 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/ + +package source + +import "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" + +// GroovyInspector -- +type GroovyInspector struct { +} + +// FromURIs -- +func (i GroovyInspector) FromURIs(source v1alpha1.SourceSpec) ([]string, error) { + answer := findAllDistinctStringSubmatch( + source.Content, + singleQuotedFrom, + doubleQuotedFrom, + ) + + return answer, nil +} + +// ToURIs -- +func (i GroovyInspector) ToURIs(source v1alpha1.SourceSpec) ([]string, error) { + answer := findAllDistinctStringSubmatch( + source.Content, + singleQuotedTo, + doubleQuotedTo, + singleQuotedToD, + doubleQuotedToD, + singleQuotedToF, + doubleQuotedToF, + ) + + return answer, nil +} diff --git a/pkg/util/source/inspector_java_script.go b/pkg/util/source/inspector_java_script.go new file mode 100644 index 0000000..913fc8d --- /dev/null +++ b/pkg/util/source/inspector_java_script.go @@ -0,0 +1,50 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/ + +package source + +import "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" + +// JavaScriptInspector -- +type JavaScriptInspector struct { +} + +// FromURIs -- +func (i JavaScriptInspector) FromURIs(source v1alpha1.SourceSpec) ([]string, error) { + answer := findAllDistinctStringSubmatch( + source.Content, + singleQuotedFrom, + doubleQuotedFrom, + ) + + return answer, nil +} + +// ToURIs -- +func (i JavaScriptInspector) ToURIs(source v1alpha1.SourceSpec) ([]string, error) { + answer := findAllDistinctStringSubmatch( + source.Content, + singleQuotedTo, + doubleQuotedTo, + singleQuotedToD, + doubleQuotedToD, + singleQuotedToF, + doubleQuotedToF, + ) + + return answer, nil +} diff --git a/pkg/util/source/inspector_java_source.go b/pkg/util/source/inspector_java_source.go new file mode 100644 index 0000000..4a22953 --- /dev/null +++ b/pkg/util/source/inspector_java_source.go @@ -0,0 +1,46 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/ + +package source + +import "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" + +// JavaSourceInspector -- +type JavaSourceInspector struct { +} + +// FromURIs -- +func (i JavaSourceInspector) FromURIs(source v1alpha1.SourceSpec) ([]string, error) { + answer := findAllDistinctStringSubmatch( + source.Content, + doubleQuotedFrom, + ) + + return answer, nil +} + +// ToURIs -- +func (i JavaSourceInspector) ToURIs(source v1alpha1.SourceSpec) ([]string, error) { + answer := findAllDistinctStringSubmatch( + source.Content, + doubleQuotedTo, + doubleQuotedToD, + doubleQuotedToF, + ) + + return answer, nil +} diff --git a/pkg/util/source/inspector_kotlin.go b/pkg/util/source/inspector_kotlin.go new file mode 100644 index 0000000..111bf14 --- /dev/null +++ b/pkg/util/source/inspector_kotlin.go @@ -0,0 +1,46 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/ + +package source + +import "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" + +// KotlinInspector -- +type KotlinInspector struct { +} + +// FromURIs -- +func (i KotlinInspector) FromURIs(source v1alpha1.SourceSpec) ([]string, error) { + answer := findAllDistinctStringSubmatch( + source.Content, + doubleQuotedFrom, + ) + + return answer, nil +} + +// ToURIs -- +func (i KotlinInspector) ToURIs(source v1alpha1.SourceSpec) ([]string, error) { + answer := findAllDistinctStringSubmatch( + source.Content, + doubleQuotedTo, + doubleQuotedToD, + doubleQuotedToF, + ) + + return answer, nil +} diff --git a/pkg/util/source/inspector_xml.go b/pkg/util/source/inspector_xml.go new file mode 100644 index 0000000..c13f1e6 --- /dev/null +++ b/pkg/util/source/inspector_xml.go @@ -0,0 +1,89 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/ + +package source + +import ( + "encoding/xml" + "strings" + + "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" +) + +// XMLInspector -- +type XMLInspector struct { +} + +// FromURIs -- +func (i XMLInspector) FromURIs(source v1alpha1.SourceSpec) ([]string, error) { + content := strings.NewReader(source.Content) + decoder := xml.NewDecoder(content) + + uris := make([]string, 0) + + for { + // Read tokens from the XML document in a stream. + t, _ := decoder.Token() + if t == nil { + break + } + + switch se := t.(type) { + case xml.StartElement: + switch se.Name.Local { + case "from", "fromF": + for _, a := range se.Attr { + if a.Name.Local == "uri" { + uris = append(uris, a.Value) + } + } + } + } + } + + return uris, nil +} + +// ToURIs -- +func (i XMLInspector) ToURIs(source v1alpha1.SourceSpec) ([]string, error) { + content := strings.NewReader(source.Content) + decoder := xml.NewDecoder(content) + + uris := make([]string, 0) + + for { + // Read tokens from the XML document in a stream. + t, _ := decoder.Token() + if t == nil { + break + } + + switch se := t.(type) { + case xml.StartElement: + switch se.Name.Local { + case "to", "toD", "toF": + for _, a := range se.Attr { + if a.Name.Local == "uri" { + uris = append(uris, a.Value) + } + } + } + } + } + + return uris, nil +} diff --git a/pkg/util/source/inspector_yaml_flow.go b/pkg/util/source/inspector_yaml_flow.go new file mode 100644 index 0000000..e677b4d --- /dev/null +++ b/pkg/util/source/inspector_yaml_flow.go @@ -0,0 +1,67 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/ + +package source + +import ( + "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" + yaml "gopkg.in/yaml.v2" +) + +// YAMLFlowInspector -- +type YAMLFlowInspector struct { +} + +// FromURIs -- +func (i YAMLFlowInspector) FromURIs(source v1alpha1.SourceSpec) ([]string, error) { + var flows []v1alpha1.Flow + + if err := yaml.Unmarshal([]byte(source.Content), &flows); err != nil { + return []string{}, nil + } + + uris := make([]string, 0) + + for _, flow := range flows { + if flow.Steps[0].URI != "" { + uris = append(uris, flow.Steps[0].URI) + } + + } + return uris, nil +} + +// ToURIs -- +func (i YAMLFlowInspector) ToURIs(source v1alpha1.SourceSpec) ([]string, error) { + var flows []v1alpha1.Flow + + if err := yaml.Unmarshal([]byte(source.Content), &flows); err != nil { + return []string{}, nil + } + + uris := make([]string, 0) + + for _, flow := range flows { + for i := 1; i < len(flow.Steps); i++ { + if flow.Steps[i].URI != "" { + uris = append(uris, flow.Steps[i].URI) + } + } + } + + return uris, nil +}