This is an automated email from the ASF dual-hosted git repository. ningjiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git
commit f311d2856f5b6786d2286fbfffd14e5894bea5c0 Author: liubao <bao....@huawei.com> AuthorDate: Thu May 24 20:51:41 2018 +0800 [SCB-611]Provide a default Dispatcher to make user using edge service easier --- .../servicecomb/demo/edge/consumer/Consumer.java | 8 +- .../demo/edge/consumer/ConsumerMain.java | 6 +- .../src/main/resources/config/log4j.properties | 2 +- .../src/main/resources/microservice.yaml | 8 ++ .../edge/core/DefaultEdgeDispatcher.java | 102 +++++++++++++++++++++ ...cecomb.transport.rest.vertx.VertxHttpDispatcher | 2 +- .../edge/core/TestServiceAndVersionDispatcher.java | 87 ++++++++++++++++++ .../transport/rest/vertx/RestServerVerticle.java | 4 +- .../transport/rest/vertx/VertxHttpDispatcher.java | 4 + .../transport/rest/vertx/VertxRestDispatcher.java | 9 ++ 10 files changed, 224 insertions(+), 8 deletions(-) diff --git a/demo/demo-edge/consumer/src/main/java/org/apache/servicecomb/demo/edge/consumer/Consumer.java b/demo/demo-edge/consumer/src/main/java/org/apache/servicecomb/demo/edge/consumer/Consumer.java index cff8d62..21d581e 100644 --- a/demo/demo-edge/consumer/src/main/java/org/apache/servicecomb/demo/edge/consumer/Consumer.java +++ b/demo/demo-edge/consumer/src/main/java/org/apache/servicecomb/demo/edge/consumer/Consumer.java @@ -78,8 +78,8 @@ public class Consumer { request.setLanguage("zh_CN"); } - public void run() { - prepareEdge(); + public void run(String prefix) { + prepareEdge(prefix); testRecursiveSelf(); testDependType(); @@ -204,12 +204,12 @@ public class Consumer { results.add(result); } - private URIEndpointObject prepareEdge() { + private URIEndpointObject prepareEdge(String prefix) { Microservice microservice = RegistryUtils.getMicroservice(); EndpointsCache endpointsCache = new EndpointsCache(microservice.getAppId(), "edge", "latest", ""); Endpoint ep = endpointsCache.getLatestEndpoints().get(0); URIEndpointObject edgeAddress = (URIEndpointObject) ep.getAddress(); - edgePrefix = String.format("http://%s:%d/api/business", edgeAddress.getHostOrIp(), edgeAddress.getPort()); + edgePrefix = String.format("http://%s:%d/" + prefix + "/business", edgeAddress.getHostOrIp(), edgeAddress.getPort()); return edgeAddress; } diff --git a/demo/demo-edge/consumer/src/main/java/org/apache/servicecomb/demo/edge/consumer/ConsumerMain.java b/demo/demo-edge/consumer/src/main/java/org/apache/servicecomb/demo/edge/consumer/ConsumerMain.java index d8bd6c4..9a91656 100644 --- a/demo/demo-edge/consumer/src/main/java/org/apache/servicecomb/demo/edge/consumer/ConsumerMain.java +++ b/demo/demo-edge/consumer/src/main/java/org/apache/servicecomb/demo/edge/consumer/ConsumerMain.java @@ -25,6 +25,10 @@ public class ConsumerMain { Log4jUtils.init(); BeanUtils.init(); - new Consumer().run(); + System.out.println("Running api dispater."); + new Consumer().run("api"); + System.out.println("Running rest dispater."); + new Consumer().run("rest"); + } } diff --git a/demo/demo-edge/edge-service/src/main/resources/config/log4j.properties b/demo/demo-edge/edge-service/src/main/resources/config/log4j.properties index dd0a080..3fc9f8b 100644 --- a/demo/demo-edge/edge-service/src/main/resources/config/log4j.properties +++ b/demo/demo-edge/edge-service/src/main/resources/config/log4j.properties @@ -15,4 +15,4 @@ # limitations under the License. # -log4j.rootLogger=DEBUG,stdout +log4j.rootLogger=INFO,stdout diff --git a/demo/demo-edge/edge-service/src/main/resources/microservice.yaml b/demo/demo-edge/edge-service/src/main/resources/microservice.yaml index f6161c3..27b17db 100644 --- a/demo/demo-edge/edge-service/src/main/resources/microservice.yaml +++ b/demo/demo-edge/edge-service/src/main/resources/microservice.yaml @@ -37,3 +37,11 @@ servicecomb: auth: loadbalance executors: default: cse.executor.groupThreadPool + http: + dispatcher: + edge: + default: + enabled: true + prefix: rest + withVersion: true + pathIndex: 2 diff --git a/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/DefaultEdgeDispatcher.java b/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/DefaultEdgeDispatcher.java new file mode 100644 index 0000000..3070240 --- /dev/null +++ b/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/DefaultEdgeDispatcher.java @@ -0,0 +1,102 @@ +/* + * 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.servicecomb.edge.core; + +import java.util.Map; + +import com.netflix.config.DynamicPropertyFactory; + +import io.vertx.ext.web.Router; +import io.vertx.ext.web.RoutingContext; +import io.vertx.ext.web.handler.CookieHandler; + +/** + * Provide an easy mapping dispatcher. User can configure prefix to easily using edge service. + */ +public class DefaultEdgeDispatcher extends AbstractEdgeDispatcher { + private static final String KEY_ENABLED = "servicecomb.http.dispatcher.edge.default.enabled"; + + private static final String KEY_PREFIX = "servicecomb.http.dispatcher.edge.default.prefix"; + + private static final String KEY_WITH_VERSION = "servicecomb.http.dispatcher.edge.default.withVersion"; + + private static final String KEY_PATH_INDEX = "servicecomb.http.dispatcher.edge.default.pathIndex"; + + private CompatiblePathVersionMapper versionMapper = new CompatiblePathVersionMapper(); + + private String prefix; + + private boolean withVersion; + + private int pathIndex; + + @Override + public int getOrder() { + return 20000; + } + + @Override + public boolean enabled() { + return DynamicPropertyFactory.getInstance().getBooleanProperty(KEY_ENABLED, false).get(); + } + + @Override + public void init(Router router) { + prefix = DynamicPropertyFactory.getInstance().getStringProperty(KEY_PREFIX, "api").get(); + withVersion = DynamicPropertyFactory.getInstance().getBooleanProperty(KEY_WITH_VERSION, true).get(); + pathIndex = DynamicPropertyFactory.getInstance().getIntProperty(KEY_PATH_INDEX, 2).get(); + String regex; + if (withVersion) { + regex = "/" + prefix + "/([^\\\\/]+)/([^\\\\/]+)/(.*)"; + } else { + regex = "/" + prefix + "/([^\\\\/]+)/(.*)"; + } + router.routeWithRegex(regex).handler(CookieHandler.create()); + router.routeWithRegex(regex).handler(createBodyHandler()); + router.routeWithRegex(regex).failureHandler(this::onFailure).handler(this::onRequest); + } + + protected void onRequest(RoutingContext context) { + Map<String, String> pathParams = context.pathParams(); + String microserviceName = pathParams.get("param0"); + String path = findActualPath(context.request().path()); + + EdgeInvocation edgeInvocation = new EdgeInvocation(); + if (withVersion) { + String pathVersion = pathParams.get("param1"); + edgeInvocation.setVersionRule(versionMapper.getOrCreate(pathVersion).getVersionRule()); + } + edgeInvocation.init(microserviceName, context, path, httpServerFilters); + edgeInvocation.edgeInvoke(); + } + + protected String findActualPath(String path) { + int fromIndex = 0; + int counter = pathIndex; + char[] chars = path.toCharArray(); + for (int i = 0; i < chars.length; i++) { + if (chars[i] == '/') { + if (--counter <= 0) { + fromIndex = i; + break; + } + } + } + return path.substring(fromIndex > 0 ? fromIndex : 0); + } +} diff --git a/demo/demo-edge/edge-service/src/main/resources/config/log4j.properties b/edge/edge-core/src/main/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.VertxHttpDispatcher similarity index 93% copy from demo/demo-edge/edge-service/src/main/resources/config/log4j.properties copy to edge/edge-core/src/main/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.VertxHttpDispatcher index dd0a080..cc2856f 100644 --- a/demo/demo-edge/edge-service/src/main/resources/config/log4j.properties +++ b/edge/edge-core/src/main/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.VertxHttpDispatcher @@ -15,4 +15,4 @@ # limitations under the License. # -log4j.rootLogger=DEBUG,stdout +org.apache.servicecomb.edge.core.DefaultEdgeDispatcher \ No newline at end of file diff --git a/edge/edge-core/src/test/java/org/apache/servicecomb/edge/core/TestServiceAndVersionDispatcher.java b/edge/edge-core/src/test/java/org/apache/servicecomb/edge/core/TestServiceAndVersionDispatcher.java new file mode 100644 index 0000000..fb36df9 --- /dev/null +++ b/edge/edge-core/src/test/java/org/apache/servicecomb/edge/core/TestServiceAndVersionDispatcher.java @@ -0,0 +1,87 @@ +/* + * 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.servicecomb.edge.core; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.servicecomb.foundation.test.scaffolding.config.ArchaiusUtils; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import io.vertx.core.Handler; +import io.vertx.core.http.HttpServerRequest; +import io.vertx.ext.web.Route; +import io.vertx.ext.web.Router; +import io.vertx.ext.web.RoutingContext; +import mockit.Deencapsulation; +import mockit.Expectations; +import mockit.Mocked; + +public class TestServiceAndVersionDispatcher { + @Before + public void setUp() { + + } + + @After + public void tearDown() { + ArchaiusUtils.resetConfig(); + } + + @Test + public void testOnRequest(@Mocked Router router, @Mocked Route route + , @Mocked RoutingContext context + , @Mocked HttpServerRequest requst + , @Mocked EdgeInvocation invocation) { + DefaultEdgeDispatcher dispatcher = new DefaultEdgeDispatcher(); + Map<String, String> pathParams = new HashMap<>(); + pathParams.put("param0", "testService"); + pathParams.put("param1", "v1"); + + new Expectations() { + { + router.routeWithRegex("/api/([^\\\\/]+)/([^\\\\/]+)/(.*)"); + result = route; + route.handler((Handler<RoutingContext>) any); + result = route; + route.failureHandler((Handler<RoutingContext>) any); + result = route; + context.pathParams(); + result = pathParams; + context.request(); + result = requst; + requst.path(); + result = "/api/testService/v1/hello"; + invocation.setVersionRule("1.0.0-2.0.0"); + invocation.init("testService", context, "/testService/v1/hello", + Deencapsulation.getField(dispatcher, "httpServerFilters")); + invocation.edgeInvoke(); + } + }; + dispatcher.init(router); + Assert.assertEquals(dispatcher.enabled(), false); + Assert.assertEquals(dispatcher.findActualPath("/api/test"), "/test"); + Assert.assertEquals(dispatcher.getOrder(), 20000); + + dispatcher.onRequest(context); + // assert done in expectations. + } +} diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/RestServerVerticle.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/RestServerVerticle.java index a3bd7e8..3866827 100644 --- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/RestServerVerticle.java +++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/RestServerVerticle.java @@ -100,7 +100,9 @@ public class RestServerVerticle extends AbstractVerticle { private void initDispatcher(Router mainRouter) { List<VertxHttpDispatcher> dispatchers = SPIServiceUtils.getSortedService(VertxHttpDispatcher.class); for (VertxHttpDispatcher dispatcher : dispatchers) { - dispatcher.init(mainRouter); + if(dispatcher.enabled()) { + dispatcher.init(mainRouter); + } } } diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/VertxHttpDispatcher.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/VertxHttpDispatcher.java index 6e62b14..cc8b6dc 100644 --- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/VertxHttpDispatcher.java +++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/VertxHttpDispatcher.java @@ -22,5 +22,9 @@ import io.vertx.ext.web.Router; public interface VertxHttpDispatcher { int getOrder(); + default boolean enabled() { + return true; + } + void init(Router router); } diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/VertxRestDispatcher.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/VertxRestDispatcher.java index 0d0c0e6..7e7eab5 100644 --- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/VertxRestDispatcher.java +++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/VertxRestDispatcher.java @@ -36,6 +36,8 @@ import org.apache.servicecomb.swagger.invocation.exception.InvocationException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.netflix.config.DynamicPropertyFactory; + import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder.ErrorDataDecoderException; import io.vertx.core.json.JsonObject; import io.vertx.ext.web.Router; @@ -45,6 +47,8 @@ import io.vertx.ext.web.handler.CookieHandler; public class VertxRestDispatcher extends AbstractVertxHttpDispatcher { private static final Logger LOGGER = LoggerFactory.getLogger(VertxRestDispatcher.class); + private static final String KEY_ENABLED = "servicecomb.http.dispatcher.rest.enabled"; + private Transport transport; @Override @@ -53,6 +57,11 @@ public class VertxRestDispatcher extends AbstractVertxHttpDispatcher { } @Override + public boolean enabled() { + return DynamicPropertyFactory.getInstance().getBooleanProperty(KEY_ENABLED, true).get(); + } + + @Override public void init(Router router) { router.route().handler(CookieHandler.create()); router.route().handler(createBodyHandler()); -- To stop receiving notification emails like this one, please contact ningji...@apache.org.