This is an automated email from the ASF dual-hosted git repository. lburgazzoli pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel.git
commit 7539ed6e811b3d786e3374d5c43658a1c899d6a6 Author: lburgazzoli <lburgazz...@gmail.com> AuthorDate: Fri May 11 12:33:33 2018 +0200 CAMEL-12505: service-call : include ServiceDefinition metatdata when computing the final URI --- .../impl/cloud/DefaultServiceCallProcessor.java | 75 +++++++----- .../ConsulServiceCallWithRegistrationTest.java | 133 +++++++++++++++++++++ ...RegistrationWithRoutePolicyAndMetadataTest.java | 40 +++++++ 3 files changed, 218 insertions(+), 30 deletions(-) diff --git a/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultServiceCallProcessor.java b/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultServiceCallProcessor.java index 78a900e..f6b5cbf 100644 --- a/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultServiceCallProcessor.java +++ b/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultServiceCallProcessor.java @@ -16,6 +16,8 @@ */ package org.apache.camel.impl.cloud; +import java.util.Map; + import org.apache.camel.AsyncCallback; import org.apache.camel.AsyncProcessor; import org.apache.camel.CamelContext; @@ -154,31 +156,17 @@ public class DefaultServiceCallProcessor extends ServiceSupport implements Async @Override public boolean process(final Exchange exchange, final AsyncCallback callback) { - Message message = exchange.getIn(); + final Message message = exchange.getIn(); // the values can be dynamic using simple language so compute those - String val = uri; - if (SimpleLanguage.hasSimpleFunction(val)) { - val = SimpleLanguage.simple(val).evaluate(exchange, String.class); - } - message.setHeader(ServiceCallConstants.SERVICE_CALL_URI, val); - - val = contextPath; - if (SimpleLanguage.hasSimpleFunction(val)) { - val = SimpleLanguage.simple(val).evaluate(exchange, String.class); - } - message.setHeader(ServiceCallConstants.SERVICE_CALL_CONTEXT_PATH, val); - - val = scheme; - if (SimpleLanguage.hasSimpleFunction(val)) { - val = SimpleLanguage.simple(val).evaluate(exchange, String.class); - } - message.setHeader(ServiceCallConstants.SERVICE_CALL_SCHEME, val); - - String serviceName = name; - if (SimpleLanguage.hasSimpleFunction(serviceName)) { - serviceName = SimpleLanguage.simple(serviceName).evaluate(exchange, String.class); - } + final String serviceName = applySimpleLanguage(name, exchange); + final String serviceUri = applySimpleLanguage(uri, exchange); + final String servicePath = applySimpleLanguage(contextPath, exchange); + final String serviceScheme = applySimpleLanguage(scheme, exchange); + + message.setHeader(ServiceCallConstants.SERVICE_CALL_URI,serviceUri); + message.setHeader(ServiceCallConstants.SERVICE_CALL_CONTEXT_PATH, servicePath); + message.setHeader(ServiceCallConstants.SERVICE_CALL_SCHEME, serviceScheme); message.setHeader(ServiceCallConstants.SERVICE_NAME, serviceName); try { @@ -189,19 +177,46 @@ public class DefaultServiceCallProcessor extends ServiceSupport implements Async } } - private boolean execute(ServiceDefinition server, Exchange exchange, AsyncCallback callback) throws Exception { - String host = server.getHost(); - int port = server.getPort(); + private boolean execute(ServiceDefinition service, Exchange exchange, AsyncCallback callback) throws Exception { + final Message message = exchange.getIn(); + final String host = service.getHost(); + final int port = service.getPort(); + final Map<String, String> meta = service.getMetadata(); LOGGER.debug("Service {} active at server: {}:{}", name, host, port); // set selected server as header - exchange.getIn().setHeader(ServiceCallConstants.SERVICE_HOST, host); - exchange.getIn().setHeader(ServiceCallConstants.SERVICE_PORT, port > 0 ? port : null); - exchange.getIn().setHeader(ServiceCallConstants.SERVICE_NAME, server.getName()); - exchange.getIn().setHeader(ServiceCallConstants.SERVICE_META, server.getMetadata()); + message.setHeader(ServiceCallConstants.SERVICE_HOST, host); + message.setHeader(ServiceCallConstants.SERVICE_PORT, port > 0 ? port : null); + message.setHeader(ServiceCallConstants.SERVICE_NAME, service.getName()); + message.setHeader(ServiceCallConstants.SERVICE_META, meta); + + // If context path is not set on service call definition, reuse the one from + // ServiceDefinition, if any + message.getHeaders().compute(ServiceCallConstants.SERVICE_CALL_CONTEXT_PATH, (k, v) -> + v == null ? meta.get(ServiceDefinition.SERVICE_META_PATH) : v + ); + + // If port is not set on service call definition, reuse the one from + // ServiceDefinition, if any + message.getHeaders().compute(ServiceCallConstants.SERVICE_PORT, (k, v) -> + v == null ? meta.get(ServiceDefinition.SERVICE_META_PORT) : v + ); // use the dynamic send processor to call the service return processor.process(exchange, callback); } + + /** + * This function applies the simple language to the given expression. + * + * @param expression the expression + * @param exchange the exchange + * @return the computed expression + */ + private String applySimpleLanguage(String expression, Exchange exchange) { + return SimpleLanguage.hasSimpleFunction(expression) + ? SimpleLanguage.simple(expression).evaluate(exchange, String.class) + : expression; + } } diff --git a/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulServiceCallWithRegistrationTest.java b/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulServiceCallWithRegistrationTest.java new file mode 100644 index 0000000..b0efaab --- /dev/null +++ b/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulServiceCallWithRegistrationTest.java @@ -0,0 +1,133 @@ +/** + * 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 org.apache.camel.component.consul.cloud; + +import java.util.UUID; + +import org.apache.camel.CamelContext; +import org.apache.camel.CamelExecutionException; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.consul.support.ConsulTestSupport; +import org.apache.camel.impl.cloud.ServiceRegistrationRoutePolicy; +import org.junit.Test; +import org.springframework.util.SocketUtils; + +public class ConsulServiceCallWithRegistrationTest extends ConsulTestSupport { + private final static String SERVICE_HOST = "localhost"; + + // ****************************** + // Setup / tear down + // ****************************** + + @Override + public boolean isUseRouteBuilder() { + return false; + } + + @Override + protected CamelContext createCamelContext() throws Exception { + final CamelContext context = super.createCamelContext(); + + ConsulServiceRegistry registry = new ConsulServiceRegistry(); + registry.setId(context.getUuidGenerator().generateUuid()); + registry.setCamelContext(context()); + registry.setUrl(consulUrl()); + registry.setServiceHost(SERVICE_HOST); + registry.setOverrideServiceHost(true); + + context.addService(registry, true, false); + + return context; + } + + // ****************************** + // Test + // ****************************** + + @Test + public void testServiceCallSuccess() throws Exception { + final int port = SocketUtils.findAvailableTcpPort(); + final String serviceId = UUID.randomUUID().toString(); + final String serviceName = UUID.randomUUID().toString(); + + context.addRoutes(new RouteBuilder() { + @Override + public void configure() throws Exception { + // context path is derived from the the jetty endpoint. + from("direct:start") + .serviceCall() + .name(serviceName) + .component("jetty") + .defaultLoadBalancer() + .consulServiceDiscovery() + .url(consulUrl()) + .end() + .end() + .log("${body}"); + + fromF("jetty:http://%s:%d/service/path", SERVICE_HOST, port) + .routeId(serviceId) + .routeGroup(serviceName) + .routePolicy(new ServiceRegistrationRoutePolicy()) + .transform() + .simple("${in.body} on " + port); + } + }); + + context.start(); + + assertEquals("ping on " + port, template.requestBody("direct:start", "ping", String.class)); + } + + @Test(expected = CamelExecutionException.class) + public void testServiceCallFailure() throws Exception { + final int port = SocketUtils.findAvailableTcpPort(); + final String serviceId = UUID.randomUUID().toString(); + final String serviceName = UUID.randomUUID().toString(); + + context.addRoutes(new RouteBuilder() { + @Override + public void configure() throws Exception { + // context path is had coded so it should fail as it not exposed + // by jetty + from("direct:start") + .serviceCall() + .name(serviceName + "/bad/path") + .component("jetty") + .defaultLoadBalancer() + .consulServiceDiscovery() + .url(consulUrl()) + .end() + .end() + .log("${body}"); + + fromF("jetty:http://%s:%d/service/path", SERVICE_HOST, port) + .routeId(serviceId) + .routeGroup(serviceName) + .routePolicy(new ServiceRegistrationRoutePolicy()) + .transform() + .simple("${in.body} on " + port); + } + }); + + context.start(); + + template.requestBody("direct:start", "ping", String.class); + fail("Should have failed"); + } +} diff --git a/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulServiceRegistrationWithRoutePolicyAndMetadataTest.java b/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulServiceRegistrationWithRoutePolicyAndMetadataTest.java new file mode 100644 index 0000000..1f9bafd --- /dev/null +++ b/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulServiceRegistrationWithRoutePolicyAndMetadataTest.java @@ -0,0 +1,40 @@ +/** + * 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 org.apache.camel.component.consul.cloud; + +import org.apache.camel.RoutesBuilder; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.cloud.ServiceDefinition; +import org.apache.camel.impl.cloud.ServiceRegistrationRoutePolicy; + +public class ConsulServiceRegistrationWithRoutePolicyAndMetadataTest extends ConsulServiceRegistrationTestBase { + @Override + protected RoutesBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + fromF("jetty:http://0.0.0.0:%d/service/endpoint", SERVICE_PORT) + .routeId(SERVICE_ID) + .routeProperty(ServiceDefinition.SERVICE_META_ID, SERVICE_ID) + .routeProperty(ServiceDefinition.SERVICE_META_NAME, SERVICE_NAME) + .routePolicy(new ServiceRegistrationRoutePolicy()) + .noAutoStartup() + .to("log:service-registry?level=INFO"); + } + }; + } +} -- To stop receiving notification emails like this one, please contact lburgazz...@apache.org.