You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by wu...@apache.org on 2020/12/22 08:16:35 UTC
[servicecomb-java-chassis] branch master updated: [SCB-2169]
optimize filter declare and chain config
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 <wu...@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)