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 2020/03/11 21:00:24 UTC
[camel-k] 02/02: refactor source code inspectors to avoid using
redgexp for markup languages
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 25a4f3d30676f41e3db42ceadda19f55c28f87cc
Author: lburgazzoli <lb...@gmail.com>
AuthorDate: Wed Mar 11 20:33:15 2020 +0100
refactor source code inspectors to avoid using redgexp for markup languages
---
examples/RestWithUndertow.java | 41 -------
pkg/metadata/http.go | 102 ----------------
pkg/metadata/metadata.go | 37 +++---
pkg/metadata/metadata_dependencies_test.go | 185 ++++++++++++++++++++++++++---
pkg/metadata/metadata_http_test.go | 20 ++--
pkg/metadata/types.go | 17 ---
pkg/trait/knative_service.go | 4 +-
pkg/trait/service.go | 2 +-
pkg/util/source/inspector.go | 173 ++++++++++++++++++++++-----
pkg/util/source/inspector_groovy.go | 5 +
pkg/util/source/inspector_java_script.go | 3 +
pkg/util/source/inspector_java_source.go | 3 +
pkg/util/source/inspector_kotlin.go | 5 +
pkg/util/source/inspector_xml.go | 4 +
pkg/util/source/inspector_yaml.go | 5 +-
pkg/util/source/types.go | 16 +++
16 files changed, 384 insertions(+), 238 deletions(-)
diff --git a/examples/RestWithUndertow.java b/examples/RestWithUndertow.java
deleted file mode 100644
index 63090a6..0000000
--- a/examples/RestWithUndertow.java
+++ /dev/null
@@ -1,41 +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.
- */
-
-//
-// To run this integrations use:
-//
-// kamel run --name=rest-with-undertow --dependency=camel-rest --dependency=camel-undertow examples/RestWithUndertow.java
-//
-import org.apache.camel.Exchange;
-
-public class RestWithUndertow extends org.apache.camel.builder.RouteBuilder {
- @Override
- public void configure() throws Exception {
- restConfiguration()
- .component("undertow")
- .host("0.0.0.0")
- .port("8080");
-
- rest()
- .get("/hello")
- .to("direct:hello");
-
- from("direct:hello")
- .setHeader(Exchange.CONTENT_TYPE, constant("text/plain"))
- .transform().simple("Hello World");
- }
-}
diff --git a/pkg/metadata/http.go b/pkg/metadata/http.go
deleted file mode 100644
index be56808..0000000
--- a/pkg/metadata/http.go
+++ /dev/null
@@ -1,102 +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"
- "strings"
-
- "github.com/apache/camel-k/pkg/util/camel"
-
- v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
-)
-
-var restIndicator = regexp.MustCompile(`.*rest\s*\([^)]*\).*`)
-var xmlRestIndicator = regexp.MustCompile(`.*<\s*rest\s+[^>]*>.*`)
-
-// requiresHTTPService returns true if the integration needs to expose itself through HTTP
-func requiresHTTPService(catalog *camel.RuntimeCatalog, source v1.SourceSpec, fromURIs []string) bool {
- if hasRestIndicator(source) {
- return true
- }
- return containsHTTPURIs(catalog, fromURIs)
-}
-
-// hasOnlyPassiveEndpoints returns true if the integration has no endpoint that needs to remain always active
-func hasOnlyPassiveEndpoints(catalog *camel.RuntimeCatalog, _ v1.SourceSpec, fromURIs []string) bool {
- passivePlusHTTP := make(map[string]bool)
- catalog.VisitSchemes(func(id string, scheme v1.CamelScheme) bool {
- if scheme.HTTP || scheme.Passive {
- passivePlusHTTP[id] = true
- }
-
- return true
- })
-
- return containsOnlyURIsIn(fromURIs, passivePlusHTTP)
-}
-
-func containsHTTPURIs(catalog *camel.RuntimeCatalog, fromURI []string) bool {
- for _, uri := range fromURI {
- prefix := getURIPrefix(uri)
- scheme, ok := catalog.GetScheme(prefix)
-
- if !ok {
- // scheme dees not exists
- continue
- }
-
- if scheme.HTTP {
- return true
- }
- }
-
- return false
-}
-
-func containsOnlyURIsIn(fromURI []string, allowed map[string]bool) bool {
- for _, uri := range fromURI {
- prefix := getURIPrefix(uri)
- if enabled, ok := allowed[prefix]; !ok || !enabled {
- return false
- }
- }
- return true
-}
-
-func getURIPrefix(uri string) string {
- parts := strings.SplitN(uri, ":", 2)
- if len(parts) > 0 {
- return parts[0]
- }
- return ""
-}
-
-func hasRestIndicator(source v1.SourceSpec) bool {
- pat := getRestIndicatorRegexpsForLanguage(source.InferLanguage())
- return pat.MatchString(source.Content)
-}
-
-func getRestIndicatorRegexpsForLanguage(language v1.Language) *regexp.Regexp {
- switch language {
- case v1.LanguageXML:
- return xmlRestIndicator
- default:
- return restIndicator
- }
-}
diff --git a/pkg/metadata/metadata.go b/pkg/metadata/metadata.go
index 9f9b53e..2c8dd8e 100644
--- a/pkg/metadata/metadata.go
+++ b/pkg/metadata/metadata.go
@@ -31,17 +31,19 @@ import (
// ExtractAll returns metadata information from all listed source codes
func ExtractAll(catalog *camel.RuntimeCatalog, sources []v1.SourceSpec) IntegrationMetadata {
// neutral metadata
- meta := NewIntegrationMetadata()
+ meta := src.NewMetadata()
meta.PassiveEndpoints = true
- meta.RequiresHTTPService = false
+ meta.ExposesHTTPServices = false
for _, source := range sources {
- meta = merge(meta, Extract(catalog, source))
+ meta = merge(meta, Extract(catalog, source).Metadata)
+ }
+ return IntegrationMetadata{
+ Metadata: meta,
}
- return meta
}
-func merge(m1 IntegrationMetadata, m2 IntegrationMetadata) IntegrationMetadata {
+func merge(m1 src.Metadata, m2 src.Metadata) src.Metadata {
d := strset.Union(m1.Dependencies, m2.Dependencies)
f := make([]string, 0, len(m1.FromURIs)+len(m2.FromURIs))
@@ -52,13 +54,11 @@ func merge(m1 IntegrationMetadata, m2 IntegrationMetadata) IntegrationMetadata {
t = append(t, m1.ToURIs...)
t = append(t, m2.ToURIs...)
- return IntegrationMetadata{
- Metadata: src.Metadata{
- FromURIs: f,
- ToURIs: t,
- Dependencies: d,
- },
- RequiresHTTPService: m1.RequiresHTTPService || m2.RequiresHTTPService,
+ return src.Metadata{
+ FromURIs: f,
+ ToURIs: t,
+ Dependencies: d,
+ ExposesHTTPServices: m1.ExposesHTTPServices || m2.ExposesHTTPServices,
PassiveEndpoints: m1.PassiveEndpoints && m2.PassiveEndpoints,
}
}
@@ -73,15 +73,16 @@ func Extract(catalog *camel.RuntimeCatalog, source v1.SourceSpec) IntegrationMet
language := source.InferLanguage()
- m := NewIntegrationMetadata()
+ meta := src.NewMetadata()
+ meta.PassiveEndpoints = true
+ meta.ExposesHTTPServices = false
// TODO: handle error
- _ = src.InspectorForLanguage(catalog, language).Extract(source, &m.Metadata)
+ _ = src.InspectorForLanguage(catalog, language).Extract(source, &meta)
- m.RequiresHTTPService = requiresHTTPService(catalog, source, m.FromURIs)
- m.PassiveEndpoints = hasOnlyPassiveEndpoints(catalog, source, m.FromURIs)
-
- return m
+ return IntegrationMetadata{
+ Metadata: meta,
+ }
}
// Each --
diff --git a/pkg/metadata/metadata_dependencies_test.go b/pkg/metadata/metadata_dependencies_test.go
index 1a96276..fe5c0e9 100644
--- a/pkg/metadata/metadata_dependencies_test.go
+++ b/pkg/metadata/metadata_dependencies_test.go
@@ -48,7 +48,17 @@ func TestDependenciesJavaSource(t *testing.T) {
meta := Extract(catalog, code)
- assert.ElementsMatch(t, []string{"camel:activemq", "camel:amqp", "camel:log", "camel:telegram", "camel:timer", "camel:twitter"}, meta.Dependencies.List())
+ assert.ElementsMatch(
+ t,
+ []string{
+ "camel:activemq",
+ "camel:amqp",
+ "camel:log",
+ "camel:telegram",
+ "camel:timer",
+ "camel:twitter",
+ },
+ meta.Dependencies.List())
}
func TestDependenciesJavaScript(t *testing.T) {
@@ -72,7 +82,16 @@ func TestDependenciesJavaScript(t *testing.T) {
meta := Extract(catalog, code)
- assert.ElementsMatch(t, []string{"camel:activemq", "camel:amqp", "camel:log", "camel:telegram", "camel:timer"}, meta.Dependencies.List())
+ assert.ElementsMatch(
+ t,
+ []string{
+ "camel:activemq",
+ "camel:amqp",
+ "camel:log",
+ "camel:telegram",
+ "camel:timer",
+ },
+ meta.Dependencies.List())
}
func TestDependenciesGroovy(t *testing.T) {
@@ -98,7 +117,17 @@ func TestDependenciesGroovy(t *testing.T) {
meta := Extract(catalog, code)
- assert.ElementsMatch(t, []string{"camel:activemq", "camel:amqp", "camel:log", "camel:telegram", "camel:timer", "camel:twitter"}, meta.Dependencies.List())
+ assert.ElementsMatch(
+ t,
+ []string{
+ "camel:activemq",
+ "camel:amqp",
+ "camel:log",
+ "camel:telegram",
+ "camel:timer",
+ "camel:twitter",
+ },
+ meta.Dependencies.List())
}
func TestDependencies(t *testing.T) {
@@ -180,7 +209,14 @@ func TestJacksonDependency(t *testing.T) {
meta := Extract(catalog, code)
- assert.ElementsMatch(t, []string{"camel:http", "camel:jackson", "camel:log"}, meta.Dependencies.List())
+ assert.ElementsMatch(
+ t,
+ []string{
+ "camel:http",
+ "camel:jackson",
+ "camel:log",
+ },
+ meta.Dependencies.List())
}
func TestJacksonImplicitDependency(t *testing.T) {
@@ -201,7 +237,14 @@ func TestJacksonImplicitDependency(t *testing.T) {
meta := Extract(catalog, code)
- assert.ElementsMatch(t, []string{"camel:http", "camel:jackson", "camel:log"}, meta.Dependencies.List())
+ assert.ElementsMatch(
+ t,
+ []string{
+ "camel:http",
+ "camel:jackson",
+ "camel:log",
+ },
+ meta.Dependencies.List())
}
func TestLanguageDependencies(t *testing.T) {
@@ -227,8 +270,19 @@ func TestLanguageDependencies(t *testing.T) {
assert.Nil(t, err)
meta := Extract(catalog, code)
- assert.ElementsMatch(t, []string{"camel:direct", "camel:ognl", "camel:saxon", "camel:xpath",
- "camel:jsonpath", "camel:groovy", "camel:jaxp", "camel:mvel"}, meta.Dependencies.List())
+ assert.ElementsMatch(
+ t,
+ []string{
+ "camel:direct",
+ "camel:ognl",
+ "camel:saxon",
+ "camel:xpath",
+ "camel:jsonpath",
+ "camel:groovy",
+ "camel:xml-jaxp",
+ "camel:mvel",
+ },
+ meta.Dependencies.List())
}
func TestLanguageDependenciesTransformExpression(t *testing.T) {
@@ -250,7 +304,15 @@ func TestLanguageDependenciesTransformExpression(t *testing.T) {
assert.Nil(t, err)
meta := Extract(catalog, code)
- assert.ElementsMatch(t, []string{"camel:direct", "camel:ognl", "camel:xpath", "camel:jsonpath"}, meta.Dependencies.List())
+ assert.ElementsMatch(
+ t,
+ []string{
+ "camel:direct",
+ "camel:ognl",
+ "camel:xpath",
+ "camel:jsonpath",
+ },
+ meta.Dependencies.List())
}
func TestHystrixDependency(t *testing.T) {
@@ -273,7 +335,13 @@ func TestHystrixDependency(t *testing.T) {
meta := Extract(catalog, code)
- assert.ElementsMatch(t, []string{"camel:http", "camel:hystrix", "camel:log"}, meta.Dependencies.List())
+ assert.ElementsMatch(t,
+ []string{
+ "camel:http",
+ "camel:hystrix",
+ "camel:log",
+ },
+ meta.Dependencies.List())
}
func TestRestDependency(t *testing.T) {
@@ -296,7 +364,16 @@ func TestRestDependency(t *testing.T) {
meta := Extract(catalog, code)
- assert.ElementsMatch(t, []string{"camel:http", "camel:rest", "camel:direct", "camel:log"}, meta.Dependencies.List())
+ assert.ElementsMatch(
+ t,
+ []string{
+ "camel:http",
+ "camel:direct",
+ "camel:log",
+ "mvn:org.apache.camel/camel-rest",
+ "mvn:org.apache.camel/camel-undertow",
+ },
+ meta.Dependencies.List())
}
func TestRestWithPathDependency(t *testing.T) {
@@ -319,7 +396,15 @@ func TestRestWithPathDependency(t *testing.T) {
meta := Extract(catalog, code)
- assert.ElementsMatch(t, []string{"camel:http", "camel:rest", "camel:direct", "camel:log"}, meta.Dependencies.List())
+ assert.ElementsMatch(
+ t, []string{
+ "camel:http",
+ "camel:direct",
+ "camel:log",
+ "mvn:org.apache.camel/camel-rest",
+ "mvn:org.apache.camel/camel-undertow",
+ },
+ meta.Dependencies.List())
}
func TestRestConfigurationDependency(t *testing.T) {
@@ -341,10 +426,17 @@ func TestRestConfigurationDependency(t *testing.T) {
meta := Extract(catalog, code)
- assert.ElementsMatch(t, []string{"camel:http", "camel:rest", "camel:log"}, meta.Dependencies.List())
+ assert.ElementsMatch(
+ t, []string{
+ "camel:http",
+ "camel:log",
+ "mvn:org.apache.camel/camel-rest",
+ "mvn:org.apache.camel/camel-undertow",
+ },
+ meta.Dependencies.List())
}
-func TestRestClosureDependency(t *testing.T) {
+func TestRestClosureDependencyGroovy(t *testing.T) {
code := v1.SourceSpec{
DataSpec: v1.DataSpec{
Name: "Request.groovy",
@@ -363,7 +455,45 @@ func TestRestClosureDependency(t *testing.T) {
meta := Extract(catalog, code)
- assert.ElementsMatch(t, []string{"camel:http", "camel:rest", "camel:log"}, meta.Dependencies.List())
+ assert.ElementsMatch(
+ t,
+ []string{
+ "camel:http",
+ "camel:log",
+ "mvn:org.apache.camel/camel-rest",
+ "mvn:org.apache.camel/camel-undertow",
+ },
+ meta.Dependencies.List())
+}
+
+func TestRestClosureDependencyKotlin(t *testing.T) {
+ code := v1.SourceSpec{
+ DataSpec: v1.DataSpec{
+ Name: "Request.groovy",
+ Content: `
+ rest {
+ }
+ from("http:test")
+ .to("log:info")
+ `,
+ },
+ Language: v1.LanguageKotlin,
+ }
+
+ catalog, err := camel.DefaultCatalog()
+ assert.Nil(t, err)
+
+ meta := Extract(catalog, code)
+
+ assert.ElementsMatch(
+ t,
+ []string{
+ "camel:http",
+ "camel:log",
+ "mvn:org.apache.camel/camel-rest",
+ "mvn:org.apache.camel/camel-undertow",
+ },
+ meta.Dependencies.List())
}
func TestXMLHystrixDependency(t *testing.T) {
@@ -389,7 +519,15 @@ func TestXMLHystrixDependency(t *testing.T) {
meta := Extract(catalog, code)
- assert.ElementsMatch(t, []string{"camel:direct", "camel:hystrix", "camel:kafka", "camel:log"}, meta.Dependencies.List())
+ assert.ElementsMatch(
+ t,
+ []string{
+ "camel:direct",
+ "camel:hystrix",
+ "camel:kafka",
+ "camel:log",
+ },
+ meta.Dependencies.List())
}
func TestXMLRestDependency(t *testing.T) {
@@ -419,7 +557,14 @@ func TestXMLRestDependency(t *testing.T) {
meta := Extract(catalog, code)
- assert.ElementsMatch(t, []string{"camel:direct", "camel:rest", "camel:mock"}, meta.Dependencies.List())
+ assert.ElementsMatch(
+ t,
+ []string{
+ "camel:direct",
+ "camel:rest",
+ "camel:mock",
+ },
+ meta.Dependencies.List())
}
func TestXMLLanguageDependencies(t *testing.T) {
@@ -556,7 +701,13 @@ func TestYAMLHystrixDependency(t *testing.T) {
meta := Extract(catalog, code)
- assert.ElementsMatch(t, []string{"camel:direct", "camel:hystrix"}, meta.Dependencies.List())
+ assert.ElementsMatch(
+ t,
+ []string{
+ "camel:direct",
+ "camel:hystrix",
+ },
+ meta.Dependencies.List())
}
func TestYAMLLanguageDependencies(t *testing.T) {
diff --git a/pkg/metadata/metadata_http_test.go b/pkg/metadata/metadata_http_test.go
index e89365e..97b4aea 100644
--- a/pkg/metadata/metadata_http_test.go
+++ b/pkg/metadata/metadata_http_test.go
@@ -44,7 +44,7 @@ func TestHttpJavaSource(t *testing.T) {
meta := Extract(catalog, code)
- assert.True(t, meta.RequiresHTTPService)
+ assert.True(t, meta.ExposesHTTPServices)
assert.False(t, meta.PassiveEndpoints)
}
@@ -67,7 +67,7 @@ func TestHttpOnlyJavaSource(t *testing.T) {
meta := Extract(catalog, code)
- assert.True(t, meta.RequiresHTTPService)
+ assert.True(t, meta.ExposesHTTPServices)
assert.True(t, meta.PassiveEndpoints)
}
@@ -88,7 +88,7 @@ func TestHttpOnlyJavaSourceRest(t *testing.T) {
meta := Extract(catalog, code)
- assert.True(t, meta.RequiresHTTPService)
+ assert.True(t, meta.ExposesHTTPServices)
assert.True(t, meta.PassiveEndpoints)
}
@@ -109,7 +109,7 @@ func TestHttpOnlyJavaSourceRest2(t *testing.T) {
meta := Extract(catalog, code)
- assert.True(t, meta.RequiresHTTPService)
+ assert.True(t, meta.ExposesHTTPServices)
assert.True(t, meta.PassiveEndpoints)
}
@@ -131,7 +131,7 @@ func TestNoHttpGroovySource(t *testing.T) {
meta := Extract(catalog, code)
- assert.False(t, meta.RequiresHTTPService)
+ assert.False(t, meta.ExposesHTTPServices)
assert.False(t, meta.PassiveEndpoints)
}
@@ -153,7 +153,7 @@ func TestHttpOnlyGroovySource(t *testing.T) {
meta := Extract(catalog, code)
- assert.True(t, meta.RequiresHTTPService)
+ assert.True(t, meta.ExposesHTTPServices)
assert.True(t, meta.PassiveEndpoints)
}
@@ -175,7 +175,7 @@ func TestHttpXMLSource(t *testing.T) {
meta := Extract(catalog, code)
- assert.True(t, meta.RequiresHTTPService)
+ assert.True(t, meta.ExposesHTTPServices)
assert.False(t, meta.PassiveEndpoints)
}
@@ -198,7 +198,7 @@ func TestHttpOnlyXMLSource(t *testing.T) {
meta := Extract(catalog, code)
- assert.True(t, meta.RequiresHTTPService)
+ assert.True(t, meta.ExposesHTTPServices)
assert.True(t, meta.PassiveEndpoints)
}
@@ -232,7 +232,7 @@ func TestMultilangHTTPOnlySource(t *testing.T) {
meta := ExtractAll(catalog, codes)
- assert.True(t, meta.RequiresHTTPService)
+ assert.True(t, meta.ExposesHTTPServices)
assert.True(t, meta.PassiveEndpoints)
}
@@ -268,6 +268,6 @@ func TestMultilangHTTPSource(t *testing.T) {
meta := ExtractAll(catalog, codes)
- assert.True(t, meta.RequiresHTTPService)
+ assert.True(t, meta.ExposesHTTPServices)
assert.False(t, meta.PassiveEndpoints)
}
diff --git a/pkg/metadata/types.go b/pkg/metadata/types.go
index 934da27..66565cf 100644
--- a/pkg/metadata/types.go
+++ b/pkg/metadata/types.go
@@ -19,26 +19,9 @@ package metadata
import (
"github.com/apache/camel-k/pkg/util/source"
- "github.com/scylladb/go-set/strset"
)
// IntegrationMetadata contains aggregate metadata about all Camel routes in a integrations
type IntegrationMetadata struct {
source.Metadata
- // RequiresHTTPService indicates if the integration needs to be invoked through HTTP
- RequiresHTTPService bool
- // PassiveEndpoints indicates that the integration contains only passive endpoints that are activated from
- // external calls, including HTTP (useful to determine if the integration can scale to 0)
- PassiveEndpoints bool
-}
-
-// NewIntegrationMetadata --
-func NewIntegrationMetadata() IntegrationMetadata {
- return IntegrationMetadata{
- Metadata: source.Metadata{
- FromURIs: make([]string, 0),
- ToURIs: make([]string, 0),
- Dependencies: strset.New(),
- },
- }
}
diff --git a/pkg/trait/knative_service.go b/pkg/trait/knative_service.go
index 9c9e671..8a46b92 100644
--- a/pkg/trait/knative_service.go
+++ b/pkg/trait/knative_service.go
@@ -158,7 +158,7 @@ func (t *knativeServiceTrait) Configure(e *Environment) (bool, error) {
}
meta := metadata.ExtractAll(e.CamelCatalog, sources)
- if !meta.RequiresHTTPService || !meta.PassiveEndpoints {
+ if !meta.ExposesHTTPServices || !meta.PassiveEndpoints {
single := 1
t.MinScale = &single
}
@@ -256,7 +256,7 @@ func (t *knativeServiceTrait) SelectControllerStrategy(e *Environment) (*Control
}
meta := metadata.ExtractAll(e.CamelCatalog, sources)
- if meta.RequiresHTTPService {
+ if meta.ExposesHTTPServices {
return &knativeServiceStrategy, nil
}
return nil, nil
diff --git a/pkg/trait/service.go b/pkg/trait/service.go
index 6257e9e..882cd48 100644
--- a/pkg/trait/service.go
+++ b/pkg/trait/service.go
@@ -88,7 +88,7 @@ func (t *serviceTrait) Configure(e *Environment) (bool, error) {
}
meta := metadata.ExtractAll(e.CamelCatalog, sources)
- if !meta.RequiresHTTPService {
+ if !meta.ExposesHTTPServices {
e.Integration.Status.SetCondition(
v1.IntegrationConditionServiceAvailable,
corev1.ConditionFalse,
diff --git a/pkg/util/source/inspector.go b/pkg/util/source/inspector.go
index 934525c..a8b690a 100644
--- a/pkg/util/source/inspector.go
+++ b/pkg/util/source/inspector.go
@@ -18,6 +18,7 @@ limitations under the License.
package source
import (
+ "fmt"
"regexp"
"strings"
@@ -26,6 +27,8 @@ import (
"github.com/apache/camel-k/pkg/util/camel"
)
+type catalog2deps func(*camel.RuntimeCatalog) []string
+
var (
singleQuotedFrom = regexp.MustCompile(`from\s*\(\s*'([a-zA-Z0-9-]+:[^']+)'`)
doubleQuotedFrom = regexp.MustCompile(`from\s*\(\s*"([a-zA-Z0-9-]+:[^"]+)"`)
@@ -41,8 +44,8 @@ var (
jsonLanguageRegexp = regexp.MustCompile(`.*\.json\(\).*`)
circuitBreakerRegexp = regexp.MustCompile(`.*\.circuitBreaker\(\).*`)
restConfigurationRegexp = regexp.MustCompile(`.*restConfiguration\(\).*`)
- restRegexp = regexp.MustCompile(`.*rest\(("[a-zA-Z0-9-/]+")*\).*`)
- restXMLRegexp = regexp.MustCompile(`^\s*rest\s*{.*`)
+ restRegexp = regexp.MustCompile(`.*rest\s*\([^)]*\).*`)
+ restClosureRegexp = regexp.MustCompile(`.*rest\s*{\s*`)
groovyLanguageRegexp = regexp.MustCompile(`.*\.groovy\s*\(.*\).*`)
jsonPathLanguageRegexp = regexp.MustCompile(`.*\.?(jsonpath|jsonpathWriteAsString)\s*\(.*\).*`)
ognlRegexp = regexp.MustCompile(`.*\.ognl\s*\(.*\).*`)
@@ -51,27 +54,91 @@ var (
xpathRegexp = regexp.MustCompile(`.*\.?xpath\s*\(.*\).*`)
xtokenizeRegexp = regexp.MustCompile(`.*\.xtokenize\s*\(.*\).*`)
- sourceDependencies = struct {
- main map[*regexp.Regexp]string
- quarkus map[*regexp.Regexp]string
- }{
- main: map[*regexp.Regexp]string{
- jsonLibraryRegexp: "camel:jackson",
- jsonLanguageRegexp: "camel:jackson",
- circuitBreakerRegexp: "camel:hystrix",
- restConfigurationRegexp: "camel:rest",
- restRegexp: "camel:rest",
- restXMLRegexp: "camel:rest",
- groovyLanguageRegexp: "camel:groovy",
- jsonPathLanguageRegexp: "camel:jsonpath",
- ognlRegexp: "camel:ognl",
- mvelRegexp: "camel:mvel",
- xqueryRegexp: "camel:saxon",
- xpathRegexp: "camel:xpath",
- xtokenizeRegexp: "camel:jaxp",
+ sourceDependencies = map[*regexp.Regexp]catalog2deps{
+ jsonLibraryRegexp: func(_ *camel.RuntimeCatalog) []string {
+ return []string{"camel:jackson"}
+ },
+ jsonLanguageRegexp: func(_ *camel.RuntimeCatalog) []string {
+ return []string{"camel:jackson"}
+ },
+ circuitBreakerRegexp: func(_ *camel.RuntimeCatalog) []string {
+ return []string{"camel:hystrix"}
+ },
+ restConfigurationRegexp: func(catalog *camel.RuntimeCatalog) []string {
+ deps := make([]string, 0)
+ if c, ok := catalog.CamelCatalogSpec.Runtime.Capabilities["rest"]; ok {
+ for _, d := range c.Dependencies {
+ deps = append(deps, fmt.Sprintf("mvn:%s/%s", d.GroupID, d.ArtifactID))
+ }
+ }
+ return deps
+ },
+ restRegexp: func(catalog *camel.RuntimeCatalog) []string {
+ deps := make([]string, 0)
+ if c, ok := catalog.CamelCatalogSpec.Runtime.Capabilities["rest"]; ok {
+ for _, d := range c.Dependencies {
+ deps = append(deps, fmt.Sprintf("mvn:%s/%s", d.GroupID, d.ArtifactID))
+ }
+ }
+ return deps
+ },
+ restClosureRegexp: func(catalog *camel.RuntimeCatalog) []string {
+ deps := make([]string, 0)
+ if c, ok := catalog.CamelCatalogSpec.Runtime.Capabilities["rest"]; ok {
+ for _, d := range c.Dependencies {
+ deps = append(deps, fmt.Sprintf("mvn:%s/%s", d.GroupID, d.ArtifactID))
+ }
+ }
+ return deps
+ },
+ groovyLanguageRegexp: func(catalog *camel.RuntimeCatalog) []string {
+ if dependency, ok := catalog.GetLanguageDependency("groovy"); ok {
+ return []string{dependency}
+ }
+
+ return []string{}
+ },
+ jsonPathLanguageRegexp: func(catalog *camel.RuntimeCatalog) []string {
+ if dependency, ok := catalog.GetLanguageDependency("jsonpath"); ok {
+ return []string{dependency}
+ }
+
+ return []string{}
+ },
+ ognlRegexp: func(catalog *camel.RuntimeCatalog) []string {
+ if dependency, ok := catalog.GetLanguageDependency("ognl"); ok {
+ return []string{dependency}
+ }
+
+ return []string{}
+ },
+ mvelRegexp: func(catalog *camel.RuntimeCatalog) []string {
+ if dependency, ok := catalog.GetLanguageDependency("mvel"); ok {
+ return []string{dependency}
+ }
+
+ return []string{}
+ },
+ xqueryRegexp: func(catalog *camel.RuntimeCatalog) []string {
+ if dependency, ok := catalog.GetLanguageDependency("xquery"); ok {
+ return []string{dependency}
+ }
+
+ return []string{}
+ },
+ xpathRegexp: func(catalog *camel.RuntimeCatalog) []string {
+ if dependency, ok := catalog.GetLanguageDependency("xpath"); ok {
+ return []string{dependency}
+ }
+
+ return []string{}
},
- quarkus: map[*regexp.Regexp]string{
- xtokenizeRegexp: "camel-quarkus:core-xml",
+ xtokenizeRegexp: func(catalog *camel.RuntimeCatalog) []string {
+ if dependency, ok := catalog.GetLanguageDependency("xtokenize"); ok {
+ return []string{dependency}
+ }
+
+ return []string{}
},
}
)
@@ -143,14 +210,12 @@ func (i *baseInspector) discoverDependencies(source v1.SourceSpec, meta *Metadat
}
}
- for pattern, dep := range sourceDependencies.main {
- if i.catalog.Runtime.Provider == v1.RuntimeProviderQuarkus {
- // Check whether quarkus has its own artifact that differs from the standard one
- if _, ok := sourceDependencies.quarkus[pattern]; ok {
- dep = sourceDependencies.quarkus[pattern]
- }
+ for pattern, supplier := range sourceDependencies {
+ if !pattern.MatchString(source.Content) {
+ continue
}
- if pattern.MatchString(source.Content) {
+
+ for _, dep := range supplier(i.catalog) {
i.addDependency(dep, meta)
}
}
@@ -192,3 +257,53 @@ func (i *baseInspector) decodeComponent(uri string) string {
}
return ""
}
+
+// hasOnlyPassiveEndpoints returns true if the source has no endpoint that needs to remain always active
+func (i *baseInspector) hasOnlyPassiveEndpoints(fromURIs []string) bool {
+ passivePlusHTTP := make(map[string]bool)
+ i.catalog.VisitSchemes(func(id string, scheme v1.CamelScheme) bool {
+ if scheme.HTTP || scheme.Passive {
+ passivePlusHTTP[id] = true
+ }
+
+ return true
+ })
+
+ return i.containsOnlyURIsIn(fromURIs, passivePlusHTTP)
+}
+
+func (i *baseInspector) containsOnlyURIsIn(fromURI []string, allowed map[string]bool) bool {
+ for _, uri := range fromURI {
+ prefix := i.getURIPrefix(uri)
+ if enabled, ok := allowed[prefix]; !ok || !enabled {
+ return false
+ }
+ }
+ return true
+}
+
+func (i *baseInspector) getURIPrefix(uri string) string {
+ parts := strings.SplitN(uri, ":", 2)
+ if len(parts) > 0 {
+ return parts[0]
+ }
+ return ""
+}
+
+func (i *baseInspector) containsHTTPURIs(fromURI []string) bool {
+ for _, uri := range fromURI {
+ prefix := i.getURIPrefix(uri)
+ scheme, ok := i.catalog.GetScheme(prefix)
+
+ if !ok {
+ // scheme does not exists
+ continue
+ }
+
+ if scheme.HTTP {
+ return true
+ }
+ }
+
+ return false
+}
diff --git a/pkg/util/source/inspector_groovy.go b/pkg/util/source/inspector_groovy.go
index 8ec8823..a37bfc0 100644
--- a/pkg/util/source/inspector_groovy.go
+++ b/pkg/util/source/inspector_groovy.go
@@ -49,5 +49,10 @@ func (i GroovyInspector) Extract(source v1.SourceSpec, meta *Metadata) error {
i.discoverDependencies(source, meta)
+ hasRest := restRegexp.MatchString(source.Content) || restClosureRegexp.MatchString(source.Content)
+
+ meta.ExposesHTTPServices = hasRest || i.containsHTTPURIs(meta.FromURIs)
+ meta.PassiveEndpoints = i.hasOnlyPassiveEndpoints(meta.FromURIs)
+
return nil
}
diff --git a/pkg/util/source/inspector_java_script.go b/pkg/util/source/inspector_java_script.go
index 60e68f3..f79dd3a 100644
--- a/pkg/util/source/inspector_java_script.go
+++ b/pkg/util/source/inspector_java_script.go
@@ -49,5 +49,8 @@ func (i JavaScriptInspector) Extract(source v1.SourceSpec, meta *Metadata) error
i.discoverDependencies(source, meta)
+ meta.ExposesHTTPServices = restRegexp.MatchString(source.Content) || i.containsHTTPURIs(meta.FromURIs)
+ meta.PassiveEndpoints = i.hasOnlyPassiveEndpoints(meta.FromURIs)
+
return nil
}
diff --git a/pkg/util/source/inspector_java_source.go b/pkg/util/source/inspector_java_source.go
index 7b79198..32bd0b0 100644
--- a/pkg/util/source/inspector_java_source.go
+++ b/pkg/util/source/inspector_java_source.go
@@ -45,5 +45,8 @@ func (i JavaSourceInspector) Extract(source v1.SourceSpec, meta *Metadata) error
i.discoverDependencies(source, meta)
+ meta.ExposesHTTPServices = restRegexp.MatchString(source.Content) || i.containsHTTPURIs(meta.FromURIs)
+ meta.PassiveEndpoints = i.hasOnlyPassiveEndpoints(meta.FromURIs)
+
return nil
}
diff --git a/pkg/util/source/inspector_kotlin.go b/pkg/util/source/inspector_kotlin.go
index 44efd09..b949318 100644
--- a/pkg/util/source/inspector_kotlin.go
+++ b/pkg/util/source/inspector_kotlin.go
@@ -45,5 +45,10 @@ func (i KotlinInspector) Extract(source v1.SourceSpec, meta *Metadata) error {
i.discoverDependencies(source, meta)
+ hasRest := restRegexp.MatchString(source.Content) || restClosureRegexp.MatchString(source.Content)
+
+ meta.ExposesHTTPServices = hasRest || i.containsHTTPURIs(meta.FromURIs)
+ meta.PassiveEndpoints = i.hasOnlyPassiveEndpoints(meta.FromURIs)
+
return nil
}
diff --git a/pkg/util/source/inspector_xml.go b/pkg/util/source/inspector_xml.go
index 5ec7b99..48777de 100644
--- a/pkg/util/source/inspector_xml.go
+++ b/pkg/util/source/inspector_xml.go
@@ -45,6 +45,7 @@ func (i XMLInspector) Extract(source v1.SourceSpec, meta *Metadata) error {
switch se.Name.Local {
case "rest", "restConfiguration":
i.addDependency("camel:rest", meta)
+ meta.ExposesHTTPServices = true
case "circuitBreaker":
i.addDependency("camel:hystrix", meta)
case "language":
@@ -77,5 +78,8 @@ func (i XMLInspector) Extract(source v1.SourceSpec, meta *Metadata) error {
i.discoverDependencies(source, meta)
+ meta.ExposesHTTPServices = meta.ExposesHTTPServices || i.containsHTTPURIs(meta.FromURIs)
+ meta.PassiveEndpoints = i.hasOnlyPassiveEndpoints(meta.FromURIs)
+
return nil
}
diff --git a/pkg/util/source/inspector_yaml.go b/pkg/util/source/inspector_yaml.go
index 06a1ce3..e42eb38 100644
--- a/pkg/util/source/inspector_yaml.go
+++ b/pkg/util/source/inspector_yaml.go
@@ -49,6 +49,9 @@ func (inspector YAMLInspector) Extract(source v1.SourceSpec, meta *Metadata) err
inspector.discoverDependencies(source, meta)
+ meta.ExposesHTTPServices = meta.ExposesHTTPServices || inspector.containsHTTPURIs(meta.FromURIs)
+ meta.PassiveEndpoints = inspector.hasOnlyPassiveEndpoints(meta.FromURIs)
+
return nil
}
@@ -56,6 +59,7 @@ func (inspector YAMLInspector) parseStep(key string, content interface{}, meta *
switch key {
case "rest":
inspector.addDependency("camel:rest", meta)
+ meta.ExposesHTTPServices = true
case "circuitBreaker":
inspector.addDependency("camel:hystrix", meta)
}
@@ -126,6 +130,5 @@ func (inspector YAMLInspector) parseStep(key string, content interface{}, meta *
meta.ToURIs = append(meta.ToURIs, maybeURI)
}
}
-
return nil
}
diff --git a/pkg/util/source/types.go b/pkg/util/source/types.go
index 09f727a..1802917 100644
--- a/pkg/util/source/types.go
+++ b/pkg/util/source/types.go
@@ -27,4 +27,20 @@ type Metadata struct {
ToURIs []string
// All inferred dependencies required to run the integration
Dependencies *strset.Set
+ // ExposesHTTPServices indicates if a route defined by the source is exposed
+ // through HTTP
+ ExposesHTTPServices bool
+ // PassiveEndpoints indicates that the source contains only passive endpoints that
+ // are activated from external calls, including HTTP (useful to determine if the
+ // integration can scale to 0)
+ PassiveEndpoints bool
+}
+
+// NewMetadata --
+func NewMetadata() Metadata {
+ return Metadata{
+ FromURIs: make([]string, 0),
+ ToURIs: make([]string, 0),
+ Dependencies: strset.New(),
+ }
}