liubao68 closed pull request #577: [SCB-352] refactor QpsControllerManager, support operation level qps controll on provider side URL: https://github.com/apache/incubator-servicecomb-java-chassis/pull/577
This is a PR merged from a forked repository. As GitHub hides the original diff on merge, it is displayed below for the sake of provenance: As this is a foreign pull request (from a fork), the diff is supplied below (as it won't show otherwise due to GitHub magic): diff --git a/handlers/handler-flowcontrol-qps/pom.xml b/handlers/handler-flowcontrol-qps/pom.xml index e9c10bdd1..86a3943ec 100644 --- a/handlers/handler-flowcontrol-qps/pom.xml +++ b/handlers/handler-flowcontrol-qps/pom.xml @@ -16,29 +16,34 @@ --> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - <parent> - <groupId>org.apache.servicecomb</groupId> - <artifactId>handlers</artifactId> - <version>1.0.0-m1</version> - </parent> - <artifactId>handler-flowcontrol-qps</artifactId> - <name>Java Chassis::Handlers::Flow Control QPS</name> - <dependencies> - <dependency> - <groupId>org.apache.servicecomb</groupId> - <artifactId>java-chassis-core</artifactId> - </dependency> - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-log4j12</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>log4j</groupId> - <artifactId>log4j</artifactId> - <scope>test</scope> - </dependency> - </dependencies> + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.apache.servicecomb</groupId> + <artifactId>handlers</artifactId> + <version>1.0.0-m1</version> + </parent> + <artifactId>handler-flowcontrol-qps</artifactId> + <name>Java Chassis::Handlers::Flow Control QPS</name> + <dependencies> + <dependency> + <groupId>org.apache.servicecomb</groupId> + <artifactId>java-chassis-core</artifactId> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-log4j12</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.servicecomb</groupId> + <artifactId>foundation-test-scaffolding</artifactId> + <scope>test</scope> + </dependency> + </dependencies> </project> diff --git a/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/ConsumerQpsControllerManager.java b/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/ConsumerQpsControllerManager.java deleted file mode 100644 index 076df492d..000000000 --- a/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/ConsumerQpsControllerManager.java +++ /dev/null @@ -1,157 +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.qps; - -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -import org.apache.servicecomb.core.definition.OperationMeta; -import org.apache.servicecomb.foundation.common.AbstractObjectManager; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.netflix.config.DynamicProperty; - -/** - * 以microservice.schema.operation为key - * 如果配置只到microservice级别,那么该microservice中所有的key都关联到同一个qpsController实例 - * 然后schema、operation级别有独立配置的,单独关联自己的qpsController实例 - * - * schema级独立的qpsController统计时,并不会导致microservice级别的统计也改变,operation级别规则也相同 - * 即:统计只在qpsController实例内部生效,不会产生实例间的关联 - * - */ -public class ConsumerQpsControllerManager extends AbstractObjectManager<OperationMeta, String, QpsController> { - private static final Logger LOGGER = LoggerFactory.getLogger(ConsumerQpsControllerManager.class); - // 最终使用的QpsController实例,实际都是从下面的map中引用出来的,不会独立创建 - - // 3种类型的key都保存在这里,不存在冲突 - // microservice - // microservice.schema - // microservice.schema.operation - private Map<String, QpsController> qpsControllerMap = new ConcurrentHashMap<>(); - - // 避免重复watch - // 只会在create流程中调用,是有锁保护的,不必考虑多线程并发 - private Set<String> watchedKeySet = new HashSet<>(); - - @Override - protected String getKey(OperationMeta operationMeta) { - return operationMeta.getMicroserviceQualifiedName(); - } - - private QpsController initQpsLimit(String key, Integer qpsLimit) { - if (qpsLimit == null) { - return null; - } - - LOGGER.info("qpsLimit of {} init as {}", key, qpsLimit); - - QpsController qpsController = new QpsController(key, qpsLimit); - qpsControllerMap.put(key, qpsController); - return qpsController; - } - - private QpsController updateQpsLimit(String key, Integer qpsLimit) { - QpsController qpsController = qpsControllerMap.get(key); - if (qpsController == null && qpsLimit != null) { - qpsController = new QpsController(key, qpsLimit); - qpsControllerMap.put(key, qpsController); - } - - if (qpsController != null) { - LOGGER.info("qpsLimit of {} changed from {} to {}", key, qpsController.getQpsLimit(), qpsLimit); - - qpsController.setQpsLimit(qpsLimit); - } - - return qpsController; - } - - private QpsController findReference(String key) { - QpsController qpsController = qpsControllerMap.get(key); - if (qpsController == null) { - return null; - } - - if (qpsController.getQpsLimit() == null) { - return null; - } - - return qpsController; - } - - private QpsController findReference(OperationMeta operationMeta) { - QpsController qpsController = findReference(operationMeta.getMicroserviceQualifiedName()); - if (qpsController != null) { - return qpsController; - } - - qpsController = findReference(operationMeta.getSchemaMeta().getMicroserviceQualifiedName()); - if (qpsController != null) { - return qpsController; - } - - qpsController = findReference(operationMeta.getMicroserviceName()); - if (qpsController != null) { - return qpsController; - } - - return initQpsLimit(operationMeta.getMicroserviceName(), Integer.MAX_VALUE); - } - - @Override - protected QpsController create(OperationMeta operationMeta) { - // create在父类中是加了锁的,不存在并发的场景 - initConfig(operationMeta, operationMeta.getMicroserviceQualifiedName()); - initConfig(operationMeta, operationMeta.getSchemaMeta().getMicroserviceQualifiedName()); - initConfig(operationMeta, operationMeta.getMicroserviceName()); - - return findReference(operationMeta); - } - - private void initConfig(OperationMeta operationMeta, String key) { - if (watchedKeySet.contains(key)) { - return; - } - - watchedKeySet.add(key); - - String configKey = Config.CONSUMER_LIMIT_KEY_PREFIX + key; - DynamicProperty property = DynamicProperty.getInstance(configKey); - initQpsLimit(key, getIntegerLimitProperty(property)); - - property.addCallback(() -> { - updateQpsLimit(key, getIntegerLimitProperty(property)); - QpsController qpsController = findReference(operationMeta); - - objMap.put(operationMeta.getMicroserviceQualifiedName(), qpsController); - }); - } - - private Integer getIntegerLimitProperty(DynamicProperty property) { - try { - return property.getInteger(); - } catch (IllegalArgumentException e) { - LOGGER.error(e.getMessage()); - return null; - } - } -} diff --git a/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/ConsumerQpsFlowControlHandler.java b/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/ConsumerQpsFlowControlHandler.java index b1fd2a669..101babc85 100644 --- a/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/ConsumerQpsFlowControlHandler.java +++ b/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/ConsumerQpsFlowControlHandler.java @@ -19,18 +19,17 @@ import org.apache.servicecomb.core.Handler; import org.apache.servicecomb.core.Invocation; -import org.apache.servicecomb.core.definition.OperationMeta; import org.apache.servicecomb.swagger.invocation.AsyncResponse; import org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData; import org.apache.servicecomb.swagger.invocation.exception.InvocationException; /** - * consumer端针对调用目标的qps控制 - * 支持microservice、schema、operation三个级别的控制 - * + * For qps flow control on consumer side. + * Support 3 levels of microservice/schema/operation. */ public class ConsumerQpsFlowControlHandler implements Handler { - private ConsumerQpsControllerManager qpsControllerMgr = new ConsumerQpsControllerManager(); + static final QpsControllerManager qpsControllerMgr = new QpsControllerManager() + .setConfigKeyPrefix(Config.CONSUMER_LIMIT_KEY_PREFIX); @Override public void handle(Invocation invocation, AsyncResponse asyncResp) throws Exception { @@ -39,10 +38,10 @@ public void handle(Invocation invocation, AsyncResponse asyncResp) throws Except return; } - OperationMeta operationMeta = invocation.getOperationMeta(); - QpsController qpsController = qpsControllerMgr.getOrCreate(operationMeta); + QpsController qpsController = qpsControllerMgr.getOrCreate( + invocation.getOperationMeta().getMicroserviceQualifiedName()); if (qpsController.isLimitNewRequest()) { - // 429 + // return http status 429 CommonExceptionData errorData = new CommonExceptionData("rejected by qps flowcontrol"); asyncResp.consumerFail( new InvocationException(QpsConst.TOO_MANY_REQUESTS_STATUS, errorData)); diff --git a/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/ProviderQpsControllerManager.java b/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/ProviderQpsControllerManager.java deleted file mode 100644 index d8d6c76ac..000000000 --- a/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/ProviderQpsControllerManager.java +++ /dev/null @@ -1,143 +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.qps; - -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -import org.apache.servicecomb.foundation.common.AbstractObjectManager; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.netflix.config.DynamicProperty; - -public class ProviderQpsControllerManager - extends AbstractObjectManager<String, String, QpsController> { - private static final Logger LOGGER = LoggerFactory.getLogger(ProviderQpsControllerManager.class); - - private Map<String, QpsController> qpsControllerMap = new ConcurrentHashMap<>(); - - // 避免重复watch - // 只会在create流程中调用,是有锁保护的,不必考虑多线程并发 - private Set<String> watchedKeySet = new HashSet<>(); - - private QpsController globalQpsController = null; - - @Override - protected String getKey(String microServiceName) { - return microServiceName; - } - - @Override - public QpsController getOrCreate(String keyOwner) { - if (keyOwner == null) { - if (globalQpsController == null) { - synchronized (lockObj) { - if (globalQpsController == null) { - DynamicProperty property = - DynamicProperty.getInstance(Config.PROVIDER_LIMIT_KEY_GLOBAL); - globalQpsController = new QpsController(keyOwner, getIntegerLimitProperty(property)); - property.addCallback(() -> { - globalQpsController.setQpsLimit(getIntegerLimitProperty(property)); - }); - } - } - } - return globalQpsController; - } else { - return super.getOrCreate(keyOwner); - } - } - - private QpsController initQpsLimit(String key, Integer qpsLimit) { - if (qpsLimit == null) { - qpsLimit = null; - } - - LOGGER.info("qpsLimit of {} init as {}", key, qpsLimit); - - QpsController qpsController = new QpsController(key, qpsLimit); - qpsControllerMap.put(key, qpsController); - return qpsController; - } - - private QpsController updateQpsLimit(String key, Integer qpsLimit) { - QpsController qpsController = qpsControllerMap.get(key); - if (qpsController == null && qpsLimit != null) { - qpsController = new QpsController(key, qpsLimit); - qpsControllerMap.put(key, qpsController); - } - - if (qpsController != null) { - LOGGER.info("qpsLimit of {} changed from {} to {}", - key, - qpsController.getQpsLimit(), - qpsLimit); - - qpsController.setQpsLimit(qpsLimit); - } - - return qpsController; - } - - private QpsController findReference(String key) { - QpsController qpsController = qpsControllerMap.get(key); - if (qpsController == null) { - return initQpsLimit(key, Integer.MAX_VALUE); - } - return qpsController; - } - - @Override - protected QpsController create(String microServiceName) { - // create在父类中是加了锁的,不存在并发的场景 - initConfig(microServiceName); - - return findReference(microServiceName); - } - - private void initConfig(String key) { - if (watchedKeySet.contains(key)) { - return; - } - - watchedKeySet.add(key); - - String configKey = Config.PROVIDER_LIMIT_KEY_PREFIX + key; - DynamicProperty property = DynamicProperty.getInstance(configKey); - initQpsLimit(key, getIntegerLimitProperty(property)); - - property.addCallback(() -> { - updateQpsLimit(key, getIntegerLimitProperty(property)); - QpsController qpsController = findReference(key); - - objMap.put(key, qpsController); - }); - } - - private Integer getIntegerLimitProperty(DynamicProperty property) { - try { - return property.getInteger(); - } catch (IllegalArgumentException e) { - LOGGER.error(e.getMessage()); - return null; - } - } -} diff --git a/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/ProviderQpsFlowControlHandler.java b/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/ProviderQpsFlowControlHandler.java index 1cf669d81..b81581ff5 100644 --- a/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/ProviderQpsFlowControlHandler.java +++ b/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/ProviderQpsFlowControlHandler.java @@ -23,9 +23,12 @@ import org.apache.servicecomb.swagger.invocation.AsyncResponse; import org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData; import org.apache.servicecomb.swagger.invocation.exception.InvocationException; +import org.springframework.util.StringUtils; public class ProviderQpsFlowControlHandler implements Handler { - private ProviderQpsControllerManager qpsControllerMgr = new ProviderQpsControllerManager(); + static final QpsControllerManager qpsControllerMgr = new QpsControllerManager() + .setConfigKeyPrefix(Config.PROVIDER_LIMIT_KEY_PREFIX) + .setGlobalQpsController(Config.PROVIDER_LIMIT_KEY_GLOBAL); @Override public void handle(Invocation invocation, AsyncResponse asyncResp) throws Exception { @@ -34,16 +37,13 @@ public void handle(Invocation invocation, AsyncResponse asyncResp) throws Except return; } - String microServiceName = (String) invocation.getContext(Const.SRC_MICROSERVICE); - if (microServiceName != null && !microServiceName.isEmpty()) { - QpsController qpsController = qpsControllerMgr.getOrCreate(microServiceName); - if (isLimitNewRequest(qpsController, asyncResp)) { - return; - } - } - - QpsController globalQpsController = qpsControllerMgr.getOrCreate(null); - if (isLimitNewRequest(globalQpsController, asyncResp)) { + String microServiceName = invocation.getContext(Const.SRC_MICROSERVICE); + QpsController qpsController = + StringUtils.isEmpty(microServiceName) + ? qpsControllerMgr.getGlobalQpsController() + : qpsControllerMgr.getOrCreate(microServiceName + QpsControllerManager.SEPARATOR + + invocation.getOperationMeta().getSchemaQualifiedName()); + if (isLimitNewRequest(qpsController, asyncResp)) { return; } diff --git a/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/QpsControllerManager.java b/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/QpsControllerManager.java new file mode 100644 index 000000000..09a69ed07 --- /dev/null +++ b/handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/QpsControllerManager.java @@ -0,0 +1,175 @@ +/* + * 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.qps; + +import java.util.Map; +import java.util.Map.Entry; +import java.util.regex.Pattern; + +import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.netflix.config.DynamicProperty; + +public class QpsControllerManager { + private static final Logger LOGGER = LoggerFactory.getLogger(QpsControllerManager.class); + + private static final Pattern QUALIFIED_KEY_CHECKER = Pattern.compile("^[^.]+\\.[^.]+\\.[^.]+$"); + + /** + * Describe the relationship between configuration and qpsController. + */ + protected final Map<String, QpsController> configQpsControllerMap = new ConcurrentHashMapEx<>(); + + /** + * Describe the relationship between qualifiedKey(format is "microservice.schema.operation") and qpsController. + */ + protected final Map<String, QpsController> qualifiedNameControllerMap = new ConcurrentHashMapEx<>(); + + protected QpsController globalQpsController; + + public static final String SEPARATOR = "."; + + private String configKeyPrefix; + + public QpsController getOrCreate(String key) { + return qualifiedNameControllerMap.computeIfAbsent(key, this::create); + } + + /** + * Create relevant qpsLimit dynamicProperty and watch the configuration change. + * Search and return a valid qpsController. + */ + protected QpsController create(String qualifiedNameKey) { + if (!QUALIFIED_KEY_CHECKER.matcher(qualifiedNameKey).matches()) { + throw new IllegalArgumentException("Unexpected qualified name: [" + qualifiedNameKey + "]"); + } + // create "microservice" + createQpsControllerIfNotExist(qualifiedNameKey.substring(0, qualifiedNameKey.indexOf(SEPARATOR))); + // create "microservice.schema" + createQpsControllerIfNotExist(qualifiedNameKey.substring(0, qualifiedNameKey.lastIndexOf(SEPARATOR))); + // create "microservice.schema.operation" + createQpsControllerIfNotExist(qualifiedNameKey); + + return searchQpsController(qualifiedNameKey); + } + + /** + * <p> Use qualifiedNameKey to search {@link QpsController}. + * Firstly try to search "microservice.schema.operation". If no valid result found, then try "microservice.schema", + * and then "microservice" or global qpsController(If there is a global qpsController).</p> + * <p> This method ensures that there is always an existing qpsController returned, as the relevant qpsController has + * been created and stored in {@link #create(String)}</p> + * + * @param qualifiedNameKey qualifiedNameKey in {@link #qualifiedNameControllerMap} + * @return a qps controller, lower level controllers with valid qpsLimit have priority. + */ + protected QpsController searchQpsController(String qualifiedNameKey) { + QpsController qpsController = configQpsControllerMap.get(qualifiedNameKey); + if (isValidQpsController(qpsController)) { + return qpsController; + } + + int index = qualifiedNameKey.lastIndexOf(SEPARATOR); + while (index > 0) { + qpsController = configQpsControllerMap.get(qualifiedNameKey.substring(0, index)); + if (isValidQpsController(qpsController)) { + return qpsController; + } + + index = qualifiedNameKey.lastIndexOf(SEPARATOR, index - 1); + } + + if (isValidQpsController(qpsController)) { + return qpsController; + } + + if (null != globalQpsController) { + return globalQpsController; + } + + // if null is returned, maybe the operation qps controller is not initiated correctly. + // getOrCreateQpsController() should be invoked before. + return qpsController; + } + + private boolean keyMatch(String configKey, Entry<String, QpsController> controllerEntry) { + return controllerEntry.getKey().equals(configKey) + || controllerEntry.getKey().startsWith(configKey + SEPARATOR); + } + + private boolean isValidQpsController(QpsController qpsController) { + return null != qpsController && null != qpsController.getQpsLimit(); + } + + private void createQpsControllerIfNotExist(String configKey) { + if (configQpsControllerMap.keySet().contains(configKey)) { + return; + } + + LOGGER.info("Create qpsController, configKey = [{}]", configKey); + DynamicProperty property = getDynamicProperty(configKey); + QpsController qpsController = new QpsController(configKey, property.getInteger()); + + configQpsControllerMap.put(configKey, qpsController); + + property.addCallback(() -> { + qpsController.setQpsLimit(property.getInteger()); + LOGGER.info("Qps limit updated, configKey = [{}], value = [{}]", configKey, property.getString()); + updateObjMap(configKey); + }); + } + + protected void updateObjMap(String configKey) { + for (Entry<String, QpsController> controllerEntry : qualifiedNameControllerMap.entrySet()) { + if (keyMatch(configKey, controllerEntry)) { + QpsController qpsController = searchQpsController(controllerEntry.getKey()); + controllerEntry.setValue(qpsController); + LOGGER.info("QpsController updated, operationId = [{}], configKey = [{}], qpsLimit = [{}]", + controllerEntry.getKey(), qpsController.getKey(), qpsController.getQpsLimit()); + } + } + } + + public QpsControllerManager setConfigKeyPrefix(String configKeyPrefix) { + this.configKeyPrefix = configKeyPrefix; + return this; + } + + public QpsControllerManager setGlobalQpsController(String globalConfigKey) { + DynamicProperty globalQpsProperty = DynamicProperty.getInstance(globalConfigKey); + QpsController qpsController = new QpsController(globalConfigKey, globalQpsProperty.getInteger()); + + globalQpsProperty.addCallback(() -> { + qpsController.setQpsLimit(globalQpsProperty.getInteger()); + LOGGER.info("Global qps limit update, value = [{}]", globalQpsProperty.getInteger()); + }); + + this.globalQpsController = qpsController; + return this; + } + + public QpsController getGlobalQpsController() { + return globalQpsController; + } + + protected DynamicProperty getDynamicProperty(String configKey) { + return DynamicProperty.getInstance(configKeyPrefix + configKey); + } +} diff --git a/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/QpsControllerManagerTest.java b/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/QpsControllerManagerTest.java new file mode 100644 index 000000000..1837ff297 --- /dev/null +++ b/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/QpsControllerManagerTest.java @@ -0,0 +1,258 @@ +/* + * 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.qps; + +import java.util.Map; + +import org.apache.servicecomb.core.Invocation; +import org.apache.servicecomb.core.definition.OperationMeta; +import org.apache.servicecomb.core.definition.SchemaMeta; +import org.apache.servicecomb.foundation.test.scaffolding.config.ArchaiusUtils; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +import mockit.Deencapsulation; + +public class QpsControllerManagerTest { + + @Before + public void beforeTest() { + ArchaiusUtils.resetConfig(); + } + + @After + public void afterTest() { + ArchaiusUtils.resetConfig(); + } + + @Test + public void testGetOrCreate() { + QpsControllerManager testQpsControllerManager = new QpsControllerManager() + .setConfigKeyPrefix(Config.CONSUMER_LIMIT_KEY_PREFIX); + initTestQpsControllerManager(testQpsControllerManager); + + // pojo + setConfigWithDefaultPrefix("pojo", 100); + QpsController qpsController = testQpsControllerManager.getOrCreate("pojo.server.test"); + Assert.assertEquals("pojo", qpsController.getKey()); + Assert.assertTrue(100 == qpsController.getQpsLimit()); + qpsController = testQpsControllerManager.getOrCreate("pojo2.server.test"); + Assert.assertEquals("pojo2", qpsController.getKey()); + Assert.assertNull(qpsController.getQpsLimit()); + qpsController = testQpsControllerManager.getOrCreate("poj.server.test"); + Assert.assertEquals("poj", qpsController.getKey()); + Assert.assertNull(qpsController.getQpsLimit()); + + testGetOrCreateCommon(testQpsControllerManager); + } + + @Test + public void testGetOrCreateWithGlobalConfig() { + QpsControllerManager testQpsControllerManager = new QpsControllerManager() + .setGlobalQpsController(Config.PROVIDER_LIMIT_KEY_GLOBAL) + .setConfigKeyPrefix(Config.CONSUMER_LIMIT_KEY_PREFIX); + + // global + setConfig(Config.PROVIDER_LIMIT_KEY_GLOBAL, 50); + QpsController qpsController = testQpsControllerManager.getOrCreate("pojo.server.test"); + Assert.assertEquals(Config.PROVIDER_LIMIT_KEY_GLOBAL, qpsController.getKey()); + Assert.assertTrue(50 == qpsController.getQpsLimit()); + qpsController = testQpsControllerManager.getOrCreate("pojo2.server.test"); + Assert.assertEquals(Config.PROVIDER_LIMIT_KEY_GLOBAL, qpsController.getKey()); + Assert.assertTrue(50 == qpsController.getQpsLimit()); + qpsController = testQpsControllerManager.getOrCreate("poj.server.test"); + Assert.assertEquals(Config.PROVIDER_LIMIT_KEY_GLOBAL, qpsController.getKey()); + Assert.assertTrue(50 == qpsController.getQpsLimit()); + + // pojo + setConfigWithDefaultPrefix("pojo", 100); + qpsController = testQpsControllerManager.getOrCreate("pojo.server.test"); + Assert.assertEquals("pojo", qpsController.getKey()); + Assert.assertTrue(100 == qpsController.getQpsLimit()); + qpsController = testQpsControllerManager.getOrCreate("pojo2.server.test"); + Assert.assertEquals(Config.PROVIDER_LIMIT_KEY_GLOBAL, qpsController.getKey()); + Assert.assertTrue(50 == qpsController.getQpsLimit()); + qpsController = testQpsControllerManager.getOrCreate("poj.server.test"); + Assert.assertEquals(Config.PROVIDER_LIMIT_KEY_GLOBAL, qpsController.getKey()); + Assert.assertTrue(50 == qpsController.getQpsLimit()); + + testGetOrCreateCommon(testQpsControllerManager); + } + + @Test + public void testQualifiedNameKey() { + QpsControllerManager qpsControllerManager = new QpsControllerManager(); + QpsController qpsController = qpsControllerManager.getOrCreate("service.schema.opr"); + Assert.assertEquals("service", qpsController.getKey()); + Assert.assertNull(qpsController.getQpsLimit()); + + qpsController = qpsControllerManager.getOrCreate("test_service.test_schema.test_opr"); + Assert.assertEquals("test_service", qpsController.getKey()); + Assert.assertNull(qpsController.getQpsLimit()); + + qpsController = qpsControllerManager.getOrCreate("test-service.test-schema.test-opr"); + Assert.assertEquals("test-service", qpsController.getKey()); + Assert.assertNull(qpsController.getQpsLimit()); + + Exception exception = null; + try { + qpsControllerManager.getOrCreate("svc.schema.opr.tail"); + } catch (Exception e) { + exception = e; + } + Assert.assertNotNull(exception); + Assert.assertEquals(IllegalArgumentException.class, exception.getClass()); + Assert.assertEquals("Unexpected qualified name: [svc.schema.opr.tail]", exception.getMessage()); + + try { + qpsControllerManager.getOrCreate("svc.schema"); + } catch (Exception e) { + exception = e; + } + Assert.assertNotNull(exception); + Assert.assertEquals(IllegalArgumentException.class, exception.getClass()); + Assert.assertEquals("Unexpected qualified name: [svc.schema]", exception.getMessage()); + + try { + qpsControllerManager.getOrCreate("..."); + } catch (Exception e) { + exception = e; + } + Assert.assertNotNull(exception); + Assert.assertEquals(IllegalArgumentException.class, exception.getClass()); + Assert.assertEquals("Unexpected qualified name: [...]", exception.getMessage()); + } + + private void testGetOrCreateCommon(QpsControllerManager testQpsControllerManager) { + // pojo.server + setConfigWithDefaultPrefix("pojo.server", 200); + QpsController qpsController = testQpsControllerManager.getOrCreate("pojo.server.test"); + Assert.assertEquals("pojo.server", qpsController.getKey()); + Assert.assertTrue(200 == qpsController.getQpsLimit()); + qpsController = testQpsControllerManager.getOrCreate("pojo.server2.test"); + Assert.assertEquals("pojo", qpsController.getKey()); + Assert.assertTrue(100 == qpsController.getQpsLimit()); + qpsController = testQpsControllerManager.getOrCreate("pojo.serve.test"); + Assert.assertEquals("pojo", qpsController.getKey()); + Assert.assertTrue(100 == qpsController.getQpsLimit()); + + // pojo.server.test + setConfigWithDefaultPrefix("pojo.server.test", 300); + qpsController = testQpsControllerManager.getOrCreate("pojo.server.test"); + Assert.assertEquals("pojo.server.test", qpsController.getKey()); + Assert.assertTrue(300 == qpsController.getQpsLimit()); + qpsController = testQpsControllerManager.getOrCreate("pojo.server.test2"); + Assert.assertEquals("pojo.server", qpsController.getKey()); + Assert.assertTrue(200 == qpsController.getQpsLimit()); + qpsController = testQpsControllerManager.getOrCreate("pojo.server.tes"); + Assert.assertEquals("pojo.server", qpsController.getKey()); + Assert.assertTrue(200 == qpsController.getQpsLimit()); + } + + /** + * Init testQpsControllerManager to test search function. + */ + private void initTestQpsControllerManager(QpsControllerManager testQpsControllerManager) { + // pojo.server.test + QpsController qpsController = testQpsControllerManager.getOrCreate("pojo.server.test"); + Assert.assertEquals("pojo", qpsController.getKey()); + Assert.assertNull(qpsController.getQpsLimit()); + + // pojo.server.test2 + testQpsControllerManager.getOrCreate("pojo.server.test2"); + + // pojo.server.tes + testQpsControllerManager.getOrCreate("pojo.server.tes"); + + // pojo.server2.test + testQpsControllerManager.getOrCreate("pojo.server2.test"); + + // pojo.serve.test + testQpsControllerManager.getOrCreate("pojo.serve.test"); + + // pojo2.server.test + qpsController = testQpsControllerManager.getOrCreate("pojo2.server.test"); + Assert.assertEquals("pojo2", qpsController.getKey()); + Assert.assertNull(qpsController.getQpsLimit()); + + // poj.server.test + qpsController = testQpsControllerManager.getOrCreate("poj.server.test"); + Assert.assertEquals("poj", qpsController.getKey()); + Assert.assertNull(qpsController.getQpsLimit()); + } + + @Test + public void testMock() { + Invocation invocation = getMockInvocation("service", "schema", "oper"); + OperationMeta operationMeta = invocation.getOperationMeta(); + SchemaMeta schemaMeta = operationMeta.getSchemaMeta(); + + Assert.assertEquals("service", operationMeta.getMicroserviceName()); + Assert.assertEquals("service.schema.oper", operationMeta.getMicroserviceQualifiedName()); + Assert.assertEquals("schema.oper", operationMeta.getSchemaQualifiedName()); + Assert.assertEquals("schema", schemaMeta.getSchemaId()); + } + + public static Invocation getMockInvocation(String microserviceName, String schemaId, String operationId) { + return getMockInvocation( + getMockOperationMeta(microserviceName, schemaId, operationId) + ); + } + + private static Invocation getMockInvocation(OperationMeta mockOperationMeta) { + Invocation invocation = Mockito.mock(Invocation.class); + Mockito.when(invocation.getOperationMeta()).thenReturn(mockOperationMeta); + return invocation; + } + + public static OperationMeta getMockOperationMeta(String microserviceName, String schemaId, String operationId) { + OperationMeta operationMeta = Mockito.mock(OperationMeta.class); + SchemaMeta schemaMeta = Mockito.mock(SchemaMeta.class); + + Mockito.when(operationMeta.getSchemaMeta()).thenReturn(schemaMeta); + Mockito.when(operationMeta.getSchemaQualifiedName()) + .thenReturn(schemaId + QpsControllerManager.SEPARATOR + operationId); + Mockito.when(operationMeta.getMicroserviceQualifiedName()).thenReturn( + microserviceName + QpsControllerManager.SEPARATOR + schemaId + QpsControllerManager.SEPARATOR + + operationId); + Mockito.when(operationMeta.getMicroserviceName()).thenReturn(microserviceName); + Mockito.when(schemaMeta.getSchemaId()).thenReturn(schemaId); + + return operationMeta; + } + + public static void setConfig(String key, int value) { + Utils.updateProperty(key, value); + } + + public static void setConfigWithDefaultPrefix(String key, int value) { + String configKey = Config.CONSUMER_LIMIT_KEY_PREFIX + key; + Utils.updateProperty(configKey, value); + } + + public static void clearState(QpsControllerManager qpsControllerManager) { + Map<String, QpsController> objMap = Deencapsulation.getField(qpsControllerManager, "qualifiedNameControllerMap"); + objMap.clear(); + Map<String, QpsController> configQpsControllerMap = Deencapsulation + .getField(qpsControllerManager, "configQpsControllerMap"); + configQpsControllerMap.clear(); + } +} diff --git a/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/TestConsumerQpsControllermanager.java b/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/TestConsumerQpsControllermanager.java deleted file mode 100644 index 426f7f8db..000000000 --- a/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/TestConsumerQpsControllermanager.java +++ /dev/null @@ -1,75 +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.qps; - -import org.apache.servicecomb.core.definition.OperationMeta; -import org.apache.servicecomb.core.definition.SchemaMeta; -import org.junit.Assert; -import org.junit.Test; - -import mockit.Expectations; -import mockit.Mocked; - -/** - * - * - */ -public class TestConsumerQpsControllermanager { - private static String microserviceName = "pojo"; - - private static String schemaQualified = microserviceName + ".server"; - - private static String operationQualified = schemaQualified + ".test"; - - @Test - public void testQpsLimit(@Mocked SchemaMeta schemaMeta, @Mocked OperationMeta operationMeta) { - new Expectations() { - { - operationMeta.getMicroserviceQualifiedName(); - result = operationQualified; - - schemaMeta.getMicroserviceQualifiedName(); - result = schemaQualified; - - operationMeta.getMicroserviceName(); - result = microserviceName; - } - }; - - ConsumerQpsControllerManager mgr = new ConsumerQpsControllerManager(); - QpsController qpsController = mgr.getOrCreate(operationMeta); - Assert.assertEquals((Integer) Integer.MAX_VALUE, qpsController.getQpsLimit()); - Assert.assertEquals(microserviceName, qpsController.getKey()); - - doTestQpsLimit(mgr, operationMeta, microserviceName, 100, microserviceName, 100); - doTestQpsLimit(mgr, operationMeta, schemaQualified, 200, schemaQualified, 200); - doTestQpsLimit(mgr, operationMeta, operationQualified, 300, operationQualified, 300); - doTestQpsLimit(mgr, operationMeta, operationQualified, null, schemaQualified, 200); - doTestQpsLimit(mgr, operationMeta, schemaQualified, null, microserviceName, 100); - doTestQpsLimit(mgr, operationMeta, microserviceName, null, microserviceName, Integer.MAX_VALUE); - } - - private void doTestQpsLimit(ConsumerQpsControllerManager mgr, OperationMeta operationMeta, String key, - Integer newValue, - String expectKey, Integer expectValue) { - Utils.updateProperty(Config.CONSUMER_LIMIT_KEY_PREFIX + key, newValue); - QpsController qpsController = mgr.getOrCreate(operationMeta); - Assert.assertEquals(expectValue, qpsController.getQpsLimit()); - Assert.assertEquals(expectKey, qpsController.getKey()); - } -} diff --git a/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/TestConsumerQpsFlowControlHandler.java b/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/TestConsumerQpsFlowControlHandler.java index 368459e19..6359a7eec 100644 --- a/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/TestConsumerQpsFlowControlHandler.java +++ b/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/TestConsumerQpsFlowControlHandler.java @@ -17,20 +17,22 @@ package org.apache.servicecomb.qps; +import java.util.concurrent.ConcurrentHashMap; + import org.apache.servicecomb.core.Invocation; import org.apache.servicecomb.core.definition.OperationMeta; +import org.apache.servicecomb.foundation.test.scaffolding.config.ArchaiusUtils; import org.apache.servicecomb.swagger.invocation.AsyncResponse; +import org.junit.After; import org.junit.Assert; +import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; +import mockit.Deencapsulation; import mockit.Mock; import mockit.MockUp; -/** - * - * - */ public class TestConsumerQpsFlowControlHandler { ConsumerQpsFlowControlHandler handler = new ConsumerQpsFlowControlHandler(); @@ -41,8 +43,21 @@ OperationMeta operationMeta = Mockito.mock(OperationMeta.class); + @Before + public void setUP() { + ArchaiusUtils.resetConfig(); + QpsControllerManagerTest.clearState(ConsumerQpsFlowControlHandler.qpsControllerMgr); + } + + + @After + public void afterTest() { + ArchaiusUtils.resetConfig(); + QpsControllerManagerTest.clearState(ConsumerQpsFlowControlHandler.qpsControllerMgr); + } + @Test - public void testQpsController() throws Exception { + public void testQpsController() { QpsController qpsController = new QpsController("abc", 100); Assert.assertEquals(false, qpsController.isLimitNewRequest()); @@ -68,9 +83,11 @@ public void testHandle() { boolean validAssert; try { validAssert = true; + String key = "svc.schema.opr"; + QpsController qpsController = new QpsController("key", 12); Mockito.when(invocation.getOperationMeta()).thenReturn(operationMeta); - Mockito.when(operationMeta.getMicroserviceQualifiedName()).thenReturn("MicroserviceQualifiedName"); - + Mockito.when(operationMeta.getMicroserviceQualifiedName()).thenReturn(key); + setQpsController(key, qpsController); new MockUp<QpsController>() { @Mock public boolean isLimitNewRequest() { @@ -78,15 +95,15 @@ public boolean isLimitNewRequest() { } }; - new MockUp<ConsumerQpsControllerManager>() { - + new MockUp<QpsControllerManager>() { @Mock - protected QpsController create(OperationMeta operationMeta) { - return new QpsController("key", 12); + protected QpsController create(String qualifiedNameKey) { + return qpsController; } }; handler.handle(invocation, asyncResp); } catch (Exception e) { + e.printStackTrace(); validAssert = false; } Assert.assertTrue(validAssert); @@ -97,8 +114,11 @@ public void testHandleIsLimitNewRequestAsFalse() { boolean validAssert; try { validAssert = true; + String key = "MicroserviceQualifiedName"; + QpsController qpsController = new QpsController("key", 12); Mockito.when(invocation.getOperationMeta()).thenReturn(operationMeta); - Mockito.when(operationMeta.getMicroserviceQualifiedName()).thenReturn("MicroserviceQualifiedName"); + Mockito.when(operationMeta.getMicroserviceQualifiedName()).thenReturn(key); + setQpsController(key, qpsController); new MockUp<QpsController>() { @Mock @@ -107,17 +127,25 @@ public boolean isLimitNewRequest() { } }; - new MockUp<ConsumerQpsControllerManager>() { + new MockUp<QpsControllerManager>() { @Mock - protected QpsController create(OperationMeta operationMeta) { - return new QpsController("key", 12); + protected QpsController create(String qualifiedNameKey) { + return qpsController; } }; handler.handle(invocation, asyncResp); } catch (Exception e) { + e.printStackTrace(); validAssert = false; } Assert.assertTrue(validAssert); } + + private void setQpsController(String key, QpsController qpsController) { + QpsControllerManager qpsControllerManager = Deencapsulation.getField(handler, "qpsControllerMgr"); + ConcurrentHashMap<String, QpsController> objMap = Deencapsulation + .getField(qpsControllerManager, "qualifiedNameControllerMap"); + objMap.put(key, qpsController); + } } diff --git a/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/TestProviderQpsControllermanager.java b/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/TestProviderQpsControllermanager.java deleted file mode 100644 index c16f7092d..000000000 --- a/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/TestProviderQpsControllermanager.java +++ /dev/null @@ -1,44 +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.qps; - -import org.junit.Assert; -import org.junit.Test; - -public class TestProviderQpsControllermanager { - private static String microserviceName = "pojo"; - - @Test - public void testQpsLimit() { - ProviderQpsControllerManager mgr = new ProviderQpsControllerManager(); - QpsController qpsController = mgr.getOrCreate(microserviceName); - Assert.assertEquals(null, qpsController.getQpsLimit()); - Assert.assertEquals(microserviceName, qpsController.getKey()); - - doTestQpsLimit(mgr, microserviceName, 100, microserviceName, 100); - doTestQpsLimit(mgr, microserviceName, null, microserviceName, null); - } - - private void doTestQpsLimit(ProviderQpsControllerManager mgr, String key, Integer newValue, - String expectKey, Integer expectValue) { - Utils.updateProperty(Config.PROVIDER_LIMIT_KEY_PREFIX + key, newValue); - QpsController qpsController = mgr.getOrCreate(key); - Assert.assertEquals(expectValue, qpsController.getQpsLimit()); - Assert.assertEquals(expectKey, qpsController.getKey()); - } -} diff --git a/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/TestProviderQpsFlowControlHandler.java b/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/TestProviderQpsFlowControlHandler.java index 40303db8e..1bdf8a215 100644 --- a/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/TestProviderQpsFlowControlHandler.java +++ b/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/TestProviderQpsFlowControlHandler.java @@ -17,10 +17,14 @@ package org.apache.servicecomb.qps; +import static org.junit.Assert.fail; + import org.apache.servicecomb.core.Const; import org.apache.servicecomb.core.Invocation; import org.apache.servicecomb.core.definition.OperationMeta; +import org.apache.servicecomb.foundation.test.scaffolding.config.ArchaiusUtils; import org.apache.servicecomb.swagger.invocation.AsyncResponse; +import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -42,9 +46,18 @@ @Before public void setUP() { + ArchaiusUtils.resetConfig(); + QpsControllerManagerTest.clearState(ProviderQpsFlowControlHandler.qpsControllerMgr); Utils.updateProperty(Config.PROVIDER_LIMIT_KEY_PREFIX + "test", 1); } + + @After + public void afterTest() { + ArchaiusUtils.resetConfig(); + QpsControllerManagerTest.clearState(ProviderQpsFlowControlHandler.qpsControllerMgr); + } + @Test public void testGlobalQpsControl(final @Injectable Invocation invocation, final @Injectable AsyncResponse asyncResp) throws Exception { @@ -52,6 +65,8 @@ public void testGlobalQpsControl(final @Injectable Invocation invocation, { invocation.getContext(Const.SRC_MICROSERVICE); result = "test"; + invocation.getOperationMeta(); + result = QpsControllerManagerTest.getMockOperationMeta("pojo", "server", "opr"); asyncResp.producerFail((Throwable) any); result = new RuntimeException("test error"); } @@ -67,7 +82,7 @@ public void testGlobalQpsControl(final @Injectable Invocation invocation, gHandler.handle(invocation, asyncResp); count++; gHandler.handle(invocation, asyncResp); - Assert.assertTrue(false); + fail("An exception is expected!"); } catch (Exception e) { Assert.assertEquals(2, count); Assert.assertEquals("test error", e.getMessage()); @@ -75,7 +90,7 @@ public void testGlobalQpsControl(final @Injectable Invocation invocation, } @Test - public void testQpsController() throws Exception { + public void testQpsController() { QpsController qpsController = new QpsController("abc", 100); Assert.assertEquals(false, qpsController.isLimitNewRequest()); @@ -93,6 +108,7 @@ public void testHandleWithException() { handler.handle(invocation, asyncResp); handler.handle(invocation, asyncResp); } catch (Exception e) { + e.printStackTrace(); validAssert = false; } Assert.assertTrue(validAssert); @@ -104,6 +120,8 @@ public void testHandle() { try { validAssert = true; Mockito.when(invocation.getContext(Const.SRC_MICROSERVICE)).thenReturn("test"); + OperationMeta mockOperationMeta = QpsControllerManagerTest.getMockOperationMeta("pojo", "server", "opr"); + Mockito.when(invocation.getOperationMeta()).thenReturn(mockOperationMeta); new MockUp<QpsController>() { @Mock @@ -112,15 +130,16 @@ public boolean isLimitNewRequest() { } }; - new MockUp<ProviderQpsControllerManager>() { + new MockUp<QpsControllerManager>() { @Mock - protected QpsController create(String serviceName) { - return new QpsController(serviceName, 12); + protected QpsController create(String qualifiedNameKey) { + return new QpsController(qualifiedNameKey, 12); } }; handler.handle(invocation, asyncResp); } catch (Exception e) { + e.printStackTrace(); validAssert = false; } Assert.assertTrue(validAssert); @@ -132,6 +151,9 @@ public void testHandleIsLimitNewRequestAsFalse() { try { validAssert = true; Mockito.when(invocation.getContext(Const.SRC_MICROSERVICE)).thenReturn("test"); + OperationMeta mockOperationMeta = QpsControllerManagerTest + .getMockOperationMeta("pojo", "server", "opr"); + Mockito.when(invocation.getOperationMeta()).thenReturn(mockOperationMeta); new MockUp<QpsController>() { @Mock @@ -140,15 +162,16 @@ public boolean isLimitNewRequest() { } }; - new MockUp<ProviderQpsControllerManager>() { + new MockUp<QpsControllerManager>() { @Mock - protected QpsController create(String serviceName) { - return new QpsController(serviceName, 12); + protected QpsController create(String qualifiedNameKey) { + return new QpsController(qualifiedNameKey, 12); } }; handler.handle(invocation, asyncResp); } catch (Exception e) { + e.printStackTrace(); validAssert = false; } Assert.assertTrue(validAssert); ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: [email protected] With regards, Apache Git Services
