之前已经完成了 Camel K Platform 的部署与 Demo 运行,现在需要一些更符合实际场景的路由逻辑

本文的平台基于 camel-k master 分支构建
Camel K Platform 搭建参考文章:部署 Apache Camel K | 从 master 分支源码构建并部署 Camel K 平台

基于 Maven 引入包含外部依赖的 Demo

有个 demo 文件:myexamples/NettyHttpDemoRoute.java

package vip.wuweijie.demo.camel.routes;

import com.zhaofujun.automapper.AutoMapper;
import io.netty.handler.codec.http.HttpHeaderNames;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.netty.http.NettyHttpMessage;
import java.util.Date;

public class NettyHttpDemoRoute extends RouteBuilder {
    @Override
    public void configure() throws Exception {
        from("netty-http:http://0.0.0.0:8765")
                .to("mock:root")
                .process(exchange -> {
                    NettyHttpMessage in = exchange.getIn(NettyHttpMessage.class);
                    String ua = in.getHeader(HttpHeaderNames.USER_AGENT.toString(), String.class);
                    System.out.println("UA => " + ua);
                    HR hr = new HR(ua);
                    System.out.println(hr);
                    AutoMapper autoMapper = new AutoMapper();
                    autoMapper.mapping(HR.class, UA.class, false)
                            .field("userAgent", "value");
                    UA uaObject = autoMapper.map(hr, UA.class);
                    System.out.println(uaObject);
                })
                .to("log:netty-http-demo?showAll=true")
                .transform()
                .constant(new Date())
        ;
    }

    public static class HR {
        private final String userAgent;
        public HR(String userAgent) {
            this.userAgent = userAgent;
        }
        @Override
        public String toString() {
            return "HR{" +
                    "userAgent='" + userAgent + '\'' +
                    '}';
        }
        public String getUserAgent() {
            return userAgent;
        }
    }

    public static class UA {
        private String value;
        @Override
        public String toString() {
            return "UA{" +
                    "value='" + value + '\'' +
                    '}';
        }
        public String getValue() {
            return value;
        }
        public void setValue(String value) {
            this.value = value;
        }
    }
}

参数说明:

  • -d mvn:com.zhaofujun.automapper:automapper:1.0.release:表示通过 maven 引入依赖 com.zhaofujun.automapper:automapper:1.0.release
  • --dev:调试模式
  • -n camel-k:在 namespace camel-k 执行
    执行 demo:
kamel run myexamples/NettyHttpDemoRoute.java -d mvn:com.zhaofujun.automapper:automapper:1.0.release --dev -n camel-k

输出结果:

integration "netty-http-demo-route" created
Progress: integration "netty-http-demo-route" in phase Initialization
Integration netty-http-demo-route in phase Initialization
IntegrationPlatformAvailable for Integration netty-http-demo-route: camel-k
Progress: integration "netty-http-demo-route" in phase Building Kit
No IntegrationKitAvailable for Integration netty-http-demo-route: creating a new integration kit
Integration netty-http-demo-route in phase Building Kit
Progress: integration "netty-http-demo-route" in phase Deploying
IntegrationKitAvailable for Integration netty-http-demo-route: kit-bptcaf2o1songb4m7pag
Integration netty-http-demo-route in phase Deploying
Progress: integration "netty-http-demo-route" in phase Running
No CronJobAvailable for Integration netty-http-demo-route: different controller strategy used (deployment)
DeploymentAvailable for Integration netty-http-demo-route: deployment name is netty-http-demo-route
No ExposureAvailable for Integration netty-http-demo-route: no host or service defined
ServiceAvailable for Integration netty-http-demo-route: netty-http-demo-route(http/80) -> integration(http/8080)
Integration netty-http-demo-route in phase Running
[1] Monitoring pod netty-http-demo-route-8455456854-gsbpl[1] 2020-03-25 02:46:38.910 INFO  [main] LRUCacheFactory - Detected and using LURCacheFactory: camel-caffeine-lrucache
[1] 2020-03-25 02:46:38.964 INFO  [main] ApplicationRuntime - Add listener: org.apache.camel.k.listener.RuntimeConfigurer@692f203f
[1] 2020-03-25 02:46:38.965 INFO  [main] ApplicationRuntime - Add listener: org.apache.camel.k.listener.ContextConfigurer@a1153bc
[1] 2020-03-25 02:46:38.965 INFO  [main] ApplicationRuntime - Add listener: org.apache.camel.k.listener.RoutesConfigurer@3270d194
[1] 2020-03-25 02:46:38.965 INFO  [main] ApplicationRuntime - Add listener: org.apache.camel.k.listener.RoutesDumper@4218d6a3
[1] 2020-03-25 02:46:38.966 INFO  [main] ApplicationRuntime - Add listener: org.apache.camel.k.listener.PropertiesFunctionsConfigurer@71d44a3
[1] 2020-03-25 02:46:38.971 INFO  [main] ApplicationRuntime - Listener org.apache.camel.k.listener.RuntimeConfigurer@692f203f executed in phase Starting
[1] 2020-03-25 02:46:38.974 INFO  [main] ApplicationRuntime - Listener org.apache.camel.k.listener.PropertiesFunctionsConfigurer@71d44a3 executed in phase Starting
[1] 2020-03-25 02:46:38.975 INFO  [main] BaseMainSupport - Using properties from: 
[1] 2020-03-25 02:46:38.980 INFO  [main] RuntimeSupport - Looking up loader for language: java
[1] 2020-03-25 02:46:38.981 INFO  [main] RuntimeSupport - Found loader org.apache.camel.k.loader.java.JavaSourceLoader@489115ef for language java from service definition
[1] 2020-03-25 02:46:39.294 INFO  [main] RoutesConfigurer - Loading routes from: file:/etc/camel/sources/i-source-000/NettyHttpDemoRoute.java?language=java
[1] 2020-03-25 02:46:39.294 INFO  [main] ApplicationRuntime - Listener org.apache.camel.k.listener.RoutesConfigurer@3270d194 executed in phase ConfigureRoutes
[1] 2020-03-25 02:46:39.345 INFO  [main] ApplicationRuntime - Listener org.apache.camel.k.listener.ContextConfigurer@a1153bc executed in phase ConfigureContext
[1] 2020-03-25 02:46:39.346 INFO  [main] AbstractCamelContext - Apache Camel 3.1.0 (CamelContext: camel-k) is starting
[1] 2020-03-25 02:46:39.347 INFO  [main] DefaultManagementStrategy - JMX is disabled
[1] 2020-03-25 02:46:39.348 INFO  [main] HeadersMapFactoryResolver - Detected and using HeadersMapFactory: camel-headersmap
[1] 2020-03-25 02:46:39.431 INFO  [main] NettyComponent - Creating shared NettyConsumerExecutorGroup with 3 threads
[1] 2020-03-25 02:46:39.460 INFO  [main] AbstractCamelContext - StreamCaching is not in use. If using streams then its recommended to enable stream caching. See more details at http://camel.apache.org/stream-caching.html
[1] 2020-03-25 02:46:39.474 INFO  [main] HttpServerBootstrapFactory - BootstrapFactory on port 8765 is using bootstrap configuration: [NettyServerBootstrapConfiguration{protocol='http', host='0.0.0.0', port=8765, broadcast=false, sendBufferSize=65536, receiveBufferSize=65536, receiveBufferSizePredictor=0, workerCount=0, bossCount=1, keepAlive=true, tcpNoDelay=true, reuseAddress=true, connectTimeout=10000, backlog=0, serverInitializerFactory=org.apache.camel.component.netty.http.HttpServerInitializerFactory@52500920, nettyServerBootstrapFactory=null, options=null, ssl=false, sslHandler=null, sslContextParameters='null', needClientAuth=false, enabledProtocols='TLSv1,TLSv1.1,TLSv1.2, keyStoreFile=null, trustStoreFile=null, keyStoreResource='null', trustStoreResource='null', keyStoreFormat='JKS', securityProvider='SunX509', passphrase='null', bossGroup=null, workerGroup=null, networkInterface='null', reconnect='true', reconnectInterval='10000'}]
[1] 2020-03-25 02:46:39.489 INFO  [main] SingleTCPNettyServerBootstrapFactory - ServerBootstrap binding to 0.0.0.0:8765
[1] 2020-03-25 02:46:39.521 INFO  [main] NettyConsumer - Netty consumer bound to: 0.0.0.0:8765
[1] 2020-03-25 02:46:39.522 INFO  [main] AbstractCamelContext - Route: route1 started and consuming from: http://0.0.0.0:8765
[1] 2020-03-25 02:46:39.525 INFO  [main] AbstractCamelContext - Total 1 routes, of which 1 are started
[1] 2020-03-25 02:46:39.526 INFO  [main] AbstractCamelContext - Apache Camel 3.1.0 (CamelContext: camel-k) started in 0.179 seconds
[1] 2020-03-25 02:46:39.526 INFO  [main] ApplicationRuntime - Listener org.apache.camel.k.listener.RoutesDumper@4218d6a3 executed in phase Started
[1] UA => curl/7.58.0
[1] HR{userAgent='curl/7.58.0'}
[1] 2020-03-25 02:46:49.893 INFO  [Camel (camel-k) thread #4 - NettyConsumerExecutorGroup] FieldMapping - 在源类型vip.wuweijie.demo.camel.routes.NettyHttpDemoRoute$HR中没有找到同名字段value
[1] UA{value='curl/7.58.0'}
[1] 2020-03-25 02:46:49.900 INFO  [Camel (camel-k) thread #4 - NettyConsumerExecutorGroup] netty-http-demo - Exchange[Id: ID-netty-http-demo-route-8455456854-gsbpl-1585104409889-0-1, ExchangePattern: InOut, Properties: {CamelToEndpoint=log://netty-http-demo?showAll=true}, Headers: {Accept=*/*, CamelHttpHost=null, CamelHttpMethod=GET, CamelHttpPath=/, CamelHttpPort=80, CamelHttpQuery=null, CamelHttpRawQuery=null, CamelHttpScheme=null, CamelHttpUri=/, CamelHttpUrl=http://0.0.0.0:8765/, CamelNettyChannelHandlerContext=ChannelHandlerContext(handler, [id: 0x78ef6f64, L:/10.240.0.64:8765 - R:/10.240.0.1:56354]), CamelNettyLocalAddress=/10.240.0.64:8765, CamelNettyRemoteAddress=/10.240.0.1:56354, content-length=0, Host=10.240.0.64:8765, User-Agent=curl/7.58.0}, BodyType: org.apache.camel.component.netty.http.NettyChannelBufferStreamCache, Body: [Body is instance of org.apache.camel.StreamCache]]

通过输出结果可以看到,路由能够正常工作。

运行一个项目的路由

一般一个集成项目不会只有一个文件,所以需要一种运行多个文件或者一个项目的方式。官方文档在这方面并没有提及什么,而且在 kamel run --help 中,参数说明用的是 [file to run],可能会让人误认为只能够支持单个文件。

Initialize empty Camel K integrations and other resources.

Usage:
  kamel init [flags]

Flags:
  -h, --help   help for init

Global Flags:
      --config string      Path to the config file to use for CLI requests
  -n, --namespace string   Namespace to use for all operations
sia@server-sia:~/GolandProjects/camel-k$ ./kamel run --help
Deploys and execute a integration pod on Kubernetes.

Usage:
  kamel run [file to run] [flags]

Flags:
      --compression                    Enable store source as a compressed binary blob
      --configmap stringArray          Add a ConfigMap
  -d, --dependency stringArray         The integration dependency
      --dev                            Enable Dev mode (equivalent to "-w --logs --sync")
  -e, --env stringArray                Set an environment variable in the integration container. E.g "-e MY_VAR=my-value"
  -h, --help                           help for run
  -k, --kit string                     The kit used to run the integration
      --label stringArray              Add a label to the integration. E.g. "--label my.company=hello"
      --logging-level stringArray      Configure the logging level. e.g. "--logging-level org.apache.camel=DEBUG"
      --logs                           Print integration logs
      --maven-repository stringArray   Add a maven repository
      --name string                    The integration name
      --open-api stringArray           Add an OpenAPI v2 spec
  -o, --output string                  Output format. One of: json|yaml
      --profile string                 Trait profile used for deployment
  -p, --property stringArray           Add a camel property
      --property-file stringArray      Bind a property file to the integration. E.g. "--property-file integration.properties"
      --resource stringArray           Add a resource
      --save                           Save the run parameters into the default kamel configuration file (kamel-config.yaml)
      --secret stringArray             Add a Secret
      --sync                           Synchronize the local source file with the cluster, republishing at each change
  -t, --trait stringArray              Configure a trait. E.g. "-t service.enabled=false"
  -v, --volume stringArray             Mount a volume into the integration container. E.g "-v pvcname:/container/path"
  -w, --wait                           Waits for the integration to be running

Global Flags:
      --config string      Path to the config file to use for CLI requests
  -n, --namespace string   Namespace to use for all operations

kamel run 指定多个文件

kamel run 命令可以指定多个文件,看了源码还支持 http 协议获取文件

kamel run examples/Sample0.java examples/Sample1.java examples/Sample2.java -ncamel-k -k kit-bpu59tjdk85h2k4pl6i0

运行一整个项目

相关 Issue:How can I run a whole project with many integration files in a comfortable way?

根据回复,单次运行包含大量路由文件的项目不在 Camel K 的设计理念中,考虑通过打包作为依赖的方式运行项目。

附:kamel run 源码解读

pkg/cmd/run.go 源码节选:

func (o *runCmdOptions) validateArgs(_ *cobra.Command, args []string) error {
	if len(args) < 1 {
		return errors.New("run expects at least 1 argument, received 0")
	}

	for _, fileName := range args {
		if !isRemoteHTTPFile(fileName) {
			if _, err := os.Stat(fileName); err != nil && os.IsNotExist(err) {
				return errors.Wrap(err, "file "+fileName+" does not exist")
			} else if err != nil {
				return errors.Wrap(err, "error while accessing file "+fileName)
			}
		} else {
			// nolint: gosec
			resp, err := http.Get(fileName)
			if resp != nil && resp.Body != nil {
				resp.Body.Close()
			}

			if err != nil {
				return errors.Wrap(err, "The URL provided is not reachable")
			} else if resp.StatusCode != 200 {
				return errors.New("The URL provided is not reachable " + fileName + " The error code returned is " + strconv.Itoa(resp.StatusCode))
			}
		}
	}

	return nil
}

可见,Camel K 支持:

  • 单次执行可以挂载多个文件
  • 支持通过 http 协议运行文件
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐