This is an automated email from the ASF dual-hosted git repository. wujimin pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git
The following commit(s) were added to refs/heads/master by this push: new 76fe676 [SCB-2169] optimize filter declare and chain config 76fe676 is described below commit 76fe676dad6d0aa12d77019246d0ea9c19eeb878 Author: wujimin <wuji...@huawei.com> AuthorDate: Tue Dec 22 10:03:16 2020 +0800 [SCB-2169] optimize filter declare and chain config --- .../rest/filter/inner/RestServerCodecFilter.java | 18 ++- .../src/test/resources/microservice.yaml | 7 +- .../org/apache/servicecomb/core/SCBEngine.java | 5 +- .../core/bootstrap/SCBEngineForTest.java | 14 +- .../core/definition/ServiceRegistryListener.java | 2 +- .../servicecomb/core/filter/ConsumerFilter.java | 16 +- .../org/apache/servicecomb/core/filter/Filter.java | 24 ++- .../core/filter/FilterChainsManager.java | 123 +++++----------- .../servicecomb/core/filter/FilterManager.java | 162 --------------------- .../apache/servicecomb/core/filter/FilterMeta.java | 50 ------- .../apache/servicecomb/core/filter/FilterNode.java | 2 +- .../{FilterProvider.java => InternalFilter.java} | 5 +- .../core/filter/InvocationFilterChains.java | 113 ++++++++++++++ .../servicecomb/core/filter/ProducerFilter.java | 19 ++- .../filter/config/AbstractFilterChainsConfig.java | 24 +-- .../core/filter/config/FilterChainsConfig.java | 95 +++++++----- .../config/InvocationFilterChainsConfig.java | 69 +++++++++ ...ilterConfig.java => TransportChainsConfig.java} | 14 +- .../core/filter/config/TransportFiltersConfig.java | 54 ------- ...DefaultFilterProvider.java => EmptyFilter.java} | 28 ++-- .../core/filter/impl/ParameterValidatorFilter.java | 25 ++-- .../core/filter/impl/ProducerOperationFilter.java | 22 +-- .../core/filter/impl/ScheduleFilter.java | 20 ++- .../core/filter/impl/SimpleLoadBalanceFilter.java | 110 ++++++++------ .../core/filter/impl/TransportFilters.java | 22 ++- core/src/main/resources/microservice.yaml | 19 ++- .../core/filter/FilterChainsManagerTest.java | 103 ------------- .../servicecomb/core/filter/SimpleRetryFilter.java | 11 +- .../filter/impl/ParameterValidatorFilterTest.java | 2 +- .../demo/pojo/client/CodeFirstPojoClient.java | 20 +-- .../src/test/resources/microservice.yaml | 22 +-- .../src/test/resources/microservice.yaml | 22 +-- .../tracing/zipkin/ZipkinTracingFilter.java | 20 ++- .../src/test/resources/microservice.yaml | 22 +-- .../src/test/resources/microservice.yaml | 2 +- .../src/test/resources/microservice.yaml | 22 +-- .../src/test/resources/microservice.yaml | 22 +-- .../transport/highway/HighwayClientFilter.java | 27 +++- .../highway/HighwayServerCodecFilter.java | 19 ++- .../src/main}/resources/microservice.yaml | 24 +-- .../rest/client/RestClientCodecFilter.java | 20 ++- .../rest/client/RestClientFilterProvider.java | 35 ----- .../rest/client/RestClientSenderFilter.java | 20 ++- 43 files changed, 655 insertions(+), 820 deletions(-) diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/filter/inner/RestServerCodecFilter.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/filter/inner/RestServerCodecFilter.java index bcf30a5..3dd5557 100644 --- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/filter/inner/RestServerCodecFilter.java +++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/filter/inner/RestServerCodecFilter.java @@ -21,12 +21,12 @@ import static com.google.common.net.HttpHeaders.CONTENT_LENGTH; import static com.google.common.net.HttpHeaders.TRANSFER_ENCODING; import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR; import static org.apache.servicecomb.core.exception.Exceptions.exceptionToResponse; -import static org.apache.servicecomb.swagger.invocation.InvocationType.PRODUCER; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.CompletableFuture; +import javax.annotation.Nonnull; import javax.servlet.http.Part; import org.apache.servicecomb.common.rest.HttpTransportContext; @@ -36,20 +36,28 @@ import org.apache.servicecomb.common.rest.codec.produce.ProduceProcessor; import org.apache.servicecomb.common.rest.definition.RestOperationMeta; import org.apache.servicecomb.core.Invocation; import org.apache.servicecomb.core.definition.OperationMeta; -import org.apache.servicecomb.core.filter.Filter; -import org.apache.servicecomb.core.filter.FilterMeta; import org.apache.servicecomb.core.filter.FilterNode; +import org.apache.servicecomb.core.filter.ProducerFilter; import org.apache.servicecomb.foundation.common.utils.AsyncUtils; import org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx; import org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx; import org.apache.servicecomb.foundation.vertx.stream.BufferOutputStream; import org.apache.servicecomb.swagger.invocation.Response; +import org.springframework.stereotype.Component; import io.netty.buffer.Unpooled; import io.vertx.core.MultiMap; -@FilterMeta(name = "rest-server-codec", invocationType = PRODUCER) -public class RestServerCodecFilter implements Filter { +@Component +public class RestServerCodecFilter implements ProducerFilter { + public static final String NAME = "rest-server-codec"; + + @Nonnull + @Override + public String getName() { + return NAME; + } + @Override public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) { return CompletableFuture.completedFuture(invocation) diff --git a/common/common-rest/src/test/resources/microservice.yaml b/common/common-rest/src/test/resources/microservice.yaml index b47bdef..5f3131b 100644 --- a/common/common-rest/src/test/resources/microservice.yaml +++ b/common/common-rest/src/test/resources/microservice.yaml @@ -32,4 +32,9 @@ servicecomb: #Provider: #server: test #server.wrapParam: test - + filter-chains: + consumer: + default: empty + producer: + default: empty + diff --git a/core/src/main/java/org/apache/servicecomb/core/SCBEngine.java b/core/src/main/java/org/apache/servicecomb/core/SCBEngine.java index 44a912e..39640f2 100644 --- a/core/src/main/java/org/apache/servicecomb/core/SCBEngine.java +++ b/core/src/main/java/org/apache/servicecomb/core/SCBEngine.java @@ -74,7 +74,6 @@ import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; import com.netflix.config.DynamicPropertyFactory; -// TODO: should not depend on spring, that will make integration more flexible public class SCBEngine { private static final Logger LOGGER = LoggerFactory.getLogger(SCBEngine.class); @@ -360,7 +359,7 @@ public class SCBEngine { triggerEvent(EventType.AFTER_HANDLER); triggerEvent(EventType.BEFORE_FILTER); - filterChainsManager.init(this); + filterChainsManager.init(); triggerEvent(EventType.AFTER_FILTER); createProducerMicroserviceMeta(); @@ -393,7 +392,7 @@ public class SCBEngine { producerMicroserviceMeta = new MicroserviceMeta(this, microserviceName, false); producerMicroserviceMeta.setHandlerChain(producerHandlerManager.getOrCreate(microserviceName)); - producerMicroserviceMeta.setFilterChain(filterChainsManager.createProducerFilterChain(microserviceName)); + producerMicroserviceMeta.setFilterChain(filterChainsManager.findProducerChain(microserviceName)); producerMicroserviceMeta.setMicroserviceVersionsMeta(new MicroserviceVersionsMeta(this, microserviceName)); } diff --git a/core/src/main/java/org/apache/servicecomb/core/bootstrap/SCBEngineForTest.java b/core/src/main/java/org/apache/servicecomb/core/bootstrap/SCBEngineForTest.java index 2a55597..61034a5 100644 --- a/core/src/main/java/org/apache/servicecomb/core/bootstrap/SCBEngineForTest.java +++ b/core/src/main/java/org/apache/servicecomb/core/bootstrap/SCBEngineForTest.java @@ -19,11 +19,14 @@ package org.apache.servicecomb.core.bootstrap; import static org.apache.servicecomb.core.executor.ExecutorManager.EXECUTOR_GROUP_THREADPOOL; +import java.util.Arrays; +import java.util.List; + import org.apache.servicecomb.core.SCBEngine; import org.apache.servicecomb.core.executor.GroupExecutor; +import org.apache.servicecomb.core.filter.Filter; import org.apache.servicecomb.core.filter.FilterChainsManager; -import org.apache.servicecomb.core.filter.FilterManager; -import org.apache.servicecomb.core.filter.config.TransportFiltersConfig; +import org.apache.servicecomb.core.filter.impl.EmptyFilter; import org.apache.servicecomb.foundation.common.event.EventManager; import org.apache.servicecomb.foundation.common.event.SimpleEventBus; import org.apache.servicecomb.foundation.common.utils.ReflectUtils; @@ -34,9 +37,12 @@ import org.apache.servicecomb.foundation.common.utils.ReflectUtils; public class SCBEngineForTest extends SCBEngine { public SCBEngineForTest() { getExecutorManager().registerExecutor(EXECUTOR_GROUP_THREADPOOL, new GroupExecutor().init()); + + List<Filter> filters = Arrays.asList( + new EmptyFilter() + ); setFilterChainsManager(new FilterChainsManager() - .setTransportFiltersConfig(new TransportFiltersConfig()) - .setFilterManager(new FilterManager())); + .addFilters(filters)); } @Override diff --git a/core/src/main/java/org/apache/servicecomb/core/definition/ServiceRegistryListener.java b/core/src/main/java/org/apache/servicecomb/core/definition/ServiceRegistryListener.java index 7f0599f..61bf36a 100644 --- a/core/src/main/java/org/apache/servicecomb/core/definition/ServiceRegistryListener.java +++ b/core/src/main/java/org/apache/servicecomb/core/definition/ServiceRegistryListener.java @@ -76,7 +76,7 @@ public class ServiceRegistryListener { String microserviceName = microserviceVersion.getMicroserviceName(); MicroserviceMeta microserviceMeta = new MicroserviceMeta(scbEngine, microserviceName, true); microserviceMeta.setHandlerChain(scbEngine.getConsumerHandlerManager().getOrCreate(microserviceName)); - microserviceMeta.setFilterChain(scbEngine.getFilterChainsManager().createConsumerFilterChain(microserviceName)); + microserviceMeta.setFilterChain(scbEngine.getFilterChainsManager().findConsumerChain(microserviceName)); MicroserviceVersions microserviceVersions = microserviceVersion.getMicroserviceVersions(); microserviceMeta.setMicroserviceVersionsMeta(getMicroserviceVersionsMeta(microserviceVersions)); diff --git a/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/ZipkinFilterProvider.java b/core/src/main/java/org/apache/servicecomb/core/filter/ConsumerFilter.java similarity index 70% rename from handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/ZipkinFilterProvider.java rename to core/src/main/java/org/apache/servicecomb/core/filter/ConsumerFilter.java index 7e8d6c5..2ede1f0 100644 --- a/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/ZipkinFilterProvider.java +++ b/core/src/main/java/org/apache/servicecomb/core/filter/ConsumerFilter.java @@ -14,17 +14,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.servicecomb.tracing.zipkin; +package org.apache.servicecomb.core.filter; -import java.util.Arrays; +import java.util.Collections; import java.util.List; -import org.apache.servicecomb.core.filter.Filter; -import org.apache.servicecomb.core.filter.FilterProvider; +import javax.annotation.Nonnull; -public class ZipkinFilterProvider implements FilterProvider { +import org.apache.servicecomb.swagger.invocation.InvocationType; + +public interface ConsumerFilter extends Filter { + @Nonnull @Override - public List<Class<? extends Filter>> getFilters() { - return Arrays.asList(ZipkinTracingFilter.class); + default List<InvocationType> getInvocationTypes() { + return Collections.singletonList(InvocationType.CONSUMER); } } diff --git a/core/src/main/java/org/apache/servicecomb/core/filter/Filter.java b/core/src/main/java/org/apache/servicecomb/core/filter/Filter.java index da6367f..6ea3631 100644 --- a/core/src/main/java/org/apache/servicecomb/core/filter/Filter.java +++ b/core/src/main/java/org/apache/servicecomb/core/filter/Filter.java @@ -16,11 +16,15 @@ */ package org.apache.servicecomb.core.filter; +import java.util.Arrays; +import java.util.List; import java.util.concurrent.CompletableFuture; +import javax.annotation.Nonnull; + import org.apache.servicecomb.core.Invocation; -import org.apache.servicecomb.core.SCBEngine; import org.apache.servicecomb.core.provider.consumer.InvokerUtils; +import org.apache.servicecomb.swagger.invocation.InvocationType; import org.apache.servicecomb.swagger.invocation.Response; /** @@ -52,16 +56,26 @@ import org.apache.servicecomb.swagger.invocation.Response; * </pre> */ public interface Filter { - default boolean enabled() { + default boolean isEnabled() { return true; } - default void init(SCBEngine engine) { + default boolean isInEventLoop() { + return InvokerUtils.isInEventLoop(); + } + @Nonnull + default String getName() { + throw new IllegalStateException("must provide filter name."); } - default boolean isInEventLoop() { - return InvokerUtils.isInEventLoop(); + /** + * + * @return can be used for the specific invocation type + */ + @Nonnull + default List<InvocationType> getInvocationTypes() { + return Arrays.asList(InvocationType.CONSUMER, InvocationType.PRODUCER); } /** diff --git a/core/src/main/java/org/apache/servicecomb/core/filter/FilterChainsManager.java b/core/src/main/java/org/apache/servicecomb/core/filter/FilterChainsManager.java index 125d1f7..962e371 100644 --- a/core/src/main/java/org/apache/servicecomb/core/filter/FilterChainsManager.java +++ b/core/src/main/java/org/apache/servicecomb/core/filter/FilterChainsManager.java @@ -18,132 +18,87 @@ package org.apache.servicecomb.core.filter; import static org.apache.servicecomb.foundation.common.utils.StringBuilderUtils.appendLine; import static org.apache.servicecomb.foundation.common.utils.StringBuilderUtils.deleteLast; -import static org.apache.servicecomb.swagger.invocation.InvocationType.CONSUMER; -import static org.apache.servicecomb.swagger.invocation.InvocationType.PRODUCER; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; import java.util.List; import java.util.Map.Entry; +import java.util.stream.Collectors; -import org.apache.servicecomb.core.SCBEngine; import org.apache.servicecomb.core.filter.config.FilterChainsConfig; -import org.apache.servicecomb.core.filter.config.TransportFiltersConfig; +import org.apache.servicecomb.swagger.invocation.InvocationType; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component public class FilterChainsManager { - private TransportFiltersConfig transportFiltersConfig; + private final FilterChainsConfig chainsConfig = new FilterChainsConfig(); - private FilterManager filterManager; + private final InvocationFilterChains consumerChains = new InvocationFilterChains(); - private FilterChainsConfig consumerChainsConfig; - - private FilterChainsConfig producerChainsConfig; - - private boolean enabled; + private final InvocationFilterChains producerChains = new InvocationFilterChains(); @Autowired - public FilterChainsManager setTransportFiltersConfig(TransportFiltersConfig transportFiltersConfig) { - this.transportFiltersConfig = transportFiltersConfig; - return this; - } - - @Value("${servicecomb.filter-chains.enabled:false}") - public FilterChainsManager setEnabled(boolean enabled) { - this.enabled = enabled; - return this; - } - - public FilterManager getFilterManager() { - return filterManager; - } + public FilterChainsManager addFilters(List<Filter> filters) { + for (Filter filter : filters) { + if (filter.getInvocationTypes().contains(InvocationType.CONSUMER)) { + consumerChains.addFilter(filter); + } + + if (filter.getInvocationTypes().contains(InvocationType.PRODUCER)) { + producerChains.addFilter(filter); + } + } - @Autowired - public FilterChainsManager setFilterManager(FilterManager filterManager) { - this.filterManager = filterManager; return this; } - public FilterChainsManager init(SCBEngine engine) { - transportFiltersConfig.load(); - filterManager.init(engine); + public FilterChainsManager init() { + chainsConfig.load(); - consumerChainsConfig = new FilterChainsConfig(transportFiltersConfig, CONSUMER); - producerChainsConfig = new FilterChainsConfig(transportFiltersConfig, PRODUCER); + consumerChains.resolve(chainsConfig.getResolver(), chainsConfig.getConsumer()); + producerChains.resolve(chainsConfig.getResolver(), chainsConfig.getProducer()); return this; } public boolean isEnabled() { - return enabled; - } - - public FilterChainsManager addProviders(FilterProvider... providers) { - return addProviders(Arrays.asList(providers)); - } - - public FilterChainsManager addProviders(Collection<FilterProvider> providers) { - filterManager.addProviders(providers); - return this; - } - - public FilterNode createConsumerFilterChain(String microservice) { - return createFilterNode(consumerChainsConfig, microservice); - } - - public FilterNode createProducerFilterChain(String microservice) { - return createFilterNode(producerChainsConfig, microservice); + return chainsConfig.isEnabled(); } - public List<Filter> createConsumerFilters(String microservice) { - return createFilters(consumerChainsConfig, microservice); + public FilterNode findConsumerChain(String microserviceName) { + return consumerChains.findChain(microserviceName); } - public List<Filter> createProducerFilters(String microservice) { - return createFilters(producerChainsConfig, microservice); + public FilterNode findProducerChain(String microserviceName) { + return producerChains.findChain(microserviceName); } public String collectResolvedChains() { StringBuilder sb = new StringBuilder(); appendLine(sb, "consumer: "); - appendLine(sb, " filters: %s", filterManager.getConsumerFilters()); - collectChainsByInvocationType(sb, consumerChainsConfig); + appendLine(sb, " filters: %s", collectFilterNames(consumerChains)); + collectChainsByInvocationType(sb, consumerChains); appendLine(sb, "producer: "); - appendLine(sb, " filters: %s", filterManager.getProducerFilters()); - collectChainsByInvocationType(sb, producerChainsConfig); + appendLine(sb, " filters: %s", collectFilterNames(producerChains)); + collectChainsByInvocationType(sb, producerChains); return deleteLast(sb, 1).toString(); } - private void collectChainsByInvocationType(StringBuilder sb, FilterChainsConfig chainsConfig) { - appendLine(sb, " chains:"); - appendLine(sb, " default: %s", chainsConfig.getDefaultChain()); - for (Entry<String, List<Object>> entry : chainsConfig.getMicroserviceChains().entrySet()) { - appendLine(sb, " %s: %s", entry.getKey(), entry.getValue()); - } + public List<String> collectFilterNames(InvocationFilterChains chains) { + return chains.getFilters().stream() + .filter(filter -> !(filter instanceof InternalFilter)) + .map(Filter::getName) + .collect(Collectors.toList()); } - private FilterNode createFilterNode(FilterChainsConfig chainsConfig, String microservice) { - if (!enabled) { - return FilterNode.EMPTY; - } - - List<Filter> filters = createFilters(chainsConfig, microservice); - return FilterNode.buildChain(filters); - } - - private List<Filter> createFilters(FilterChainsConfig chainsConfig, String microservice) { - if (!enabled) { - return Collections.emptyList(); + private void collectChainsByInvocationType(StringBuilder sb, InvocationFilterChains chains) { + appendLine(sb, " chains:"); + appendLine(sb, " framework: %s", chains.getResolvedFrameworkConfig()); + appendLine(sb, " default : %s", chains.getResolvedDefaultConfig()); + for (Entry<String, List<Object>> entry : chains.getResolvedMicroserviceConfig().entrySet()) { + appendLine(sb, " %s: %s", entry.getKey(), entry.getValue()); } - - List<Object> chain = chainsConfig.findChain(microservice); - return filterManager.createFilters(chain); } } diff --git a/core/src/main/java/org/apache/servicecomb/core/filter/FilterManager.java b/core/src/main/java/org/apache/servicecomb/core/filter/FilterManager.java deleted file mode 100644 index ce41907..0000000 --- a/core/src/main/java/org/apache/servicecomb/core/filter/FilterManager.java +++ /dev/null @@ -1,162 +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 org.apache.servicecomb.core.filter; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.stream.Collectors; - -import org.apache.servicecomb.core.SCBEngine; -import org.apache.servicecomb.core.filter.config.TransportFilterConfig; -import org.apache.servicecomb.core.filter.impl.TransportFilters; -import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils; -import org.apache.servicecomb.swagger.invocation.InvocationType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -@Component -public class FilterManager { - private static final Logger LOGGER = LoggerFactory.getLogger(FilterManager.class); - - interface Factory { - Filter create(); - } - - private SCBEngine engine; - - private final List<FilterProvider> providers = new ArrayList<>( - SPIServiceUtils.getOrLoadSortedService(FilterProvider.class)); - - private final Map<String, Factory> factoryMap = new HashMap<>(); - - private final List<String> consumerFilters = new ArrayList<>(); - - private final List<String> producerFilters = new ArrayList<>(); - - @Autowired(required = false) - public void addProviders(Collection<FilterProvider> providers) { - this.providers.addAll(providers); - } - - public List<String> getConsumerFilters() { - return consumerFilters; - } - - public List<String> getProducerFilters() { - return producerFilters; - } - - public void init(SCBEngine engine) { - this.engine = engine; - List<Class<? extends Filter>> filterClasses = providers.stream() - .flatMap(provider -> provider.getFilters().stream()) - .collect(Collectors.toList()); - - for (Class<? extends Filter> filterClass : filterClasses) { - FilterMeta meta = filterClass.getAnnotation(FilterMeta.class); - Factory factory = buildFactory(filterClass, meta); - - if (factoryMap.put(meta.name(), factory) != null) { - throw new IllegalStateException( - String.format("duplicated filter, name=%s, class=%s", meta.name(), filterClass.getName())); - } - - if (Arrays.binarySearch(meta.invocationType(), InvocationType.CONSUMER) >= 0) { - consumerFilters.add(meta.name()); - } - if (Arrays.binarySearch(meta.invocationType(), InvocationType.PRODUCER) >= 0) { - producerFilters.add(meta.name()); - } - } - } - - public List<Filter> createFilters(List<Object> chain) { - return chain.stream() - .map(filterConfig -> { - Filter filter = createFilter(filterConfig); - filter.init(engine); - return filter; - }) - .collect(Collectors.toList()); - } - - private Filter createFilter(Object filterConfig) { - if (filterConfig instanceof String) { - return createFilterByName((String) filterConfig); - } - - if (filterConfig instanceof TransportFilterConfig) { - return createTransportFilter((TransportFilterConfig) filterConfig); - } - - throw new IllegalStateException("not support create filter by " + filterConfig); - } - - private Filter createTransportFilter(TransportFilterConfig config) { - TransportFilters transportFilters = new TransportFilters(); - for (Entry<String, List<Object>> entry : config.getFiltersByTransport().entrySet()) { - List<Filter> filters = createFilters(entry.getValue()); - transportFilters.getChainByTransport().put(entry.getKey(), FilterNode.buildChain(filters)); - } - return transportFilters; - } - - private Filter createFilterByName(String filterName) { - Factory factory = factoryMap.get(filterName); - if (factory != null) { - return factory.create(); - } - - throw new IllegalStateException("filter not exist, name=" + filterName); - } - - private Factory buildFactory(Class<? extends Filter> filterClass, FilterMeta meta) { - if (meta.shareable()) { - Filter filter = createFilter(filterClass); - return () -> filter; - } - - return () -> createFilter(filterClass); - } - - private Filter createFilter(Class<? extends Filter> filterClass) { - try { - Filter filter = filterClass.newInstance(); - injectSpringBean(filter); - filter.init(engine); - return filter; - } catch (Exception e) { - throw new IllegalStateException("failed to create filter.", e); - } - } - - private void injectSpringBean(Filter filter) { - if (engine == null || engine.getApplicationContext() == null) { - LOGGER.error("engine or application context is null, only allowed when UT."); - return; - } - - engine.getApplicationContext().getAutowireCapableBeanFactory().autowireBean(filter); - } -} diff --git a/core/src/main/java/org/apache/servicecomb/core/filter/FilterMeta.java b/core/src/main/java/org/apache/servicecomb/core/filter/FilterMeta.java deleted file mode 100644 index e40aca4..0000000 --- a/core/src/main/java/org/apache/servicecomb/core/filter/FilterMeta.java +++ /dev/null @@ -1,50 +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 org.apache.servicecomb.core.filter; - -import static org.apache.servicecomb.swagger.invocation.InvocationType.CONSUMER; -import static org.apache.servicecomb.swagger.invocation.InvocationType.PRODUCER; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.apache.servicecomb.swagger.invocation.InvocationType; - -@Documented -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -@Inherited -public @interface FilterMeta { - String name(); - - /** - * - * @return can be used for the specific invocation type - */ - InvocationType[] invocationType() default {CONSUMER, PRODUCER}; - - /** - * - * @return true to use same instance for all filter chains - */ - boolean shareable() default true; -} diff --git a/core/src/main/java/org/apache/servicecomb/core/filter/FilterNode.java b/core/src/main/java/org/apache/servicecomb/core/filter/FilterNode.java index 31ac18a..bc6bda0 100644 --- a/core/src/main/java/org/apache/servicecomb/core/filter/FilterNode.java +++ b/core/src/main/java/org/apache/servicecomb/core/filter/FilterNode.java @@ -78,7 +78,7 @@ public class FilterNode { } public CompletableFuture<Response> onFilter(Invocation invocation) { - if (!filter.enabled()) { + if (!filter.isEnabled()) { return nextNode.onFilter(invocation); } diff --git a/core/src/main/java/org/apache/servicecomb/core/filter/FilterProvider.java b/core/src/main/java/org/apache/servicecomb/core/filter/InternalFilter.java similarity index 89% rename from core/src/main/java/org/apache/servicecomb/core/filter/FilterProvider.java rename to core/src/main/java/org/apache/servicecomb/core/filter/InternalFilter.java index df14364..a79032d 100644 --- a/core/src/main/java/org/apache/servicecomb/core/filter/FilterProvider.java +++ b/core/src/main/java/org/apache/servicecomb/core/filter/InternalFilter.java @@ -16,8 +16,5 @@ */ package org.apache.servicecomb.core.filter; -import java.util.List; - -public interface FilterProvider { - List<Class<? extends Filter>> getFilters(); +public interface InternalFilter extends Filter { } diff --git a/core/src/main/java/org/apache/servicecomb/core/filter/InvocationFilterChains.java b/core/src/main/java/org/apache/servicecomb/core/filter/InvocationFilterChains.java new file mode 100644 index 0000000..c719166 --- /dev/null +++ b/core/src/main/java/org/apache/servicecomb/core/filter/InvocationFilterChains.java @@ -0,0 +1,113 @@ +/* + * 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.core.filter; + +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.function.Function; +import java.util.stream.Collectors; + +import org.apache.servicecomb.core.filter.config.InvocationFilterChainsConfig; +import org.apache.servicecomb.core.filter.config.TransportChainsConfig; +import org.apache.servicecomb.core.filter.impl.TransportFilters; + +public class InvocationFilterChains { + private final Map<String, Filter> filters = new HashMap<>(); + + private List<Object> resolvedFrameworkConfig; + + private List<Object> resolvedDefaultConfig; + + private final Map<String, List<Object>> resolvedMicroserviceConfig = new HashMap<>(); + + private FilterNode defaultChain; + + private final Map<String, FilterNode> microserviceChains = new HashMap<>(); + + public Collection<Filter> getFilters() { + return filters.values(); + } + + public void addFilter(Filter filter) { + filters.put(filter.getName(), filter); + } + + public List<Object> getResolvedFrameworkConfig() { + return resolvedFrameworkConfig; + } + + public List<Object> getResolvedDefaultConfig() { + return resolvedDefaultConfig; + } + + public Map<String, List<Object>> getResolvedMicroserviceConfig() { + return resolvedMicroserviceConfig; + } + + public void resolve(Function<List<String>, List<Object>> resolver, + InvocationFilterChainsConfig config) { + resolvedFrameworkConfig = resolver.apply(config.getFrameworkChain()); + resolvedDefaultConfig = resolver.apply(config.getDefaultChain()); + + defaultChain = createChain(resolvedDefaultConfig); + for (Entry<String, List<String>> entry : config.getMicroserviceChains().entrySet()) { + List<Object> resolveConfig = resolver.apply(entry.getValue()); + + resolvedMicroserviceConfig.put(entry.getKey(), resolveConfig); + microserviceChains.put(entry.getKey(), createChain(resolveConfig)); + } + } + + private <T> FilterNode createChain(List<T> chain) { + List<Filter> filters = createFilters(chain); + return FilterNode.buildChain(filters); + } + + private <T> List<Filter> createFilters(List<T> chain) { + return chain.stream() + .map(this::findFilter) + .collect(Collectors.toList()); + } + + private Filter findFilter(Object filterConfig) { + if (filterConfig instanceof TransportChainsConfig) { + return createTransportFilter((TransportChainsConfig) filterConfig); + } + + Filter filter = filters.get(filterConfig); + if (filter == null) { + throw new IllegalStateException("failed to find filter, name=" + filterConfig); + } + return filter; + } + + private Filter createTransportFilter(TransportChainsConfig config) { + TransportFilters transportFilters = new TransportFilters(); + for (Entry<String, List<String>> entry : config.getChainByTransport().entrySet()) { + List<Filter> filters = createFilters(entry.getValue()); + transportFilters.getChainByTransport().put(entry.getKey(), FilterNode.buildChain(filters)); + } + return transportFilters; + } + + public FilterNode findChain(String microserviceName) { + return microserviceChains.getOrDefault(microserviceName, defaultChain); + } +} diff --git a/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayFilterProvider.java b/core/src/main/java/org/apache/servicecomb/core/filter/ProducerFilter.java similarity index 67% rename from transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayFilterProvider.java rename to core/src/main/java/org/apache/servicecomb/core/filter/ProducerFilter.java index 87c2b47..969e425 100644 --- a/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayFilterProvider.java +++ b/core/src/main/java/org/apache/servicecomb/core/filter/ProducerFilter.java @@ -14,20 +14,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.servicecomb.transport.highway; +package org.apache.servicecomb.core.filter; -import java.util.Arrays; +import java.util.Collections; import java.util.List; -import org.apache.servicecomb.core.filter.Filter; -import org.apache.servicecomb.core.filter.FilterProvider; +import javax.annotation.Nonnull; -public class HighwayFilterProvider implements FilterProvider { +import org.apache.servicecomb.swagger.invocation.InvocationType; + +public interface ProducerFilter extends Filter { + @Nonnull @Override - public List<Class<? extends Filter>> getFilters() { - return Arrays.asList( - HighwayClientFilter.class, - HighwayServerCodecFilter.class - ); + default List<InvocationType> getInvocationTypes() { + return Collections.singletonList(InvocationType.PRODUCER); } } diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/filter/RestFilterProvider.java b/core/src/main/java/org/apache/servicecomb/core/filter/config/AbstractFilterChainsConfig.java similarity index 60% rename from common/common-rest/src/main/java/org/apache/servicecomb/common/rest/filter/RestFilterProvider.java rename to core/src/main/java/org/apache/servicecomb/core/filter/config/AbstractFilterChainsConfig.java index b91a96e..1257245 100644 --- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/filter/RestFilterProvider.java +++ b/core/src/main/java/org/apache/servicecomb/core/filter/config/AbstractFilterChainsConfig.java @@ -14,20 +14,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.servicecomb.common.rest.filter; +package org.apache.servicecomb.core.filter.config; -import java.util.Arrays; -import java.util.List; +import java.util.function.Consumer; -import org.apache.servicecomb.common.rest.filter.inner.RestServerCodecFilter; -import org.apache.servicecomb.core.filter.Filter; -import org.apache.servicecomb.core.filter.FilterProvider; +import org.apache.commons.configuration.Configuration; -public class RestFilterProvider implements FilterProvider { - @Override - public List<Class<? extends Filter>> getFilters() { - return Arrays.asList( - RestServerCodecFilter.class - ); +import com.netflix.config.DynamicPropertyFactory; + +public class AbstractFilterChainsConfig { + public static final String ROOT = "servicecomb.filter-chains."; + + protected final Configuration config = (Configuration) DynamicPropertyFactory.getBackingConfigurationSource(); + + protected void loadKeys(String root, Consumer<String> loadKey) { + config.getKeys(root).forEachRemaining(loadKey); } } diff --git a/core/src/main/java/org/apache/servicecomb/core/filter/config/FilterChainsConfig.java b/core/src/main/java/org/apache/servicecomb/core/filter/config/FilterChainsConfig.java index a0e5156..db364c2 100644 --- a/core/src/main/java/org/apache/servicecomb/core/filter/config/FilterChainsConfig.java +++ b/core/src/main/java/org/apache/servicecomb/core/filter/config/FilterChainsConfig.java @@ -16,63 +16,90 @@ */ package org.apache.servicecomb.core.filter.config; -import static org.apache.servicecomb.core.filter.config.TransportFiltersConfig.FILTER_CHAINS_PREFIX; - +import java.util.Collections; import java.util.HashMap; import java.util.List; -import java.util.Locale; import java.util.Map; +import java.util.function.Function; import java.util.stream.Collectors; -import org.apache.commons.configuration.Configuration; import org.apache.servicecomb.config.ConfigUtil; -import org.apache.servicecomb.swagger.invocation.InvocationType; -import com.netflix.config.DynamicPropertyFactory; +public class FilterChainsConfig extends AbstractFilterChainsConfig { + public static final String TRANSPORT_ROOT = ROOT + "transport"; + + public static final String DEFINITION_ROOT = ROOT + "definition"; + + // key is chain name + private final Map<String, TransportChainsConfig> transportChains = new HashMap<>(); + + private final Map<String, List<String>> definitions = new HashMap<>(); + + private InvocationFilterChainsConfig consumer; + + private InvocationFilterChainsConfig producer; + + private boolean enabled; -public class FilterChainsConfig { - private final List<Object> defaultChain; + public void load() { + enabled = config.getBoolean(ROOT + "enabled", false); - private final Map<String, List<Object>> microserviceChains = new HashMap<>(); + loadKeys(TRANSPORT_ROOT, this::loadTransportChain); + loadKeys(DEFINITION_ROOT, this::loadDefinitionChain); - private final TransportFiltersConfig transportFiltersConfig; + consumer = new InvocationFilterChainsConfig(ROOT + "consumer"); + producer = new InvocationFilterChainsConfig(ROOT + "producer"); + } - public FilterChainsConfig(TransportFiltersConfig transportFiltersConfig, InvocationType type) { - this.transportFiltersConfig = transportFiltersConfig; + private void loadTransportChain(String qualifiedKey) { + String qualifiedName = qualifiedKey.substring(TRANSPORT_ROOT.length() + 1); + int dotIdx = qualifiedName.indexOf('.'); + String chainName = qualifiedName.substring(0, dotIdx); + String transport = qualifiedName.substring(dotIdx + 1); - Configuration config = (Configuration) DynamicPropertyFactory.getBackingConfigurationSource(); - String root = FILTER_CHAINS_PREFIX + type.name().toLowerCase(Locale.US); - defaultChain = resolve(ConfigUtil.getStringList(config, root + ".default")); - loadMicroserviceChains(config, root + ".policies"); + transportChains.computeIfAbsent(chainName, key -> new TransportChainsConfig()) + .add(transport, ConfigUtil.getStringList(config, qualifiedKey)); } - public List<Object> getDefaultChain() { - return defaultChain; + private void loadDefinitionChain(String qualifiedKey) { + String chainName = qualifiedKey.substring(DEFINITION_ROOT.length() + 1); + + definitions.put(chainName, ConfigUtil.getStringList(config, qualifiedKey)); } - public Map<String, List<Object>> getMicroserviceChains() { - return microserviceChains; + public boolean isEnabled() { + return enabled; } - public List<Object> findChain(String microservice) { - return microserviceChains.getOrDefault(microservice, defaultChain); + public InvocationFilterChainsConfig getConsumer() { + return consumer; } - private void loadMicroserviceChains(Configuration config, String policiesRoot) { - config.getKeys(policiesRoot).forEachRemaining(qualifiedKey -> { - String microserviceName = qualifiedKey.substring(policiesRoot.length() + 1); - List<String> chain = ConfigUtil.getStringList(config, qualifiedKey); + public InvocationFilterChainsConfig getProducer() { + return producer; + } - microserviceChains.put(microserviceName, resolve(chain)); - }); + public Function<List<String>, List<Object>> getResolver() { + return this::resolveChain; } - private List<Object> resolve(List<String> rawChain) { - return rawChain.stream() - .map(value -> { - TransportFilterConfig config = transportFiltersConfig.getConfig(value); - return config == null ? value : config; - }) + private List<Object> resolveChain(List<String> chain) { + return chain.stream() + .flatMap(filterOrReference -> resolveFilterOrReference(filterOrReference).stream()) .collect(Collectors.toList()); } + + private List<Object> resolveFilterOrReference(String filterOrReference) { + TransportChainsConfig transportChain = transportChains.get(filterOrReference); + if (transportChain != null) { + return Collections.singletonList(transportChain); + } + + List<String> chain = definitions.get(filterOrReference); + if (chain == null) { + return Collections.singletonList(filterOrReference); + } + + return resolveChain(chain); + } } diff --git a/core/src/main/java/org/apache/servicecomb/core/filter/config/InvocationFilterChainsConfig.java b/core/src/main/java/org/apache/servicecomb/core/filter/config/InvocationFilterChainsConfig.java new file mode 100644 index 0000000..417aea5 --- /dev/null +++ b/core/src/main/java/org/apache/servicecomb/core/filter/config/InvocationFilterChainsConfig.java @@ -0,0 +1,69 @@ +/* + * 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.core.filter.config; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.servicecomb.config.ConfigUtil; +import org.springframework.util.CollectionUtils; + +public class InvocationFilterChainsConfig extends AbstractFilterChainsConfig { + private final String policiesRoot; + + private final List<String> frameworkChain; + + private final List<String> defaultChain; + + private final Map<String, List<String>> microserviceChains = new HashMap<>(); + + public InvocationFilterChainsConfig(String root) { + frameworkChain = ConfigUtil.getStringList(config, root + ".framework"); + defaultChain = loadDefaultChain(root); + + policiesRoot = root + ".policies"; + loadKeys(policiesRoot, this::loadPolicies); + } + + private List<String> loadDefaultChain(String root) { + String defaultChainKey = root + ".default"; + List<String> defaultChain = ConfigUtil.getStringList(config, defaultChainKey); + if (CollectionUtils.isEmpty(defaultChain) && config.getProperty(defaultChainKey) == null) { + defaultChain = frameworkChain; + } + return defaultChain; + } + + private void loadPolicies(String qualifiedKey) { + String microserviceName = qualifiedKey.substring(policiesRoot.length() + 1); + + microserviceChains.put(microserviceName, ConfigUtil.getStringList(config, qualifiedKey)); + } + + public List<String> getFrameworkChain() { + return frameworkChain; + } + + public List<String> getDefaultChain() { + return defaultChain; + } + + public Map<String, List<String>> getMicroserviceChains() { + return microserviceChains; + } +} diff --git a/core/src/main/java/org/apache/servicecomb/core/filter/config/TransportFilterConfig.java b/core/src/main/java/org/apache/servicecomb/core/filter/config/TransportChainsConfig.java similarity index 72% rename from core/src/main/java/org/apache/servicecomb/core/filter/config/TransportFilterConfig.java rename to core/src/main/java/org/apache/servicecomb/core/filter/config/TransportChainsConfig.java index e6b675d..5ef2dcd 100644 --- a/core/src/main/java/org/apache/servicecomb/core/filter/config/TransportFilterConfig.java +++ b/core/src/main/java/org/apache/servicecomb/core/filter/config/TransportChainsConfig.java @@ -20,21 +20,21 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -public class TransportFilterConfig { - private Map<String, List<Object>> filtersByTransport = new HashMap<>(); +public class TransportChainsConfig { + private Map<String, List<String>> chainByTransport = new HashMap<>(); - public Map<String, List<Object>> getFiltersByTransport() { - return filtersByTransport; + public Map<String, List<String>> getChainByTransport() { + return chainByTransport; } - public TransportFilterConfig setTransportFilters(String transport, List<Object> filters) { - filtersByTransport.put(transport, filters); + public TransportChainsConfig add(String transport, List<String> chain) { + chainByTransport.put(transport, chain); return this; } @Override public String toString() { - return filtersByTransport.toString(); + return chainByTransport.toString(); } } diff --git a/core/src/main/java/org/apache/servicecomb/core/filter/config/TransportFiltersConfig.java b/core/src/main/java/org/apache/servicecomb/core/filter/config/TransportFiltersConfig.java deleted file mode 100644 index ef2883d..0000000 --- a/core/src/main/java/org/apache/servicecomb/core/filter/config/TransportFiltersConfig.java +++ /dev/null @@ -1,54 +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 org.apache.servicecomb.core.filter.config; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.commons.configuration.Configuration; -import org.springframework.stereotype.Component; - -import com.netflix.config.DynamicPropertyFactory; - -@Component -public class TransportFiltersConfig { - public static final String FILTER_CHAINS_PREFIX = "servicecomb.filter-chains."; - - public static final String ROOT = FILTER_CHAINS_PREFIX + "transport-filters"; - - private final Map<String, TransportFilterConfig> byName = new HashMap<>(); - - private final Configuration config = (Configuration) DynamicPropertyFactory.getBackingConfigurationSource(); - - public void load() { - config.getKeys(ROOT).forEachRemaining(this::loadOneChain); - } - - private void loadOneChain(String qualifiedKey) { - String qualifiedName = qualifiedKey.substring(ROOT.length() + 1); - int dotIdx = qualifiedName.indexOf('.'); - String name = qualifiedName.substring(0, dotIdx); - String transport = qualifiedName.substring(dotIdx + 1); - - byName.computeIfAbsent(name, key -> new TransportFilterConfig()) - .setTransportFilters(transport, config.getList(qualifiedKey)); - } - - public TransportFilterConfig getConfig(String name) { - return byName.get(name); - } -} diff --git a/core/src/main/java/org/apache/servicecomb/core/filter/impl/DefaultFilterProvider.java b/core/src/main/java/org/apache/servicecomb/core/filter/impl/EmptyFilter.java similarity index 59% rename from core/src/main/java/org/apache/servicecomb/core/filter/impl/DefaultFilterProvider.java rename to core/src/main/java/org/apache/servicecomb/core/filter/impl/EmptyFilter.java index 3cfd20e..95da754 100644 --- a/core/src/main/java/org/apache/servicecomb/core/filter/impl/DefaultFilterProvider.java +++ b/core/src/main/java/org/apache/servicecomb/core/filter/impl/EmptyFilter.java @@ -16,19 +16,25 @@ */ package org.apache.servicecomb.core.filter.impl; -import java.util.Arrays; -import java.util.List; +import java.util.concurrent.CompletableFuture; -import org.apache.servicecomb.core.filter.Filter; -import org.apache.servicecomb.core.filter.FilterProvider; +import javax.annotation.Nonnull; + +import org.apache.servicecomb.core.Invocation; +import org.apache.servicecomb.core.filter.FilterNode; +import org.apache.servicecomb.core.filter.InternalFilter; +import org.apache.servicecomb.swagger.invocation.Response; + +// just for test +public class EmptyFilter implements InternalFilter { + @Nonnull + @Override + public String getName() { + return "empty"; + } -public class DefaultFilterProvider implements FilterProvider { @Override - public List<Class<? extends Filter>> getFilters() { - return Arrays.asList( - SimpleLoadBalanceFilter.class, - ScheduleFilter.class, - ParameterValidatorFilter.class, - ProducerOperationFilter.class); + public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) { + return CompletableFuture.completedFuture(Response.ok(null)); } } diff --git a/core/src/main/java/org/apache/servicecomb/core/filter/impl/ParameterValidatorFilter.java b/core/src/main/java/org/apache/servicecomb/core/filter/impl/ParameterValidatorFilter.java index 08a6dda..c1d1e70 100644 --- a/core/src/main/java/org/apache/servicecomb/core/filter/impl/ParameterValidatorFilter.java +++ b/core/src/main/java/org/apache/servicecomb/core/filter/impl/ParameterValidatorFilter.java @@ -16,12 +16,11 @@ */ package org.apache.servicecomb.core.filter.impl; -import static org.apache.servicecomb.swagger.invocation.InvocationType.PRODUCER; - import java.lang.reflect.Method; import java.util.Set; import java.util.concurrent.CompletableFuture; +import javax.annotation.Nonnull; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; import javax.validation.Validation; @@ -30,10 +29,8 @@ import javax.validation.executable.ExecutableValidator; import javax.validation.groups.Default; import org.apache.servicecomb.core.Invocation; -import org.apache.servicecomb.core.SCBEngine; -import org.apache.servicecomb.core.filter.Filter; -import org.apache.servicecomb.core.filter.FilterMeta; import org.apache.servicecomb.core.filter.FilterNode; +import org.apache.servicecomb.core.filter.ProducerFilter; import org.apache.servicecomb.foundation.common.utils.AsyncUtils; import org.apache.servicecomb.swagger.engine.SwaggerProducerOperation; import org.apache.servicecomb.swagger.invocation.Response; @@ -43,19 +40,29 @@ import org.hibernate.validator.messageinterpolation.ParameterMessageInterpolator import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.stereotype.Component; import com.netflix.config.DynamicPropertyFactory; -@FilterMeta(name = "validator", invocationType = PRODUCER) -public class ParameterValidatorFilter implements Filter { +@Component +public class ParameterValidatorFilter implements ProducerFilter, InitializingBean { private static final Logger LOGGER = LoggerFactory.getLogger(ParameterValidatorFilter.class); + public static final String NAME = "validator"; + private static final String ENABLE_EL = "servicecomb.filters.validation.useResourceBundleMessageInterpolator"; - private ExecutableValidator validator; + protected ExecutableValidator validator; + + @Nonnull + @Override + public String getName() { + return NAME; + } @Override - public void init(SCBEngine engine) { + public void afterPropertiesSet() { validator = createValidatorFactory() .getValidator().forExecutables(); } diff --git a/core/src/main/java/org/apache/servicecomb/core/filter/impl/ProducerOperationFilter.java b/core/src/main/java/org/apache/servicecomb/core/filter/impl/ProducerOperationFilter.java index 1695ba8..cb06081 100644 --- a/core/src/main/java/org/apache/servicecomb/core/filter/impl/ProducerOperationFilter.java +++ b/core/src/main/java/org/apache/servicecomb/core/filter/impl/ProducerOperationFilter.java @@ -16,26 +16,30 @@ */ package org.apache.servicecomb.core.filter.impl; -import static org.apache.servicecomb.swagger.invocation.InvocationType.PRODUCER; - import java.lang.reflect.Method; import java.util.concurrent.CompletableFuture; +import javax.annotation.Nonnull; + import org.apache.servicecomb.core.Invocation; import org.apache.servicecomb.core.exception.Exceptions; -import org.apache.servicecomb.core.filter.Filter; -import org.apache.servicecomb.core.filter.FilterMeta; import org.apache.servicecomb.core.filter.FilterNode; +import org.apache.servicecomb.core.filter.ProducerFilter; import org.apache.servicecomb.foundation.common.utils.AsyncUtils; import org.apache.servicecomb.swagger.engine.SwaggerProducerOperation; import org.apache.servicecomb.swagger.invocation.Response; import org.apache.servicecomb.swagger.invocation.context.ContextUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +public class ProducerOperationFilter implements ProducerFilter { + public static final String NAME = "producer-operation"; -@FilterMeta(name = "producer-operation", invocationType = PRODUCER) -public class ProducerOperationFilter implements Filter { - private static final Logger LOGGER = LoggerFactory.getLogger(ProducerOperationFilter.class); + @Nonnull + @Override + public String getName() { + return NAME; + } @Override public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) { diff --git a/core/src/main/java/org/apache/servicecomb/core/filter/impl/ScheduleFilter.java b/core/src/main/java/org/apache/servicecomb/core/filter/impl/ScheduleFilter.java index 716095e..a07ff75 100644 --- a/core/src/main/java/org/apache/servicecomb/core/filter/impl/ScheduleFilter.java +++ b/core/src/main/java/org/apache/servicecomb/core/filter/impl/ScheduleFilter.java @@ -16,21 +16,29 @@ */ package org.apache.servicecomb.core.filter.impl; -import static org.apache.servicecomb.swagger.invocation.InvocationType.PRODUCER; - import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; +import javax.annotation.Nonnull; + import org.apache.servicecomb.core.Invocation; import org.apache.servicecomb.core.exception.Exceptions; -import org.apache.servicecomb.core.filter.Filter; -import org.apache.servicecomb.core.filter.FilterMeta; import org.apache.servicecomb.core.filter.FilterNode; +import org.apache.servicecomb.core.filter.ProducerFilter; import org.apache.servicecomb.core.invocation.InvocationStageTrace; import org.apache.servicecomb.swagger.invocation.Response; +import org.springframework.stereotype.Component; + +@Component +public class ScheduleFilter implements ProducerFilter { + public static final String NAME = "schedule"; + + @Nonnull + @Override + public String getName() { + return NAME; + } -@FilterMeta(name = "schedule", invocationType = PRODUCER) -public class ScheduleFilter implements Filter { @Override public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode next) { invocation.getInvocationStageTrace().startSchedule(); diff --git a/core/src/main/java/org/apache/servicecomb/core/filter/impl/SimpleLoadBalanceFilter.java b/core/src/main/java/org/apache/servicecomb/core/filter/impl/SimpleLoadBalanceFilter.java index 557cf1b..0282b95 100644 --- a/core/src/main/java/org/apache/servicecomb/core/filter/impl/SimpleLoadBalanceFilter.java +++ b/core/src/main/java/org/apache/servicecomb/core/filter/impl/SimpleLoadBalanceFilter.java @@ -17,18 +17,18 @@ package org.apache.servicecomb.core.filter.impl; import static org.apache.servicecomb.core.exception.ExceptionCodes.LB_ADDRESS_NOT_FOUND; -import static org.apache.servicecomb.swagger.invocation.InvocationType.CONSUMER; import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicInteger; +import javax.annotation.Nonnull; + import org.apache.servicecomb.core.Endpoint; import org.apache.servicecomb.core.Invocation; import org.apache.servicecomb.core.exception.Exceptions; -import org.apache.servicecomb.core.filter.Filter; -import org.apache.servicecomb.core.filter.FilterMeta; +import org.apache.servicecomb.core.filter.ConsumerFilter; import org.apache.servicecomb.core.filter.FilterNode; import org.apache.servicecomb.core.handler.impl.SimpleLoadBalanceHandler; import org.apache.servicecomb.core.registry.discovery.EndpointDiscoveryFilter; @@ -40,23 +40,74 @@ import org.apache.servicecomb.registry.discovery.DiscoveryTree; import org.apache.servicecomb.swagger.invocation.Response; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; /** * build-in round robin LB, for demo scenes */ -@FilterMeta(name = "simple-load-balance", invocationType = CONSUMER, shareable = false) -public class SimpleLoadBalanceFilter implements Filter { +@Component +public class SimpleLoadBalanceFilter implements ConsumerFilter { private static final Logger LOGGER = LoggerFactory.getLogger(SimpleLoadBalanceHandler.class); - private DiscoveryTree discoveryTree = new DiscoveryTree(); + public static final String NAME = "simple-load-balance"; + + private static class Service { + private final String name; + + private final DiscoveryTree discoveryTree = new DiscoveryTree(); + + // key is grouping filter qualified name + private final Map<String, AtomicInteger> indexMap = new ConcurrentHashMapEx<>(); + + public Service(String name) { + this.name = name; + discoveryTree.loadFromSPI(DiscoveryFilter.class); + discoveryTree.addFilter(new EndpointDiscoveryFilter()); + discoveryTree.sort(); + } + + public String getName() { + return name; + } + + public Endpoint selectEndpoint(Invocation invocation) { + DiscoveryContext context = new DiscoveryContext(); + context.setInputParameters(invocation); + VersionedCache endpointsVersionedCache = discoveryTree.discovery(context, + invocation.getAppId(), + invocation.getMicroserviceName(), + invocation.getMicroserviceVersionRule()); + if (endpointsVersionedCache.isEmpty()) { + String msg = "No available address found."; + LOGGER.error("{} microserviceName={}, version={}, discoveryGroupName={}", + msg, + invocation.getMicroserviceName(), + invocation.getMicroserviceVersionRule(), + endpointsVersionedCache.name()); + throw Exceptions.consumer(LB_ADDRESS_NOT_FOUND, msg); + } + + List<Endpoint> endpoints = endpointsVersionedCache.data(); + AtomicInteger index = indexMap.computeIfAbsent(endpointsVersionedCache.name(), name -> { + LOGGER.info("Create loadBalancer for {}.", name); + return new AtomicInteger(); + }); + LOGGER.debug("invocation {} use discoveryGroup {}.", + invocation.getMicroserviceQualifiedName(), + endpointsVersionedCache.name()); + + int idx = Math.abs(index.getAndIncrement()); + idx = idx % endpoints.size(); + return endpoints.get(idx); + } + } - // key is grouping filter qualified name - private volatile Map<String, AtomicInteger> indexMap = new ConcurrentHashMapEx<>(); + private final Map<String, Service> servicesByName = new ConcurrentHashMapEx<>(); - public SimpleLoadBalanceFilter() { - discoveryTree.loadFromSPI(DiscoveryFilter.class); - discoveryTree.addFilter(new EndpointDiscoveryFilter()); - discoveryTree.sort(); + @Nonnull + @Override + public String getName() { + return NAME; } @Override @@ -65,38 +116,9 @@ public class SimpleLoadBalanceFilter implements Filter { return nextNode.onFilter(invocation); } - invocation.setEndpoint(selectEndpoint(invocation)); + Service service = servicesByName.computeIfAbsent(invocation.getMicroserviceName(), Service::new); + Endpoint endpoint = service.selectEndpoint(invocation); + invocation.setEndpoint(endpoint); return nextNode.onFilter(invocation); } - - public Endpoint selectEndpoint(Invocation invocation) { - DiscoveryContext context = new DiscoveryContext(); - context.setInputParameters(invocation); - VersionedCache endpointsVersionedCache = discoveryTree.discovery(context, - invocation.getAppId(), - invocation.getMicroserviceName(), - invocation.getMicroserviceVersionRule()); - if (endpointsVersionedCache.isEmpty()) { - String msg = "No available address found."; - LOGGER.error("{} microserviceName={}, version={}, discoveryGroupName={}", - msg, - invocation.getMicroserviceName(), - invocation.getMicroserviceVersionRule(), - endpointsVersionedCache.name()); - throw Exceptions.consumer(LB_ADDRESS_NOT_FOUND, msg); - } - - List<Endpoint> endpoints = endpointsVersionedCache.data(); - AtomicInteger index = indexMap.computeIfAbsent(endpointsVersionedCache.name(), name -> { - LOGGER.info("Create loadBalancer for {}.", name); - return new AtomicInteger(); - }); - LOGGER.debug("invocation {} use discoveryGroup {}.", - invocation.getMicroserviceQualifiedName(), - endpointsVersionedCache.name()); - - int idx = Math.abs(index.getAndIncrement()); - idx = idx % endpoints.size(); - return endpoints.get(idx); - } } diff --git a/core/src/main/java/org/apache/servicecomb/core/filter/impl/TransportFilters.java b/core/src/main/java/org/apache/servicecomb/core/filter/impl/TransportFilters.java index 2170af3..40e8362 100644 --- a/core/src/main/java/org/apache/servicecomb/core/filter/impl/TransportFilters.java +++ b/core/src/main/java/org/apache/servicecomb/core/filter/impl/TransportFilters.java @@ -20,19 +20,29 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.CompletableFuture; +import javax.annotation.Nonnull; + import org.apache.servicecomb.core.Invocation; -import org.apache.servicecomb.core.filter.Filter; -import org.apache.servicecomb.core.filter.FilterMeta; import org.apache.servicecomb.core.filter.FilterNode; +import org.apache.servicecomb.core.filter.InternalFilter; import org.apache.servicecomb.swagger.invocation.Response; +import org.springframework.stereotype.Component; /** - * Internal use only, will not publish by {@link DefaultFilterProvider} + * Internal use only */ -@FilterMeta(name = "transport-filters") -public class TransportFilters implements Filter { +@Component +public class TransportFilters implements InternalFilter { + public static final String NAME = "transport-filters"; + private Map<String, FilterNode> chainByTransport = new HashMap<>(); + @Nonnull + @Override + public String getName() { + return NAME; + } + public Map<String, FilterNode> getChainByTransport() { return chainByTransport; } @@ -43,7 +53,7 @@ public class TransportFilters implements Filter { if (filterNode == null) { return nextNode.onFilter(invocation); } - + return filterNode.onFilter(invocation); } } diff --git a/core/src/main/resources/microservice.yaml b/core/src/main/resources/microservice.yaml index cb2c464..8b505cd 100644 --- a/core/src/main/resources/microservice.yaml +++ b/core/src/main/resources/microservice.yaml @@ -20,20 +20,25 @@ servicecomb-config-order: -500 servicecomb: filter-chains: enabled: false - transport-filters: - default-consumer-transport: + transport: + scb-consumer-transport: rest: rest-client-codec, rest-client-sender - highway: highway-client - default-producer-transport: + scb-producer-transport: rest: rest-server-codec - highway: highway-server-codec + definition: + scb-consumer: simple-load-balance, scb-consumer-transport + scb-producer: scb-producer-transport, schedule, producer-operation consumer: - default: simple-load-balance, default-consumer-transport + framework: scb-consumer + # when there is no "default" chains, will read framework chains as "default" chains + #default: scb-consumer # samples for customize microservice filter chain #policies: # ms-1: retry, load-balance, transport-client, ms-1-consumer-transport producer: - default: default-producer-transport, schedule, producer-operation + framework: scb-producer + # when there is no "default" chains, will read framework chains as "default" chains + #default: scb-producer # samples for customize microservice filter chain #policies: # ms-1: qps-limiter, ms-1-producer-transport, schedule, producer-operation \ No newline at end of file diff --git a/core/src/test/java/org/apache/servicecomb/core/filter/FilterChainsManagerTest.java b/core/src/test/java/org/apache/servicecomb/core/filter/FilterChainsManagerTest.java deleted file mode 100644 index 1a42497..0000000 --- a/core/src/test/java/org/apache/servicecomb/core/filter/FilterChainsManagerTest.java +++ /dev/null @@ -1,103 +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 org.apache.servicecomb.core.filter; - -import static org.assertj.core.api.Assertions.assertThat; - -import java.util.Collections; -import java.util.List; - -import org.apache.servicecomb.core.filter.config.TransportFiltersConfig; -import org.apache.servicecomb.foundation.test.scaffolding.config.ArchaiusUtils; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.Test; - -public class FilterChainsManagerTest { - @Before - public void setUp() { - ArchaiusUtils.resetConfig(); - } - - @AfterClass - public static void afterAll() { - ArchaiusUtils.resetConfig(); - } - - private void default_chain(String filters) { - ArchaiusUtils.setProperty("servicecomb.filter-chains.consumer.default", filters); - } - - private void microservice_chain(String microservice, String filters) { - String key = String.format("servicecomb.filter-chains.consumer.policies.%s", microservice); - ArchaiusUtils.setProperty(key, filters); - } - - private FilterChainsManager createFilterChains() { - return new FilterChainsManager() - .setEnabled(true) - .setTransportFiltersConfig(new TransportFiltersConfig()) - .setFilterManager(new FilterManager()) - .addProviders(() -> Collections.singletonList(SimpleRetryFilter.class)) - .init(null); - } - - @Test - public void should_allow_not_share_filter_instance() { - default_chain("simple-load-balance"); - - FilterChainsManager filterChains = createFilterChains(); - List<Filter> aFilters = filterChains.createConsumerFilters("a"); - List<Filter> bFilters = filterChains.createConsumerFilters("b"); - - assertThat(aFilters.get(0)).isNotSameAs(bFilters.get(0)); - } - - @Test - public void should_allow_share_filter_instance() { - default_chain("simple-retry"); - - FilterChainsManager filterChains = createFilterChains(); - List<Filter> aFilters = filterChains.createConsumerFilters("a"); - List<Filter> bFilters = filterChains.createConsumerFilters("b"); - - assertThat(aFilters).hasSameElementsAs(bFilters); - } - - @Test - public void should_allow_mix_share_and_not_share_filter_instance() { - default_chain("simple-load-balance, simple-retry"); - - FilterChainsManager filterChains = createFilterChains(); - List<Filter> aFilters = filterChains.createConsumerFilters("a"); - List<Filter> bFilters = filterChains.createConsumerFilters("b"); - - assertThat(aFilters.get(0)).isNotSameAs(bFilters.get(0)); - assertThat(aFilters.get(1)).isSameAs(bFilters.get(1)); - } - - @Test - public void microservice_scope_should_override_default_scope() { - default_chain("simple-load-balance"); - microservice_chain("a", "simple-retry"); - - FilterChainsManager filterChains = createFilterChains(); - List<Filter> filters = filterChains.createConsumerFilters("a"); - - assertThat(filters.get(0)).isInstanceOf(SimpleRetryFilter.class); - } -} diff --git a/core/src/test/java/org/apache/servicecomb/core/filter/SimpleRetryFilter.java b/core/src/test/java/org/apache/servicecomb/core/filter/SimpleRetryFilter.java index 061356d..ce54faf 100644 --- a/core/src/test/java/org/apache/servicecomb/core/filter/SimpleRetryFilter.java +++ b/core/src/test/java/org/apache/servicecomb/core/filter/SimpleRetryFilter.java @@ -19,14 +19,21 @@ package org.apache.servicecomb.core.filter; import java.io.IOException; import java.util.concurrent.CompletableFuture; +import javax.annotation.Nonnull; + import org.apache.servicecomb.core.Invocation; import org.apache.servicecomb.core.exception.Exceptions; import org.apache.servicecomb.swagger.invocation.Response; -@FilterMeta(name = "simple-retry") -public class SimpleRetryFilter implements Filter { +public class SimpleRetryFilter implements ConsumerFilter { protected int maxRetry = 3; + @Nonnull + @Override + public String getName() { + return "simple-retry"; + } + public SimpleRetryFilter setMaxRetry(int maxRetry) { this.maxRetry = maxRetry; return this; diff --git a/core/src/test/java/org/apache/servicecomb/core/filter/impl/ParameterValidatorFilterTest.java b/core/src/test/java/org/apache/servicecomb/core/filter/impl/ParameterValidatorFilterTest.java index ef7db5e..d21e9a9 100644 --- a/core/src/test/java/org/apache/servicecomb/core/filter/impl/ParameterValidatorFilterTest.java +++ b/core/src/test/java/org/apache/servicecomb/core/filter/impl/ParameterValidatorFilterTest.java @@ -96,7 +96,7 @@ public class ParameterValidatorFilterTest { @BeforeClass public static void beforeClass() throws Exception { - filter.init(null); + filter.afterPropertiesSet(); } @Before diff --git a/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/CodeFirstPojoClient.java b/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/CodeFirstPojoClient.java index ee91f31..e9c55a1 100644 --- a/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/CodeFirstPojoClient.java +++ b/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/CodeFirstPojoClient.java @@ -22,7 +22,6 @@ import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; import javax.inject.Inject; @@ -98,18 +97,19 @@ public class CodeFirstPojoClient { InvocationContext context = new InvocationContext(); context.addContext("k", "v"); ContextUtils.setInvocationContext(context); - CompletableFuture<String> future = ((CodeFirstPojoClientIntf) codeFirst).sayHiAsync("someone"); - future.thenCompose(result -> { - TestMgr.check("someone sayhi, context k: v", result); + ((CodeFirstPojoClientIntf) codeFirst).sayHiAsync("someone") + .thenCompose(result -> { + TestMgr.check("someone sayhi, context k: v", result); - TestMgr.check(true, context == ContextUtils.getInvocationContext()); + TestMgr.check(true, context == ContextUtils.getInvocationContext()); - return ((CodeFirstPojoClientIntf) codeFirst).sayHiAsync("someone 1"); - }).whenComplete((r, e) -> { - TestMgr.check("someone 1 sayhi, context k: v", r); - latch.countDown(); - }); + return ((CodeFirstPojoClientIntf) codeFirst).sayHiAsync("someone 1"); + }) + .whenComplete((r, e) -> { + TestMgr.check("someone 1 sayhi, context k: v", r); + latch.countDown(); + }); ContextUtils.removeInvocationContext(); }); diff --git a/common/common-rest/src/test/resources/microservice.yaml b/handlers/handler-loadbalance/src/test/resources/microservice.yaml similarity index 75% copy from common/common-rest/src/test/resources/microservice.yaml copy to handlers/handler-loadbalance/src/test/resources/microservice.yaml index b47bdef..4db1321 100644 --- a/common/common-rest/src/test/resources/microservice.yaml +++ b/handlers/handler-loadbalance/src/test/resources/microservice.yaml @@ -15,21 +15,9 @@ ## limitations under the License. ## --------------------------------------------------------------------------- -APPLICATION_ID: test -service_description: - name: test - version: 0.0.1 servicecomb: - service: - registry: - address: http://127.0.0.1:30100 - rest: - address: 0.0.0.0:8080 - highway: - address: 0.0.0.0:7070 - #executors: - #default: test - #Provider: - #server: test - #server.wrapParam: test - + filter-chains: + consumer: + default: empty + producer: + default: empty \ No newline at end of file diff --git a/common/common-rest/src/test/resources/microservice.yaml b/handlers/handler-publickey-auth/src/test/resources/microservice.yaml similarity index 75% copy from common/common-rest/src/test/resources/microservice.yaml copy to handlers/handler-publickey-auth/src/test/resources/microservice.yaml index b47bdef..4db1321 100644 --- a/common/common-rest/src/test/resources/microservice.yaml +++ b/handlers/handler-publickey-auth/src/test/resources/microservice.yaml @@ -15,21 +15,9 @@ ## limitations under the License. ## --------------------------------------------------------------------------- -APPLICATION_ID: test -service_description: - name: test - version: 0.0.1 servicecomb: - service: - registry: - address: http://127.0.0.1:30100 - rest: - address: 0.0.0.0:8080 - highway: - address: 0.0.0.0:7070 - #executors: - #default: test - #Provider: - #server: test - #server.wrapParam: test - + filter-chains: + consumer: + default: empty + producer: + default: empty \ No newline at end of file diff --git a/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/ZipkinTracingFilter.java b/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/ZipkinTracingFilter.java index 9d76b26..f896004 100644 --- a/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/ZipkinTracingFilter.java +++ b/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/ZipkinTracingFilter.java @@ -21,28 +21,36 @@ import static org.apache.servicecomb.swagger.invocation.InvocationType.PRODUCER; import java.util.concurrent.CompletableFuture; +import javax.annotation.Nonnull; + import org.apache.servicecomb.core.Invocation; -import org.apache.servicecomb.core.SCBEngine; import org.apache.servicecomb.core.exception.Exceptions; import org.apache.servicecomb.core.filter.Filter; -import org.apache.servicecomb.core.filter.FilterMeta; import org.apache.servicecomb.core.filter.FilterNode; -import org.apache.servicecomb.foundation.common.utils.BeanUtils; import org.apache.servicecomb.swagger.invocation.Response; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; import brave.Span; import brave.Tracer.SpanInScope; import brave.http.HttpTracing; -@FilterMeta(name = "zipkin") +@Component public class ZipkinTracingFilter implements Filter { + public static final String NAME = "zipkin"; + private ZipkinConsumerDelegate consumer; private ZipkinProviderDelegate producer; + @Nonnull @Override - public void init(SCBEngine engine) { - HttpTracing httpTracing = BeanUtils.getContext().getBean(HttpTracing.class); + public String getName() { + return NAME; + } + + @Autowired + public void setHttpTracing(HttpTracing httpTracing) { this.consumer = new ZipkinConsumerDelegate(httpTracing); this.producer = new ZipkinProviderDelegate(httpTracing); } diff --git a/common/common-rest/src/test/resources/microservice.yaml b/inspector/src/test/resources/microservice.yaml similarity index 75% copy from common/common-rest/src/test/resources/microservice.yaml copy to inspector/src/test/resources/microservice.yaml index b47bdef..4db1321 100644 --- a/common/common-rest/src/test/resources/microservice.yaml +++ b/inspector/src/test/resources/microservice.yaml @@ -15,21 +15,9 @@ ## limitations under the License. ## --------------------------------------------------------------------------- -APPLICATION_ID: test -service_description: - name: test - version: 0.0.1 servicecomb: - service: - registry: - address: http://127.0.0.1:30100 - rest: - address: 0.0.0.0:8080 - highway: - address: 0.0.0.0:7070 - #executors: - #default: test - #Provider: - #server: test - #server.wrapParam: test - + filter-chains: + consumer: + default: empty + producer: + default: empty \ No newline at end of file diff --git a/integration-tests/tracing-tests/src/test/resources/microservice.yaml b/integration-tests/tracing-tests/src/test/resources/microservice.yaml index 939decc..314ad9b 100644 --- a/integration-tests/tracing-tests/src/test/resources/microservice.yaml +++ b/integration-tests/tracing-tests/src/test/resources/microservice.yaml @@ -35,7 +35,7 @@ servicecomb: default: tracing-consumer,loadbalance,bizkeeper-consumer filter-chains: producer: - default: default-producer-transport, schedule, zipkin, validator, producer-operation + default: scb-producer-transport, schedule, zipkin, validator, producer-operation tracing: collector: address: http://localhost:9411 diff --git a/common/common-rest/src/test/resources/microservice.yaml b/providers/provider-pojo/src/test/resources/microservice.yaml similarity index 75% copy from common/common-rest/src/test/resources/microservice.yaml copy to providers/provider-pojo/src/test/resources/microservice.yaml index b47bdef..4db1321 100644 --- a/common/common-rest/src/test/resources/microservice.yaml +++ b/providers/provider-pojo/src/test/resources/microservice.yaml @@ -15,21 +15,9 @@ ## limitations under the License. ## --------------------------------------------------------------------------- -APPLICATION_ID: test -service_description: - name: test - version: 0.0.1 servicecomb: - service: - registry: - address: http://127.0.0.1:30100 - rest: - address: 0.0.0.0:8080 - highway: - address: 0.0.0.0:7070 - #executors: - #default: test - #Provider: - #server: test - #server.wrapParam: test - + filter-chains: + consumer: + default: empty + producer: + default: empty \ No newline at end of file diff --git a/common/common-rest/src/test/resources/microservice.yaml b/providers/provider-springmvc/src/test/resources/microservice.yaml similarity index 75% copy from common/common-rest/src/test/resources/microservice.yaml copy to providers/provider-springmvc/src/test/resources/microservice.yaml index b47bdef..4db1321 100644 --- a/common/common-rest/src/test/resources/microservice.yaml +++ b/providers/provider-springmvc/src/test/resources/microservice.yaml @@ -15,21 +15,9 @@ ## limitations under the License. ## --------------------------------------------------------------------------- -APPLICATION_ID: test -service_description: - name: test - version: 0.0.1 servicecomb: - service: - registry: - address: http://127.0.0.1:30100 - rest: - address: 0.0.0.0:8080 - highway: - address: 0.0.0.0:7070 - #executors: - #default: test - #Provider: - #server: test - #server.wrapParam: test - + filter-chains: + consumer: + default: empty + producer: + default: empty \ No newline at end of file diff --git a/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayClientFilter.java b/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayClientFilter.java index 3110b40..fdd7a3e 100644 --- a/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayClientFilter.java +++ b/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayClientFilter.java @@ -16,27 +16,36 @@ */ package org.apache.servicecomb.transport.highway; -import static org.apache.servicecomb.swagger.invocation.InvocationType.CONSUMER; - import java.util.concurrent.CompletableFuture; +import javax.annotation.Nonnull; + import org.apache.servicecomb.codec.protobuf.definition.OperationProtobuf; import org.apache.servicecomb.codec.protobuf.definition.ProtobufManager; import org.apache.servicecomb.core.Invocation; import org.apache.servicecomb.core.exception.Exceptions; -import org.apache.servicecomb.core.filter.Filter; -import org.apache.servicecomb.core.filter.FilterMeta; +import org.apache.servicecomb.core.filter.ConsumerFilter; import org.apache.servicecomb.core.filter.FilterNode; import org.apache.servicecomb.foundation.common.utils.AsyncUtils; import org.apache.servicecomb.foundation.vertx.client.tcp.TcpData; import org.apache.servicecomb.swagger.invocation.Response; +import org.apache.servicecomb.swagger.invocation.exception.InvocationException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; -@FilterMeta(name = "highway-client", invocationType = CONSUMER) -public class HighwayClientFilter implements Filter { +@Component +public class HighwayClientFilter implements ConsumerFilter { private static final Logger LOGGER = LoggerFactory.getLogger(HighwayClientFilter.class); + public static final String NAME = "highway-client"; + + @Nonnull + @Override + public String getName() { + return NAME; + } + @Override public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) { LOGGER.debug("Sending request by highway, operation={}, endpoint={}.", @@ -81,7 +90,11 @@ public class HighwayClientFilter implements Filter { protected Response convertFailedResponseToException(Response response) { if (response.isFailed()) { - throw Exceptions.create(response.getStatus(), response.getResult()); + Object errorData = response.getResult(); + if (errorData instanceof InvocationException) { + errorData = ((InvocationException) errorData).getErrorData(); + } + throw Exceptions.create(response.getStatus(), errorData); } return response; diff --git a/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayServerCodecFilter.java b/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayServerCodecFilter.java index c719ead..0464b6b 100644 --- a/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayServerCodecFilter.java +++ b/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayServerCodecFilter.java @@ -18,24 +18,33 @@ package org.apache.servicecomb.transport.highway; import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR; import static org.apache.servicecomb.core.exception.Exceptions.exceptionToResponse; -import static org.apache.servicecomb.swagger.invocation.InvocationType.PRODUCER; import java.util.concurrent.CompletableFuture; +import javax.annotation.Nonnull; + import org.apache.servicecomb.codec.protobuf.definition.OperationProtobuf; import org.apache.servicecomb.codec.protobuf.definition.ResponseRootSerializer; import org.apache.servicecomb.core.Invocation; -import org.apache.servicecomb.core.filter.Filter; -import org.apache.servicecomb.core.filter.FilterMeta; import org.apache.servicecomb.core.filter.FilterNode; +import org.apache.servicecomb.core.filter.ProducerFilter; import org.apache.servicecomb.foundation.common.utils.AsyncUtils; import org.apache.servicecomb.swagger.invocation.Response; import org.apache.servicecomb.transport.highway.message.ResponseHeader; +import org.springframework.stereotype.Component; import io.vertx.core.buffer.Buffer; -@FilterMeta(name = "highway-server-codec", invocationType = PRODUCER) -public class HighwayServerCodecFilter implements Filter { +@Component +public class HighwayServerCodecFilter implements ProducerFilter { + public static final String NAME = "highway-server-codec"; + + @Nonnull + @Override + public String getName() { + return NAME; + } + @Override public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) { return CompletableFuture.completedFuture(invocation) diff --git a/common/common-rest/src/test/resources/microservice.yaml b/transports/transport-highway/src/main/resources/microservice.yaml similarity index 75% copy from common/common-rest/src/test/resources/microservice.yaml copy to transports/transport-highway/src/main/resources/microservice.yaml index b47bdef..4b37228 100644 --- a/common/common-rest/src/test/resources/microservice.yaml +++ b/transports/transport-highway/src/main/resources/microservice.yaml @@ -15,21 +15,11 @@ ## limitations under the License. ## --------------------------------------------------------------------------- -APPLICATION_ID: test -service_description: - name: test - version: 0.0.1 +servicecomb-config-order: -500 servicecomb: - service: - registry: - address: http://127.0.0.1:30100 - rest: - address: 0.0.0.0:8080 - highway: - address: 0.0.0.0:7070 - #executors: - #default: test - #Provider: - #server: test - #server.wrapParam: test - + filter-chains: + transport: + scb-consumer-transport: + highway: highway-client + scb-producer-transport: + highway: highway-server-codec diff --git a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientCodecFilter.java b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientCodecFilter.java index 24f50ca..6db242a 100644 --- a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientCodecFilter.java +++ b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientCodecFilter.java @@ -16,25 +16,33 @@ */ package org.apache.servicecomb.transport.rest.client; -import static org.apache.servicecomb.swagger.invocation.InvocationType.CONSUMER; - import java.util.concurrent.CompletableFuture; +import javax.annotation.Nonnull; + import org.apache.servicecomb.core.Invocation; -import org.apache.servicecomb.core.filter.Filter; -import org.apache.servicecomb.core.filter.FilterMeta; +import org.apache.servicecomb.core.filter.ConsumerFilter; import org.apache.servicecomb.core.filter.FilterNode; import org.apache.servicecomb.swagger.invocation.Response; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class RestClientCodecFilter implements ConsumerFilter { + public static final String NAME = "rest-client-codec"; -@FilterMeta(name = "rest-client-codec", invocationType = CONSUMER) -public class RestClientCodecFilter implements Filter { protected RestClientTransportContextFactory transportContextFactory; protected RestClientEncoder encoder; protected RestClientDecoder decoder; + @Nonnull + @Override + public String getName() { + return NAME; + } + @Autowired public RestClientCodecFilter setTransportContextFactory(RestClientTransportContextFactory transportContextFactory) { this.transportContextFactory = transportContextFactory; diff --git a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientFilterProvider.java b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientFilterProvider.java deleted file mode 100644 index d1e9afb..0000000 --- a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientFilterProvider.java +++ /dev/null @@ -1,35 +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 org.apache.servicecomb.transport.rest.client; - -import java.util.Arrays; -import java.util.List; - -import org.apache.servicecomb.core.filter.Filter; -import org.apache.servicecomb.core.filter.FilterProvider; -import org.springframework.stereotype.Component; - -@Component -public class RestClientFilterProvider implements FilterProvider { - @Override - public List<Class<? extends Filter>> getFilters() { - return Arrays.asList( - RestClientCodecFilter.class, - RestClientSenderFilter.class - ); - } -} diff --git a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientSenderFilter.java b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientSenderFilter.java index dfec70a..d5c2bd4 100644 --- a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientSenderFilter.java +++ b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientSenderFilter.java @@ -16,18 +16,26 @@ */ package org.apache.servicecomb.transport.rest.client; -import static org.apache.servicecomb.swagger.invocation.InvocationType.CONSUMER; - import java.util.concurrent.CompletableFuture; +import javax.annotation.Nonnull; + import org.apache.servicecomb.core.Invocation; -import org.apache.servicecomb.core.filter.Filter; -import org.apache.servicecomb.core.filter.FilterMeta; +import org.apache.servicecomb.core.filter.ConsumerFilter; import org.apache.servicecomb.core.filter.FilterNode; import org.apache.servicecomb.swagger.invocation.Response; +import org.springframework.stereotype.Component; + +@Component +public class RestClientSenderFilter implements ConsumerFilter { + public static final String NAME = "rest-client-sender"; + + @Nonnull + @Override + public String getName() { + return NAME; + } -@FilterMeta(name = "rest-client-sender", invocationType = CONSUMER) -public class RestClientSenderFilter implements Filter { @Override public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) { CompletableFuture<Response> future = new RestClientSender(invocation)