You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2018/03/22 09:16:35 UTC

[incubator-servicecomb-java-chassis] branch master updated (f37cbfd -> a7ea310)

This is an automated email from the ASF dual-hosted git repository.

liubao pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git.


    from f37cbfd  simplify unit test case
     new 28eedb4  Fault-Injection handler implementation
     new ebd1ced  Review comments fix:Fault-Injection handler
     new ee2b626  Review comments fix:Fault-Injection handler
     new d382693  Review comments fix:Fault-Injection handler
     new a7ea310  Review comments fix:Fault-Injection handler

The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 coverage-reports/pom.xml                           |   4 +
 .../pom.xml                                        |   4 +-
 .../servicecomb/faultinjection/AbortFault.java     |  67 ++
 .../servicecomb/faultinjection/AbstractFault.java  |   4 +-
 .../servicecomb/faultinjection/DelayFault.java     |  78 +++
 .../apache/servicecomb/faultinjection/Fault.java   |  16 +-
 .../servicecomb/faultinjection/FaultExecutor.java  |  65 ++
 .../faultinjection/FaultInjectionConfig.java       |  59 ++
 .../faultinjection/FaultInjectionConst.java        |  21 +-
 .../faultinjection/FaultInjectionHandler.java      |  74 +++
 .../faultinjection/FaultInjectionUtil.java         | 165 +++++
 .../servicecomb/faultinjection/FaultParam.java     |  37 +-
 .../org.apache.servicecomb.faultinjection.Fault    |   5 +-
 .../src/main}/resources/config/cse.handler.xml     |   4 +-
 .../faultinjection/TestFaultInjectConfig.java      |  89 +++
 .../faultinjection/TestFaultInjectHandler.java     | 706 +++++++++++++++++++++
 .../faultinjection/TestFaultInjectUtil.java        |  28 +-
 handlers/pom.xml                                   |   1 +
 java-chassis-dependencies/pom.xml                  |   5 +
 java-chassis-distribution/pom.xml                  |   4 +
 20 files changed, 1392 insertions(+), 44 deletions(-)
 copy handlers/{handler-flowcontrol-qps => handler-fault-injection}/pom.xml (94%)
 mode change 100644 => 100755
 create mode 100644 handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/AbortFault.java
 copy dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/client/ConnSuccEvent.java => handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/AbstractFault.java (88%)
 create mode 100644 handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/DelayFault.java
 copy core/src/main/java/org/apache/servicecomb/core/event/InvocationStartEvent.java => handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/Fault.java (75%)
 create mode 100644 handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultExecutor.java
 create mode 100755 handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionConfig.java
 copy foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/performance/PerfStat.java => handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionConst.java (60%)
 create mode 100755 handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionHandler.java
 create mode 100755 handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionUtil.java
 copy foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/executor/VertxWorkerExecutor.java => handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultParam.java (61%)
 copy common/common-rest/src/test/resources/config/test.properties => handlers/handler-fault-injection/src/main/resources/META-INF/services/org.apache.servicecomb.faultinjection.Fault (88%)
 copy {core/src/test => handlers/handler-fault-injection/src/main}/resources/config/cse.handler.xml (88%)
 mode change 100644 => 100755
 create mode 100644 handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectConfig.java
 create mode 100644 handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectHandler.java
 copy core/src/test/java/org/apache/servicecomb/core/Utils.java => handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectUtil.java (57%)

-- 
To stop receiving notification emails like this one, please contact
liubao@apache.org.

[incubator-servicecomb-java-chassis] 02/05: Review comments fix:Fault-Injection handler

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git

commit ebd1cedb00d387afda8096778d1098777f8a4783
Author: maheshrajus <ma...@huawei.com>
AuthorDate: Wed Mar 21 18:19:22 2018 +0530

    Review comments fix:Fault-Injection handler
---
 .../servicecomb/faultinjection/AbortFault.java     | 26 ++++----
 .../servicecomb/faultinjection/DelayFault.java     | 54 ++++++++---------
 .../apache/servicecomb/faultinjection/Fault.java   |  3 +-
 .../servicecomb/faultinjection/FaultExecutor.java  | 70 ++++++++++++++++++++++
 .../faultinjection/FaultInjectionConfig.java       |  6 +-
 .../faultinjection/FaultInjectionConst.java        |  8 +--
 .../faultinjection/FaultInjectionHandler.java      | 34 +++++++----
 .../faultinjection/FaultInjectionUtil.java         | 10 ++--
 .../servicecomb/faultinjection/FaultParam.java     | 12 ++++
 .../faultinjection/TestFaultInjectConfig.java      | 11 ++--
 .../faultinjection/TestFaultInjectHandler.java     | 56 +++++++++++------
 11 files changed, 207 insertions(+), 83 deletions(-)

diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/AbortFault.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/AbortFault.java
index 3bf4d84..c878899 100644
--- a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/AbortFault.java
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/AbortFault.java
@@ -18,6 +18,7 @@
 package org.apache.servicecomb.faultinjection;
 
 import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.swagger.invocation.AsyncResponse;
 import org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -28,14 +29,15 @@ public class AbortFault extends AbstractFault {
   private static final Logger LOGGER = LoggerFactory.getLogger(FaultInjectionConfig.class);
 
   @Override
-  public FaultResponse injectFault(Invocation invocation, FaultParam faultParam) {
+  public void injectFault(Invocation invocation, FaultParam faultParam, AsyncResponse asynResponse) {
     // get the config values related to delay.
     int abortPercent = FaultInjectionUtil.getFaultInjectionConfig(invocation,
         "abort.percent");
 
-    if (abortPercent == FaultInjectionConst.FAULT_INJECTION_CFG_NULL) {
-      LOGGER.info("Fault injection: Abort percentage is not configured");
-      return new FaultResponse();
+    if (abortPercent == FaultInjectionConst.FAULT_INJECTION_DEFAULT_VALUE) {
+      LOGGER.debug("Fault injection: Abort percentage is not configured");
+      asynResponse.success(new FaultResponse());
+      return;
     }
 
     // check fault abort condition.
@@ -45,20 +47,24 @@ public class AbortFault extends AbstractFault {
       int errorCode = FaultInjectionUtil.getFaultInjectionConfig(invocation,
           "abort.httpStatus");
 
-      if (errorCode == FaultInjectionConst.FAULT_INJECTION_CFG_NULL) {
-        LOGGER.info("Fault injection: Abort error code is not configured");
-        return new FaultResponse();
+      if (errorCode == FaultInjectionConst.FAULT_INJECTION_DEFAULT_VALUE) {
+        LOGGER.debug("Fault injection: Abort error code is not configured");
+        asynResponse.success(new FaultResponse());
+        return;
       }
       // if request need to be abort then return failure with given error code
       CommonExceptionData errorData = new CommonExceptionData("aborted by fault inject");
-      return new FaultResponse(-1, errorCode, errorData);
+
+      FaultResponse response = new FaultResponse(FaultInjectionConst.FAULT_INJECTION_ERROR, errorCode, errorData);
+      asynResponse.success(response);
+      return;
     }
 
-    return new FaultResponse();
+    asynResponse.success(new FaultResponse());
   }
 
   @Override
   public int getPriority() {
-    return FaultInjectionConst.FAULTINJECTION_PRIORITY_MIN;
+    return 200;
   }
 }
diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/DelayFault.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/DelayFault.java
index 5ab0ed9..aaf2f63 100644
--- a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/DelayFault.java
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/DelayFault.java
@@ -17,10 +17,8 @@
 
 package org.apache.servicecomb.faultinjection;
 
-import java.util.concurrent.CountDownLatch;
-
 import org.apache.servicecomb.core.Invocation;
-import org.apache.servicecomb.foundation.vertx.VertxUtils;
+import org.apache.servicecomb.swagger.invocation.AsyncResponse;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
@@ -34,48 +32,50 @@ public class DelayFault extends AbstractFault {
 
   @Override
   public int getPriority() {
-    return FaultInjectionConst.FAULTINJECTION_PRIORITY_MAX;
+    return 100;
   }
 
   @Override
-  public FaultResponse injectFault(Invocation invocation, FaultParam faultAttributes) {
+  public void injectFault(Invocation invocation, FaultParam faultParam, AsyncResponse asynResponse) {
     int delayPercent = FaultInjectionUtil.getFaultInjectionConfig(invocation,
         "delay.percent");
 
-    if (delayPercent == FaultInjectionConst.FAULT_INJECTION_CFG_NULL) {
-      LOGGER.info("Fault injection: delay percentage is not configured");
-      return new FaultResponse();
+    if (delayPercent == FaultInjectionConst.FAULT_INJECTION_DEFAULT_VALUE) {
+      LOGGER.debug("Fault injection: delay percentage is not configured");
+      asynResponse.success(new FaultResponse());
+      return;
     }
 
     // check fault delay condition.
-    boolean isDelay = FaultInjectionUtil.checkFaultInjectionDelayAndAbort(faultAttributes.getReqCount(), delayPercent);
+    boolean isDelay = FaultInjectionUtil.checkFaultInjectionDelayAndAbort(faultParam.getReqCount(), delayPercent);
     if (isDelay) {
-      LOGGER.info("Fault injection: delay is added for the request by fault inject handler");
+      LOGGER.debug("Fault injection: delay is added for the request by fault inject handler");
       long delay = FaultInjectionUtil.getFaultInjectionConfig(invocation,
           "delay.fixedDelay");
 
-      if (delay == FaultInjectionConst.FAULT_INJECTION_CFG_NULL) {
-        LOGGER.info("Fault injection: delay is not configured");
-        return new FaultResponse();
+      if (delay == FaultInjectionConst.FAULT_INJECTION_DEFAULT_VALUE) {
+        LOGGER.debug("Fault injection: delay is not configured");
+        asynResponse.success(new FaultResponse());
+        return;
       }
 
-      CountDownLatch latch = new CountDownLatch(1);
-      Vertx vertx = VertxUtils.getOrCreateVertxByName("faultinjection", null);
-      vertx.setTimer(delay, new Handler<Long>() {
-        @Override
-        public void handle(Long timeID) {
-          latch.countDown();
+      Vertx vertx = faultParam.getVertx();
+      if (vertx != null) {
+        vertx.setTimer(delay, new Handler<Long>() {
+          @Override
+          public void handle(Long timeID) {
+            asynResponse.success(new FaultResponse());
+          }
+        });
+      } else {
+        try {
+          Thread.sleep(delay);
+        } catch (InterruptedException e) {
+          LOGGER.info("Interrupted exception is received");
         }
-      });
-
-      try {
-        latch.await();
-      } catch (InterruptedException e) {
-        LOGGER.info("Interrupted exception is received");
+        asynResponse.success(new FaultResponse());
       }
     }
-
-    return new FaultResponse();
   }
 
 }
diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/Fault.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/Fault.java
index 9d17e07..6f50c62 100644
--- a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/Fault.java
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/Fault.java
@@ -18,10 +18,11 @@
 package org.apache.servicecomb.faultinjection;
 
 import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.swagger.invocation.AsyncResponse;
 
 public interface Fault {
 
   int getPriority();
 
-  FaultResponse injectFault(Invocation invocation, FaultParam faultAttributes);
+  void injectFault(Invocation invocation, FaultParam faultAttributes, AsyncResponse asynResponse);
 }
diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultExecutor.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultExecutor.java
new file mode 100644
index 0000000..291b1c8
--- /dev/null
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultExecutor.java
@@ -0,0 +1,70 @@
+/*
+ * 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.faultinjection;
+
+import java.util.List;
+
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.swagger.invocation.AsyncResponse;
+import org.apache.servicecomb.swagger.invocation.Response;
+
+
+/**
+ * Implements the fault feature execution one after other.
+ */
+public class FaultExecutor {
+  private List<Fault> faultInjectList;
+
+  private int handlerIndex = 0;
+
+  private Invocation invocation;
+
+  private FaultParam param;
+
+  public FaultExecutor(List<Fault> faultInjectList, Invocation invocation, FaultParam param) {
+    this.faultInjectList = faultInjectList;
+    this.invocation = invocation;
+    this.param = param;
+  }
+
+  public void execute(AsyncResponse asyncResponse) {
+    this.next(asyncResponse);
+  }
+
+  private void next(AsyncResponse asyncResponse) {
+    if (handlerIndex >= faultInjectList.size()) {
+      asyncResponse.complete(Response.succResp(new FaultResponse()));
+      return;
+    }
+
+    int runIndex = handlerIndex;
+    handlerIndex++;
+    faultInjectList.get(runIndex).injectFault(invocation, param, response -> {
+      if (response.isFailed()) {
+        asyncResponse.complete(response);
+      } else {
+        FaultResponse r = response.getResult();
+        if (r.getStatusCode() != 0) {
+          asyncResponse.complete(response);
+        } else {
+          FaultExecutor.this.next(asyncResponse);
+        }
+      }
+    });
+  }
+}
diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionConfig.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionConfig.java
index f6000e5..d43eb2f 100755
--- a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionConfig.java
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionConfig.java
@@ -42,8 +42,7 @@ public final class FaultInjectionConfig {
     DynamicIntProperty dynamicIntProperty = DynamicPropertyFactory.getInstance().getIntProperty(config,
         defaultValue);
 
-    if (cfgCallback.get(config) == null) {
-      cfgCallback.put(config, config);
+    cfgCallback.computeIfAbsent(config, key -> {
       dynamicIntProperty.addCallback(() -> {
         int newValue = dynamicIntProperty.get();
         String cfgName = dynamicIntProperty.getName();
@@ -52,7 +51,8 @@ public final class FaultInjectionConfig {
         FaultInjectionUtil.setConfigCenterValue(cfgName, new AtomicInteger(newValue));
         LOGGER.info("{} changed to {}", cfgName, newValue);
       });
-    }
+      return config;
+    });
 
     return dynamicIntProperty.get();
   }
diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionConst.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionConst.java
index fdc2a8b..b1221e7 100644
--- a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionConst.java
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionConst.java
@@ -22,15 +22,13 @@ package org.apache.servicecomb.faultinjection;
  */
 public class FaultInjectionConst {
 
-  public static final int FAULT_INJECTION_CFG_NULL = -1;
+  public static final int FAULT_INJECTION_DEFAULT_VALUE = -1;
+
+  public static final int FAULT_INJECTION_ERROR = -1;
 
   public static final String CONSUMER_FAULTINJECTION = "cse.governance.Consumer.";
 
   public static final String CONSUMER_FAULTINJECTION_GLOBAL = "cse.governance.Consumer._global.";
 
   public static final String CONSUMER_FAULTINJECTION_POLICY_PROTOCOLS = "policy.fault.protocols.";
-
-  public static final int FAULTINJECTION_PRIORITY_MIN = 10;
-
-  public static final int FAULTINJECTION_PRIORITY_MAX = 1;
 }
diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionHandler.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionHandler.java
index 090b5a9..204049c 100755
--- a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionHandler.java
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionHandler.java
@@ -24,9 +24,11 @@ import java.util.concurrent.atomic.AtomicLong;
 import org.apache.servicecomb.core.Handler;
 import org.apache.servicecomb.core.Invocation;
 import org.apache.servicecomb.swagger.invocation.AsyncResponse;
-import org.apache.servicecomb.swagger.invocation.context.HttpStatus;
 import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
 
+import io.vertx.core.Context;
+import io.vertx.core.Vertx;
+
 /**
  * Fault injection handler which injects the delay/abort for requests based on
  * the percentage configured in service file.
@@ -57,16 +59,28 @@ public class FaultInjectionHandler implements Handler {
     // increment the request count here after checking the delay/abort condition.
     reqCount.incrementAndGet();
 
-    for (Fault fault : faultInjectionFeatureList) {
-      FaultResponse faultResponse = fault.injectFault(invocation, new FaultParam(reqCountCurrent));
-
-      if (faultResponse.getStatusCode() != 0) {
-        asyncResp.consumerFail(new InvocationException(new HttpStatus(faultResponse.getErrorCode(),
-            "invocation exception induced by fault injection"), faultResponse.getErrorData()));
-        return;
-      }
+    FaultParam param = new FaultParam(reqCountCurrent);
+    Context currentContext = Vertx.currentContext();
+    if (currentContext != null && currentContext.isEventLoopContext()) {
+      param.setVertx(currentContext.owner());
     }
 
-    invocation.next(asyncResp);
+    FaultExecutor executor = new FaultExecutor(faultInjectionFeatureList, invocation, param);
+    executor.execute(response -> {
+      try {
+        if (response.isFailed()) {
+          asyncResp.complete(response);
+        } else {
+          FaultResponse r = response.getResult();
+          if (r.getStatusCode() == FaultInjectionConst.FAULT_INJECTION_ERROR) {
+            asyncResp.consumerFail(new InvocationException(r.getErrorCode(), "", r.getErrorData()));
+            return;
+          }
+          invocation.next(asyncResp);
+        }
+      } catch (Exception e) {
+        asyncResp.consumerFail(e);
+      }
+    });
   }
 }
diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionUtil.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionUtil.java
index 2ff4abf..18dba50 100755
--- a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionUtil.java
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionUtil.java
@@ -20,7 +20,7 @@ package org.apache.servicecomb.faultinjection;
 import static org.apache.servicecomb.faultinjection.FaultInjectionConst.CONSUMER_FAULTINJECTION;
 import static org.apache.servicecomb.faultinjection.FaultInjectionConst.CONSUMER_FAULTINJECTION_GLOBAL;
 import static org.apache.servicecomb.faultinjection.FaultInjectionConst.CONSUMER_FAULTINJECTION_POLICY_PROTOCOLS;
-import static org.apache.servicecomb.faultinjection.FaultInjectionConst.FAULT_INJECTION_CFG_NULL;
+import static org.apache.servicecomb.faultinjection.FaultInjectionConst.FAULT_INJECTION_DEFAULT_VALUE;
 
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -90,7 +90,7 @@ public class FaultInjectionUtil {
         + CONSUMER_FAULTINJECTION_POLICY_PROTOCOLS + invocation.getTransport().getName() + "." + key;
 
     value = getConfigValue(config);
-    if ((value != FAULT_INJECTION_CFG_NULL)) {
+    if ((value != FAULT_INJECTION_DEFAULT_VALUE)) {
       return value;
     }
 
@@ -98,14 +98,14 @@ public class FaultInjectionUtil {
         + CONSUMER_FAULTINJECTION_POLICY_PROTOCOLS + invocation.getTransport().getName() + "." + key;
 
     value = getConfigValue(config);
-    if ((value != FAULT_INJECTION_CFG_NULL)) {
+    if ((value != FAULT_INJECTION_DEFAULT_VALUE)) {
       return value;
     }
 
     config = CONSUMER_FAULTINJECTION + serviceName + "." + CONSUMER_FAULTINJECTION_POLICY_PROTOCOLS
         + invocation.getTransport().getName() + "." + key;
     value = getConfigValue(config);
-    if ((value != FAULT_INJECTION_CFG_NULL)) {
+    if ((value != FAULT_INJECTION_DEFAULT_VALUE)) {
       return value;
     }
 
@@ -130,7 +130,7 @@ public class FaultInjectionUtil {
       return cfgMap.get(config).get();
     }
 
-    value = FaultInjectionConfig.getConfigVal(config, FAULT_INJECTION_CFG_NULL);
+    value = FaultInjectionConfig.getConfigVal(config, FAULT_INJECTION_DEFAULT_VALUE);
     return value;
 
   }
diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultParam.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultParam.java
index 0dcd19b..92f0e84 100644
--- a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultParam.java
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultParam.java
@@ -17,12 +17,16 @@
 
 package org.apache.servicecomb.faultinjection;
 
+import io.vertx.core.Vertx;
+
 /**
  * Fault injection parameters which decides the fault injection condition.
  */
 public class FaultParam {
   private long reqCount;
 
+  private Vertx vertx;
+
   public long getReqCount() {
     return reqCount;
   }
@@ -34,4 +38,12 @@ public class FaultParam {
   FaultParam(long reqCount) {
     this.reqCount = reqCount;
   }
+
+  public Vertx getVertx() {
+    return vertx;
+  }
+
+  public void setVertx(Vertx vertx) {
+    this.vertx = vertx;
+  }
 }
diff --git a/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectConfig.java b/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectConfig.java
index f4d3137..4c2a08e 100644
--- a/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectConfig.java
+++ b/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectConfig.java
@@ -71,16 +71,17 @@ public class TestFaultInjectConfig {
   public void testConstants() {
     assertEquals("cse.governance.Consumer.", FaultInjectionConst.CONSUMER_FAULTINJECTION);
     assertEquals("policy.fault.protocols.", FaultInjectionConst.CONSUMER_FAULTINJECTION_POLICY_PROTOCOLS);
-    assertEquals(-1, FaultInjectionConst.FAULT_INJECTION_CFG_NULL);
+    assertEquals(-1, FaultInjectionConst.FAULT_INJECTION_DEFAULT_VALUE);
     assertEquals("cse.governance.Consumer._global.", FaultInjectionConst.CONSUMER_FAULTINJECTION_GLOBAL);
-    assertEquals(10, FaultInjectionConst.FAULTINJECTION_PRIORITY_MIN);
-    assertEquals(1, FaultInjectionConst.FAULTINJECTION_PRIORITY_MAX);
+    assertEquals(-1, FaultInjectionConst.FAULT_INJECTION_ERROR);
   }
 
   @Test
   public void testFaultParam() {
     faultParam.setReqCount(100);
+    faultParam.setVertx(null);
     assertEquals(100, faultParam.getReqCount());
+    assertEquals(null, faultParam.getVertx());
   }
 
   @Test
@@ -96,7 +97,7 @@ public class TestFaultInjectConfig {
 
   @Test
   public void testFaultPriority() {
-    assertEquals(10, abortFault.getPriority());
-    assertEquals(1, delayFault.getPriority());
+    assertEquals(200, abortFault.getPriority());
+    assertEquals(100, delayFault.getPriority());
   }
 }
diff --git a/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectHandler.java b/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectHandler.java
index 7288f78..600c59a 100644
--- a/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectHandler.java
+++ b/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectHandler.java
@@ -26,6 +26,7 @@ import java.util.concurrent.atomic.AtomicLong;
 import org.apache.servicecomb.core.Invocation;
 import org.apache.servicecomb.core.Transport;
 import org.apache.servicecomb.core.definition.OperationMeta;
+import org.apache.servicecomb.foundation.vertx.VertxUtils;
 import org.apache.servicecomb.swagger.invocation.AsyncResponse;
 import org.apache.servicecomb.swagger.invocation.Response;
 import org.junit.After;
@@ -36,6 +37,8 @@ import org.mockito.InjectMocks;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
+import io.vertx.core.Vertx;
+
 /**
  * Tests the fault injection handler functionality.
  */
@@ -139,7 +142,7 @@ public class TestFaultInjectHandler {
     Mockito.when(invocation.getSchemaId()).thenReturn("sayHelloSchema");
     Mockito.when(invocation.getMicroserviceName()).thenReturn("hello");
 
-    List<Fault> faultInjectionFeatureList = Arrays.asList(abortFault, delayFault);
+    List<Fault> faultInjectionFeatureList = Arrays.asList(delayFault, abortFault);
     handler.setFaultFeature(faultInjectionFeatureList);
 
     handler.handle(invocation, asyncResp);
@@ -367,7 +370,6 @@ public class TestFaultInjectHandler {
     Mockito.when(invocation.getSchemaId()).thenReturn("testSchema1");
     Mockito.when(invocation.getMicroserviceName()).thenReturn("carts1");
     boolean validAssert;
-    long timeOld = System.currentTimeMillis();
 
     List<Fault> faultInjectionFeatureList = Arrays.asList(delayFault, abortFault);
     handler.setFaultFeature(faultInjectionFeatureList);
@@ -385,15 +387,9 @@ public class TestFaultInjectHandler {
         .updateProperty("cse.governance.Consumer._global.policy.fault.protocols.rest.abort.httpStatus", 421);
 
     handler.handle(invocation, ar -> {
-      //check whether error code return, defaut is 421.
-      assertEquals(421, response.getStatusCode());
       assertEquals(true, response.isFailed());
-      long timeNow = System.currentTimeMillis();
-      //if really time delay is added it should be greater than 5s.
-      Assert.assertTrue((timeNow - timeOld) >= 500);
     });
 
-
     System.getProperties()
         .remove(
             "cse.governance.Consumer._global.policy.fault.protocols.rest.delay.fixedDelay");
@@ -617,7 +613,6 @@ public class TestFaultInjectHandler {
 
     AtomicLong count = FaultInjectionUtil.getOperMetTotalReq("restMicroserviceQualifiedName10");
     assertEquals(3, count.get());
-
   }
 
   /**
@@ -641,7 +636,6 @@ public class TestFaultInjectHandler {
     Mockito.when(invocation.getSchemaId()).thenReturn("testSchema4");
     Mockito.when(invocation.getMicroserviceName()).thenReturn("carts5");
     boolean validAssert;
-    long timeOld = System.currentTimeMillis();
 
     List<Fault> faultInjectionFeatureList = Arrays.asList(delayFault, abortFault);
     handler.setFaultFeature(faultInjectionFeatureList);
@@ -657,15 +651,9 @@ public class TestFaultInjectHandler {
         .updateProperty("cse.governance.Consumer.carts5.policy.fault.protocols.rest.abort.percent", 500);
 
     handler.handle(invocation, ar -> {
-      //check whether error code return,
-      assertEquals(421, response.getStatusCode());
       assertEquals(true, response.isFailed());
-      long timeNow = System.currentTimeMillis();
-      //if really time delay is added it should be greater than 5s.
-      Assert.assertTrue((timeNow - timeOld) >= 500);
     });
 
-
     System.getProperties()
         .remove("cse.governance.Consumer.carts5.policy.fault.protocols.rest.delay.fixedDelay");
     System.getProperties()
@@ -675,9 +663,43 @@ public class TestFaultInjectHandler {
     System.getProperties()
         .remove("cse.governance.Consumer.carts5.policy.fault.protocols.rest.abort.httpStatus");
 
-
     AtomicLong count = FaultInjectionUtil.getOperMetTotalReq("restMicroserviceQualifiedName11");
     assertEquals(3, count.get());
+  }
+
+  /**
+   * Tests the fault injection handler functionality with configuration change event for service level config.
+   * 
+   * @throws Exception
+   */
+  @Test
+  public void testFaultInjectHandlerConfigChangeEvent6() throws Exception {
+    System.setProperty("cse.governance.Consumer.carts6.policy.fault.protocols.rest.delay.fixedDelay", "1000");
+
+    System.setProperty(
+        "cse.governance.Consumer.carts6.policy.fault.protocols.rest.delay.percent",
+        "100");
+
+    Mockito.when(invocation.getMicroserviceQualifiedName()).thenReturn("MicroserviceQualifiedName12");
+    Mockito.when(invocation.getTransport()).thenReturn(transport);
+    Mockito.when(transport.getName()).thenReturn("rest");
+    Mockito.when(invocation.getOperationName()).thenReturn("sayBye4");
+    Mockito.when(invocation.getSchemaId()).thenReturn("testSchema4");
+    Mockito.when(invocation.getMicroserviceName()).thenReturn("carts6");
+
+    DelayFault delayFault = new DelayFault();
+    FaultParam faultParam = new FaultParam(3);
+    Vertx vertx = VertxUtils.getOrCreateVertxByName("faultinjectionTest", null);
+    faultParam.setVertx(vertx);
+
+    delayFault.injectFault(invocation, faultParam, ar);
+    System.getProperties()
+        .remove("cse.governance.Consumer.carts6.policy.fault.protocols.rest.delay.fixedDelay");
+    System.getProperties()
+        .remove("cse.governance.Consumer.carts6.policy.fault.protocols.rest.delay.percent");
+
+    AtomicLong count = FaultInjectionUtil.getOperMetTotalReq("restMicroserviceQualifiedName12");
+    assertEquals(1, count.get());
 
   }
 }

-- 
To stop receiving notification emails like this one, please contact
liubao@apache.org.

[incubator-servicecomb-java-chassis] 03/05: Review comments fix:Fault-Injection handler

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git

commit ee2b62627e47b003d85255174eecefc190077be7
Author: maheshrajus <ma...@huawei.com>
AuthorDate: Wed Mar 21 20:05:49 2018 +0530

    Review comments fix:Fault-Injection handler
---
 .../servicecomb/faultinjection/AbortFault.java     |  6 +-
 .../servicecomb/faultinjection/AbstractFault.java  |  3 -
 .../servicecomb/faultinjection/DelayFault.java     |  3 +-
 .../servicecomb/faultinjection/FaultExecutor.java  |  2 +-
 .../src/main/resources/config/cse.handler.xml      |  2 +-
 .../faultinjection/TestFaultInjectHandler.java     | 67 +++++++++++-----------
 6 files changed, 41 insertions(+), 42 deletions(-)

diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/AbortFault.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/AbortFault.java
index c878899..f53eef3 100644
--- a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/AbortFault.java
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/AbortFault.java
@@ -26,11 +26,11 @@ import org.springframework.stereotype.Component;
 
 @Component
 public class AbortFault extends AbstractFault {
-  private static final Logger LOGGER = LoggerFactory.getLogger(FaultInjectionConfig.class);
+  private static final Logger LOGGER = LoggerFactory.getLogger(AbortFault.class);
 
   @Override
   public void injectFault(Invocation invocation, FaultParam faultParam, AsyncResponse asynResponse) {
-    // get the config values related to delay.
+    // get the config values related to abort.
     int abortPercent = FaultInjectionUtil.getFaultInjectionConfig(invocation,
         "abort.percent");
 
@@ -43,7 +43,7 @@ public class AbortFault extends AbstractFault {
     // check fault abort condition.
     boolean isAbort = FaultInjectionUtil.checkFaultInjectionDelayAndAbort(faultParam.getReqCount(), abortPercent);
     if (isAbort) {
-      // get the config values related to delay percentage.
+      // get the config values related to abort percentage.
       int errorCode = FaultInjectionUtil.getFaultInjectionConfig(invocation,
           "abort.httpStatus");
 
diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/AbstractFault.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/AbstractFault.java
index db88a5e..e92a68e 100644
--- a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/AbstractFault.java
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/AbstractFault.java
@@ -17,9 +17,6 @@
 
 package org.apache.servicecomb.faultinjection;
 
-import org.springframework.stereotype.Component;
-
-@Component
 public abstract class AbstractFault implements Fault {
 
 }
diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/DelayFault.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/DelayFault.java
index aaf2f63..e486ae3 100644
--- a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/DelayFault.java
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/DelayFault.java
@@ -28,7 +28,7 @@ import io.vertx.core.Vertx;
 
 @Component
 public class DelayFault extends AbstractFault {
-  private static final Logger LOGGER = LoggerFactory.getLogger(FaultInjectionHandler.class);
+  private static final Logger LOGGER = LoggerFactory.getLogger(DelayFault.class);
 
   @Override
   public int getPriority() {
@@ -76,6 +76,7 @@ public class DelayFault extends AbstractFault {
         asynResponse.success(new FaultResponse());
       }
     }
+    asynResponse.success(new FaultResponse());
   }
 
 }
diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultExecutor.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultExecutor.java
index 291b1c8..c5a0e9b 100644
--- a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultExecutor.java
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultExecutor.java
@@ -59,7 +59,7 @@ public class FaultExecutor {
         asyncResponse.complete(response);
       } else {
         FaultResponse r = response.getResult();
-        if (r.getStatusCode() != 0) {
+        if (r.getStatusCode() == FaultInjectionConst.FAULT_INJECTION_ERROR) {
           asyncResponse.complete(response);
         } else {
           FaultExecutor.this.next(asyncResponse);
diff --git a/handlers/handler-fault-injection/src/main/resources/config/cse.handler.xml b/handlers/handler-fault-injection/src/main/resources/config/cse.handler.xml
index 477963b..4c1553e 100755
--- a/handlers/handler-fault-injection/src/main/resources/config/cse.handler.xml
+++ b/handlers/handler-fault-injection/src/main/resources/config/cse.handler.xml
@@ -16,6 +16,6 @@
   -->
 
 <config>
-	<handler id="fault-injection"
+	<handler id="fault-injection-consumer"
 		class="org.apache.servicecomb.faultinjection.FaultInjectionHandler" />
 </config>
diff --git a/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectHandler.java b/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectHandler.java
index 600c59a..255de43 100644
--- a/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectHandler.java
+++ b/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectHandler.java
@@ -55,6 +55,9 @@ public class TestFaultInjectHandler {
 
   Response response;
 
+  boolean isDelay;
+
+  boolean isAbort;
 
   @InjectMocks
   FaultInjectionHandler faultHandler;
@@ -172,23 +175,22 @@ public class TestFaultInjectHandler {
     Mockito.when(invocation.getSchemaId()).thenReturn("sayHelloSchema");
     Mockito.when(invocation.getMicroserviceName()).thenReturn("hello");
 
-    List<Fault> faultInjectionFeatureList = Arrays.asList(abortFault, delayFault);
+    List<Fault> faultInjectionFeatureList = Arrays.asList(abortFault);
     handler.setFaultFeature(faultInjectionFeatureList);
 
-    boolean validAssert;
-    try {
-      validAssert = true;
-      handler.handle(invocation, asyncResp);
-    } catch (Exception e) {
-      validAssert = false;
-    }
+    handler.handle(invocation, ar -> {
+      //this case no delay/no abort so reponse is null, it should not enter this in this block.
+      isDelay = true;
+      isAbort = true;
+    });
+    Assert.assertFalse(isDelay);
+    Assert.assertFalse(isAbort);
 
     System.getProperties().remove("cse.governance.Consumer._global.policy.fault.protocols.rest.delay.fixedDelay");
     System.getProperties().remove("cse.governance.Consumer._global.policy.fault.protocols.rest.delay.percent");
     System.getProperties().remove("cse.governance.Consumer._global.policy.fault.protocols.rest.abort.percent");
     System.getProperties().remove("cse.governance.Consumer._global.policy.fault.protocols.rest.abort.httpStatus");
 
-    Assert.assertTrue(validAssert);
     AtomicLong count = FaultInjectionUtil.getOperMetTotalReq("restMicroserviceQualifiedName3");
     assertEquals(2, count.get());
   }
@@ -217,20 +219,19 @@ public class TestFaultInjectHandler {
     List<Fault> faultInjectionFeatureList = Arrays.asList(abortFault, delayFault);
     handler.setFaultFeature(faultInjectionFeatureList);
 
-    boolean validAssert;
-    try {
-      validAssert = true;
-      handler.handle(invocation, asyncResp);
-    } catch (Exception e) {
-      validAssert = false;
-    }
+    handler.handle(invocation, ar -> {
+      //this case no delay/no abort so reponse is null, it should not enter this in this block.
+      isDelay = true;
+      isAbort = true;
+    });
+    Assert.assertFalse(isDelay);
+    Assert.assertFalse(isAbort);
 
     System.getProperties().remove("cse.governance.Consumer.carts.policy.fault.protocols.rest.delay.fixedDelay");
     System.getProperties().remove("cse.governance.Consumer.carts.policy.fault.protocols.rest.delay.percent");
     System.getProperties().remove("cse.governance.Consumer.carts.policy.fault.protocols.rest.abort.percent");
     System.getProperties().remove("cse.governance.Consumer.carts.policy.fault.protocols.rest.abort.httpStatus");
 
-    Assert.assertTrue(validAssert);
     AtomicLong count = FaultInjectionUtil.getOperMetTotalReq("restMicroserviceQualifiedName4");
     assertEquals(2, count.get());
   }
@@ -263,13 +264,13 @@ public class TestFaultInjectHandler {
     List<Fault> faultInjectionFeatureList = Arrays.asList(abortFault, delayFault);
     handler.setFaultFeature(faultInjectionFeatureList);
 
-    boolean validAssert;
-    try {
-      validAssert = true;
-      handler.handle(invocation, asyncResp);
-    } catch (Exception e) {
-      validAssert = false;
-    }
+    handler.handle(invocation, ar -> {
+      //this case no delay/no abort so reponse is null, it should not enter this in this block.
+      isDelay = true;
+      isAbort = true;
+    });
+    Assert.assertFalse(isDelay);
+    Assert.assertFalse(isAbort);
 
     System.getProperties()
         .remove("cse.governance.Consumer.carts.schemas.testSchema.policy.fault.protocols.rest.delay.fixedDelay");
@@ -280,7 +281,6 @@ public class TestFaultInjectHandler {
     System.getProperties()
         .remove("cse.governance.Consumer.carts.schemas.testSchema.policy.fault.protocols.rest.abort.httpStatus");
 
-    Assert.assertTrue(validAssert);
     AtomicLong count = FaultInjectionUtil.getOperMetTotalReq("restMicroserviceQualifiedName5");
     assertEquals(2, count.get());
   }
@@ -317,13 +317,14 @@ public class TestFaultInjectHandler {
     List<Fault> faultInjectionFeatureList = Arrays.asList(abortFault, delayFault);
     handler.setFaultFeature(faultInjectionFeatureList);
 
-    boolean validAssert;
-    try {
-      validAssert = true;
-      handler.handle(invocation, asyncResp);
-    } catch (Exception e) {
-      validAssert = false;
-    }
+    handler.handle(invocation, ar -> {
+      //this case no delay/no abort so reponse is null, it should not enter this in this block.
+      isDelay = true;
+      isAbort = true;
+    });
+
+    Assert.assertFalse(isDelay);
+    Assert.assertFalse(isAbort);
 
     System.getProperties()
         .remove(
@@ -337,7 +338,7 @@ public class TestFaultInjectHandler {
     System.getProperties()
         .remove(
             "cse.governance.Consumer.carts.schemas.testSchema.operations.sayHi.policy.fault.protocols.rest.abort.httpStatus");
-    Assert.assertTrue(validAssert);
+
     AtomicLong count = FaultInjectionUtil.getOperMetTotalReq("restMicroserviceQualifiedName6");
     assertEquals(2, count.get());
   }

-- 
To stop receiving notification emails like this one, please contact
liubao@apache.org.

[incubator-servicecomb-java-chassis] 01/05: Fault-Injection handler implementation

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git

commit 28eedb4b2493430d39e82903ba87010edd0e06ef
Author: maheshrajus <ma...@huawei.com>
AuthorDate: Tue Mar 20 22:27:24 2018 +0530

    Fault-Injection handler implementation
---
 coverage-reports/pom.xml                           |   4 +
 handlers/handler-fault-injection/pom.xml           |  44 ++
 .../servicecomb/faultinjection/AbortFault.java     |  64 ++
 .../servicecomb/faultinjection/AbstractFault.java  |  25 +
 .../servicecomb/faultinjection/BeanHolder.java     |  47 ++
 .../servicecomb/faultinjection/DelayFault.java     |  81 +++
 .../apache/servicecomb/faultinjection/Fault.java   |  27 +
 .../faultinjection/FaultInjectionConfig.java       |  59 ++
 .../faultinjection/FaultInjectionConst.java        |  36 ++
 .../faultinjection/FaultInjectionHandler.java      |  72 +++
 .../faultinjection/FaultInjectionUtil.java         | 168 +++++
 .../servicecomb/faultinjection/FaultParam.java     |  37 ++
 .../servicecomb/faultinjection/FaultResponse.java  |  63 ++
 .../main/resources/META-INF/spring/cse.bean.xml}   |  37 +-
 .../src/main/resources/config/cse.handler.xml      |  21 +
 .../faultinjection/TestFaultInjectConfig.java      | 102 +++
 .../faultinjection/TestFaultInjectHandler.java     | 683 +++++++++++++++++++++
 .../faultinjection/TestFaultInjectUtil.java        |  73 +++
 handlers/pom.xml                                   |   1 +
 java-chassis-dependencies/pom.xml                  |   5 +
 java-chassis-distribution/pom.xml                  |   4 +
 21 files changed, 1629 insertions(+), 24 deletions(-)

diff --git a/coverage-reports/pom.xml b/coverage-reports/pom.xml
index 27a6c0e..337ae26 100644
--- a/coverage-reports/pom.xml
+++ b/coverage-reports/pom.xml
@@ -72,6 +72,10 @@
     </dependency>
     <dependency>
       <groupId>org.apache.servicecomb</groupId>
+      <artifactId>handler-fault-injection</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.servicecomb</groupId>
       <artifactId>common-rest</artifactId>
     </dependency>
     <dependency>
diff --git a/handlers/handler-fault-injection/pom.xml b/handlers/handler-fault-injection/pom.xml
new file mode 100755
index 0000000..3fda7b4
--- /dev/null
+++ b/handlers/handler-fault-injection/pom.xml
@@ -0,0 +1,44 @@
+<!--
+  ~ 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.
+  -->
+
+<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-m2-SNAPSHOT</version>
+	</parent>
+	<artifactId>handler-fault-injection</artifactId>
+	<name>Java Chassis::Handlers::Fault Injection</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>
+</project>
diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/AbortFault.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/AbortFault.java
new file mode 100644
index 0000000..3bf4d84
--- /dev/null
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/AbortFault.java
@@ -0,0 +1,64 @@
+/*
+ * 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.faultinjection;
+
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+public class AbortFault extends AbstractFault {
+  private static final Logger LOGGER = LoggerFactory.getLogger(FaultInjectionConfig.class);
+
+  @Override
+  public FaultResponse injectFault(Invocation invocation, FaultParam faultParam) {
+    // get the config values related to delay.
+    int abortPercent = FaultInjectionUtil.getFaultInjectionConfig(invocation,
+        "abort.percent");
+
+    if (abortPercent == FaultInjectionConst.FAULT_INJECTION_CFG_NULL) {
+      LOGGER.info("Fault injection: Abort percentage is not configured");
+      return new FaultResponse();
+    }
+
+    // check fault abort condition.
+    boolean isAbort = FaultInjectionUtil.checkFaultInjectionDelayAndAbort(faultParam.getReqCount(), abortPercent);
+    if (isAbort) {
+      // get the config values related to delay percentage.
+      int errorCode = FaultInjectionUtil.getFaultInjectionConfig(invocation,
+          "abort.httpStatus");
+
+      if (errorCode == FaultInjectionConst.FAULT_INJECTION_CFG_NULL) {
+        LOGGER.info("Fault injection: Abort error code is not configured");
+        return new FaultResponse();
+      }
+      // if request need to be abort then return failure with given error code
+      CommonExceptionData errorData = new CommonExceptionData("aborted by fault inject");
+      return new FaultResponse(-1, errorCode, errorData);
+    }
+
+    return new FaultResponse();
+  }
+
+  @Override
+  public int getPriority() {
+    return FaultInjectionConst.FAULTINJECTION_PRIORITY_MIN;
+  }
+}
diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/AbstractFault.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/AbstractFault.java
new file mode 100644
index 0000000..db88a5e
--- /dev/null
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/AbstractFault.java
@@ -0,0 +1,25 @@
+/*
+ * 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.faultinjection;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public abstract class AbstractFault implements Fault {
+
+}
diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/BeanHolder.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/BeanHolder.java
new file mode 100644
index 0000000..756ad4b
--- /dev/null
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/BeanHolder.java
@@ -0,0 +1,47 @@
+/*
+ * 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.faultinjection;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class BeanHolder {
+
+  @Inject
+  private List<Fault> faultInjectionFeatureList = Collections.emptyList();
+
+  public void init() {
+    //sort the fault injection feature list based on priority.
+    Collections.sort(faultInjectionFeatureList, new Comparator<Fault>() {
+
+      @Override
+      public int compare(Fault o1, Fault o2) {
+        return Integer.compare(o1.getPriority(), o2.getPriority());
+      }
+    });
+
+    FaultInjectionHandler.getFaultFeature().addAll(faultInjectionFeatureList);
+
+  }
+}
diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/DelayFault.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/DelayFault.java
new file mode 100644
index 0000000..5ab0ed9
--- /dev/null
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/DelayFault.java
@@ -0,0 +1,81 @@
+/*
+ * 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.faultinjection;
+
+import java.util.concurrent.CountDownLatch;
+
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.foundation.vertx.VertxUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import io.vertx.core.Handler;
+import io.vertx.core.Vertx;
+
+@Component
+public class DelayFault extends AbstractFault {
+  private static final Logger LOGGER = LoggerFactory.getLogger(FaultInjectionHandler.class);
+
+  @Override
+  public int getPriority() {
+    return FaultInjectionConst.FAULTINJECTION_PRIORITY_MAX;
+  }
+
+  @Override
+  public FaultResponse injectFault(Invocation invocation, FaultParam faultAttributes) {
+    int delayPercent = FaultInjectionUtil.getFaultInjectionConfig(invocation,
+        "delay.percent");
+
+    if (delayPercent == FaultInjectionConst.FAULT_INJECTION_CFG_NULL) {
+      LOGGER.info("Fault injection: delay percentage is not configured");
+      return new FaultResponse();
+    }
+
+    // check fault delay condition.
+    boolean isDelay = FaultInjectionUtil.checkFaultInjectionDelayAndAbort(faultAttributes.getReqCount(), delayPercent);
+    if (isDelay) {
+      LOGGER.info("Fault injection: delay is added for the request by fault inject handler");
+      long delay = FaultInjectionUtil.getFaultInjectionConfig(invocation,
+          "delay.fixedDelay");
+
+      if (delay == FaultInjectionConst.FAULT_INJECTION_CFG_NULL) {
+        LOGGER.info("Fault injection: delay is not configured");
+        return new FaultResponse();
+      }
+
+      CountDownLatch latch = new CountDownLatch(1);
+      Vertx vertx = VertxUtils.getOrCreateVertxByName("faultinjection", null);
+      vertx.setTimer(delay, new Handler<Long>() {
+        @Override
+        public void handle(Long timeID) {
+          latch.countDown();
+        }
+      });
+
+      try {
+        latch.await();
+      } catch (InterruptedException e) {
+        LOGGER.info("Interrupted exception is received");
+      }
+    }
+
+    return new FaultResponse();
+  }
+
+}
diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/Fault.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/Fault.java
new file mode 100644
index 0000000..9d17e07
--- /dev/null
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/Fault.java
@@ -0,0 +1,27 @@
+/*
+ * 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.faultinjection;
+
+import org.apache.servicecomb.core.Invocation;
+
+public interface Fault {
+
+  int getPriority();
+
+  FaultResponse injectFault(Invocation invocation, FaultParam faultAttributes);
+}
diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionConfig.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionConfig.java
new file mode 100755
index 0000000..f6000e5
--- /dev/null
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionConfig.java
@@ -0,0 +1,59 @@
+/*
+ * 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.faultinjection;
+
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.netflix.config.DynamicIntProperty;
+import com.netflix.config.DynamicPropertyFactory;
+
+/**
+ * Handles the fault injection configuration read from micro service file/config
+ * center.
+ */
+public final class FaultInjectionConfig {
+
+  private static final Logger LOGGER = LoggerFactory.getLogger(FaultInjectionConfig.class);
+
+  // key is configuration parameter.
+  private static Map<String, String> cfgCallback = new ConcurrentHashMapEx<>();
+
+  public static int getConfigVal(String config, int defaultValue) {
+    DynamicIntProperty dynamicIntProperty = DynamicPropertyFactory.getInstance().getIntProperty(config,
+        defaultValue);
+
+    if (cfgCallback.get(config) == null) {
+      cfgCallback.put(config, config);
+      dynamicIntProperty.addCallback(() -> {
+        int newValue = dynamicIntProperty.get();
+        String cfgName = dynamicIntProperty.getName();
+
+        //store the value in config center map and check for next requests.
+        FaultInjectionUtil.setConfigCenterValue(cfgName, new AtomicInteger(newValue));
+        LOGGER.info("{} changed to {}", cfgName, newValue);
+      });
+    }
+
+    return dynamicIntProperty.get();
+  }
+}
diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionConst.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionConst.java
new file mode 100644
index 0000000..fdc2a8b
--- /dev/null
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionConst.java
@@ -0,0 +1,36 @@
+/*
+ * 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.faultinjection;
+
+/**
+ * Handles the all constant values for fault injection.
+ */
+public class FaultInjectionConst {
+
+  public static final int FAULT_INJECTION_CFG_NULL = -1;
+
+  public static final String CONSUMER_FAULTINJECTION = "cse.governance.Consumer.";
+
+  public static final String CONSUMER_FAULTINJECTION_GLOBAL = "cse.governance.Consumer._global.";
+
+  public static final String CONSUMER_FAULTINJECTION_POLICY_PROTOCOLS = "policy.fault.protocols.";
+
+  public static final int FAULTINJECTION_PRIORITY_MIN = 10;
+
+  public static final int FAULTINJECTION_PRIORITY_MAX = 1;
+}
diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionHandler.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionHandler.java
new file mode 100755
index 0000000..090b5a9
--- /dev/null
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionHandler.java
@@ -0,0 +1,72 @@
+/*
+ * 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.faultinjection;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.apache.servicecomb.core.Handler;
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.swagger.invocation.AsyncResponse;
+import org.apache.servicecomb.swagger.invocation.context.HttpStatus;
+import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
+
+/**
+ * Fault injection handler which injects the delay/abort for requests based on
+ * the percentage configured in service file.
+ *
+ */
+
+public class FaultInjectionHandler implements Handler {
+
+  private static List<Fault> faultInjectionFeatureList = new ArrayList<>();
+
+  //added only for unit testing
+  public void setFaultFeature(List<Fault> faultFeature) {
+    faultInjectionFeatureList = faultFeature;
+  }
+
+  public static List<Fault> getFaultFeature() {
+    return faultInjectionFeatureList;
+  }
+
+  @Override
+  public void handle(Invocation invocation, AsyncResponse asyncResp) throws Exception {
+
+    // prepare the key and lookup for request count.
+    String key = invocation.getTransport().getName() + invocation.getMicroserviceQualifiedName();
+    AtomicLong reqCount = FaultInjectionUtil.getOperMetTotalReq(key);
+    long reqCountCurrent = reqCount.get();
+
+    // increment the request count here after checking the delay/abort condition.
+    reqCount.incrementAndGet();
+
+    for (Fault fault : faultInjectionFeatureList) {
+      FaultResponse faultResponse = fault.injectFault(invocation, new FaultParam(reqCountCurrent));
+
+      if (faultResponse.getStatusCode() != 0) {
+        asyncResp.consumerFail(new InvocationException(new HttpStatus(faultResponse.getErrorCode(),
+            "invocation exception induced by fault injection"), faultResponse.getErrorData()));
+        return;
+      }
+    }
+
+    invocation.next(asyncResp);
+  }
+}
diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionUtil.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionUtil.java
new file mode 100755
index 0000000..2ff4abf
--- /dev/null
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionUtil.java
@@ -0,0 +1,168 @@
+/*
+ * 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.faultinjection;
+
+import static org.apache.servicecomb.faultinjection.FaultInjectionConst.CONSUMER_FAULTINJECTION;
+import static org.apache.servicecomb.faultinjection.FaultInjectionConst.CONSUMER_FAULTINJECTION_GLOBAL;
+import static org.apache.servicecomb.faultinjection.FaultInjectionConst.CONSUMER_FAULTINJECTION_POLICY_PROTOCOLS;
+import static org.apache.servicecomb.faultinjection.FaultInjectionConst.FAULT_INJECTION_CFG_NULL;
+
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;
+
+/**
+ * Handles the count for all request based key[transport + microservice qualified name].
+ */
+public class FaultInjectionUtil {
+
+  // key is transport+operQualifiedName
+  private static Map<String, AtomicLong> requestCount = new ConcurrentHashMapEx<>();
+
+  // key is config paramter
+  private static Map<String, AtomicInteger> configCenterValue = new ConcurrentHashMapEx<>();
+
+  /**
+   * Returns total requests per provider for operational level.
+   * 
+   * @param key
+   *            transport+operational name
+   * @return long total requests
+   */
+  public static AtomicLong getOperMetTotalReq(String key) {
+    return requestCount.computeIfAbsent(key, p -> new AtomicLong(1));
+  }
+
+  /**
+   * Returns the map of config parameter key and values.
+   * @return value of config parameter map
+   */
+  public static Map<String, AtomicInteger> getConfigCenterMap() {
+    return configCenterValue;
+  }
+
+  /**
+   * Sets the value for given config parameter.
+   * @param key
+   * @param value
+   */
+  public static void setConfigCenterValue(String key, AtomicInteger value) {
+    configCenterValue.put(key, value);
+  }
+
+  /**
+   * Handles the reading fault injection configuration.
+   * 
+   * @param invocation
+   *            invocation of request
+   * @param key
+   *            configuration key
+   * @return configuration value
+   */
+  public static int getFaultInjectionConfig(Invocation invocation, String key) {
+    int value = 0;
+    String config;
+
+    // get the config base on priority. operationName-->schema-->service-->global
+    String operationName = invocation.getOperationName();
+    String schema = invocation.getSchemaId();
+    String serviceName = invocation.getMicroserviceName();
+
+    config = CONSUMER_FAULTINJECTION + serviceName + ".schemas." + schema + ".operations." + operationName + "."
+        + CONSUMER_FAULTINJECTION_POLICY_PROTOCOLS + invocation.getTransport().getName() + "." + key;
+
+    value = getConfigValue(config);
+    if ((value != FAULT_INJECTION_CFG_NULL)) {
+      return value;
+    }
+
+    config = CONSUMER_FAULTINJECTION + serviceName + ".schemas." + schema + "."
+        + CONSUMER_FAULTINJECTION_POLICY_PROTOCOLS + invocation.getTransport().getName() + "." + key;
+
+    value = getConfigValue(config);
+    if ((value != FAULT_INJECTION_CFG_NULL)) {
+      return value;
+    }
+
+    config = CONSUMER_FAULTINJECTION + serviceName + "." + CONSUMER_FAULTINJECTION_POLICY_PROTOCOLS
+        + invocation.getTransport().getName() + "." + key;
+    value = getConfigValue(config);
+    if ((value != FAULT_INJECTION_CFG_NULL)) {
+      return value;
+    }
+
+    config = CONSUMER_FAULTINJECTION_GLOBAL + CONSUMER_FAULTINJECTION_POLICY_PROTOCOLS
+        + invocation.getTransport().getName() + "." + key;
+
+    value = getConfigValue(config);
+    return value;
+  }
+
+  /**
+   * Get the configuration value
+   * @param config config parameter
+   * @return int value
+   */
+  private static int getConfigValue(String config) {
+    int value = 0;
+    //first need to check in config center map which has high priority.
+    Map<String, AtomicInteger> cfgMap = FaultInjectionUtil.getConfigCenterMap();
+
+    if (cfgMap.containsKey(config)) {
+      return cfgMap.get(config).get();
+    }
+
+    value = FaultInjectionConfig.getConfigVal(config, FAULT_INJECTION_CFG_NULL);
+    return value;
+
+  }
+
+  /**
+   * It will check the delay/abort condition based on request count and percentage
+   * received.
+   * 
+   * @param reqCount
+   * @param percentage
+   * @param key
+   * @return true/false
+   */
+  public static boolean checkFaultInjectionDelayAndAbort(long reqCount, int percentage) {
+    /*
+     * Example: delay/abort percentage configured is 10% and Get the count(suppose
+     * if it is 10th request) from map and calculate resultNew(10th request) and
+     * requestOld(9th request). Like this for every request it will calculate
+     * current request count and previous count. if both not matched need to add
+     * delay/abort otherwise no need to add.
+     */
+
+    // calculate the value with current request count.
+    long resultNew = (reqCount * percentage) / 100;
+
+    // calculate the value with previous count value.
+    long resultOld = ((reqCount - 1) * percentage) / 100;
+
+    // if both are not matching then delay/abort should be added.
+    if (resultNew != resultOld) {
+      return true;
+    }
+    return false;
+  }
+}
diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultParam.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultParam.java
new file mode 100644
index 0000000..0dcd19b
--- /dev/null
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultParam.java
@@ -0,0 +1,37 @@
+/*
+ * 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.faultinjection;
+
+/**
+ * Fault injection parameters which decides the fault injection condition.
+ */
+public class FaultParam {
+  private long reqCount;
+
+  public long getReqCount() {
+    return reqCount;
+  }
+
+  public void setReqCount(long reqCount) {
+    this.reqCount = reqCount;
+  }
+
+  FaultParam(long reqCount) {
+    this.reqCount = reqCount;
+  }
+}
diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultResponse.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultResponse.java
new file mode 100644
index 0000000..ee59d71
--- /dev/null
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultResponse.java
@@ -0,0 +1,63 @@
+/*
+ * 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.faultinjection;
+
+/**
+ * Fault response which contains status of fault injection.
+ */
+public class FaultResponse {
+  private int statusCode;
+
+  private int errorCode;
+
+  private Object errorData;
+
+  FaultResponse(int statusCode, int errorCode, Object errorData) {
+    this.statusCode = statusCode;
+    this.errorCode = errorCode;
+    this.errorData = errorData;
+  }
+
+  FaultResponse() {
+  }
+
+  public int getStatusCode() {
+    return statusCode;
+  }
+
+  public void setStatusCode(int statusCode) {
+    this.statusCode = statusCode;
+  }
+
+  public int getErrorCode() {
+    return errorCode;
+  }
+
+  public void setErrorCode(int errorCode) {
+    this.errorCode = errorCode;
+  }
+
+  public Object getErrorData() {
+    return errorData;
+  }
+
+  public void setErrorData(Object errorData) {
+    this.errorData = errorData;
+  }
+
+}
diff --git a/handlers/pom.xml b/handlers/handler-fault-injection/src/main/resources/META-INF/spring/cse.bean.xml
old mode 100644
new mode 100755
similarity index 51%
copy from handlers/pom.xml
copy to handlers/handler-fault-injection/src/main/resources/META-INF/spring/cse.bean.xml
index 2afaa77..b8f5c57
--- a/handlers/pom.xml
+++ b/handlers/handler-fault-injection/src/main/resources/META-INF/spring/cse.bean.xml
@@ -16,27 +16,16 @@
   ~ limitations under the License.
   -->
 
-<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">
-  <parent>
-    <groupId>org.apache.servicecomb</groupId>
-    <artifactId>java-chassis-parent</artifactId>
-    <version>1.0.0-m2-SNAPSHOT</version>
-    <relativePath>../parent</relativePath>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-
-  <artifactId>handlers</artifactId>
-  <name>Java Chassis::Handlers</name>
-  <packaging>pom</packaging>
-
-  <modules>
-    <module>handler-tracing-zipkin</module>
-    <module>handler-bizkeeper</module>
-    <module>handler-flowcontrol-qps</module>
-    <module>handler-loadbalance</module>
-    <module>handler-publickey-auth</module>
-  </modules>
-
-</project>
+  <beans xmlns = "http://www.springframework.org/schema/beans"
+   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
+   xmlns:context = "http://www.springframework.org/schema/context"
+   xsi:schemaLocation = "http://www.springframework.org/schema/beans
+   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+   http://www.springframework.org/schema/context
+   http://www.springframework.org/schema/context/spring-context-3.0.xsd">
+  
+  <context:annotation-config />
+	<!-- <context:spring-configured /> -->
+  <context:component-scan base-package="org.apache.servicecomb.faultinjection" />
+  <bean class="org.apache.servicecomb.faultinjection.BeanHolder" init-method="init"/>
+</beans>
diff --git a/handlers/handler-fault-injection/src/main/resources/config/cse.handler.xml b/handlers/handler-fault-injection/src/main/resources/config/cse.handler.xml
new file mode 100755
index 0000000..477963b
--- /dev/null
+++ b/handlers/handler-fault-injection/src/main/resources/config/cse.handler.xml
@@ -0,0 +1,21 @@
+<!--
+  ~ 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.
+  -->
+
+<config>
+	<handler id="fault-injection"
+		class="org.apache.servicecomb.faultinjection.FaultInjectionHandler" />
+</config>
diff --git a/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectConfig.java b/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectConfig.java
new file mode 100644
index 0000000..f4d3137
--- /dev/null
+++ b/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectConfig.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.faultinjection;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests the fault injection configuration.
+ */
+public class TestFaultInjectConfig {
+  FaultInjectionConfig faultCfg;
+
+  FaultInjectionConst faultConst;
+
+  FaultInjectionUtil faultUtil;
+
+  FaultParam faultParam;
+
+  FaultResponse faultResp;
+
+  AbortFault abortFault;
+
+  DelayFault delayFault;
+
+  @Before
+  public void setUp() throws Exception {
+    faultCfg = new FaultInjectionConfig();
+    faultConst = new FaultInjectionConst();
+    faultUtil = new FaultInjectionUtil();
+    faultParam = new FaultParam(10);
+    faultResp = new FaultResponse();
+    abortFault = new AbortFault();
+    delayFault = new DelayFault();
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    faultCfg = null;
+    faultConst = null;
+    faultUtil = null;
+    faultParam = null;
+  }
+
+  @Test
+  public void testFaultInjectConfig() throws Exception {
+    int val = FaultInjectionConfig.getConfigVal("cse.servicecomb.handler.consumer.faultinject.config", 0);
+    Assert.assertEquals(0, val);
+  }
+
+  @Test
+  public void testConstants() {
+    assertEquals("cse.governance.Consumer.", FaultInjectionConst.CONSUMER_FAULTINJECTION);
+    assertEquals("policy.fault.protocols.", FaultInjectionConst.CONSUMER_FAULTINJECTION_POLICY_PROTOCOLS);
+    assertEquals(-1, FaultInjectionConst.FAULT_INJECTION_CFG_NULL);
+    assertEquals("cse.governance.Consumer._global.", FaultInjectionConst.CONSUMER_FAULTINJECTION_GLOBAL);
+    assertEquals(10, FaultInjectionConst.FAULTINJECTION_PRIORITY_MIN);
+    assertEquals(1, FaultInjectionConst.FAULTINJECTION_PRIORITY_MAX);
+  }
+
+  @Test
+  public void testFaultParam() {
+    faultParam.setReqCount(100);
+    assertEquals(100, faultParam.getReqCount());
+  }
+
+  @Test
+  public void testFaultResponse() {
+    Object obj = new Object();
+    faultResp.setErrorCode(100);
+    faultResp.setErrorData(obj);
+    faultResp.setStatusCode(123);
+    assertEquals(123, faultResp.getStatusCode());
+    assertEquals(100, faultResp.getErrorCode());
+    assertEquals(obj, faultResp.getErrorData());
+  }
+
+  @Test
+  public void testFaultPriority() {
+    assertEquals(10, abortFault.getPriority());
+    assertEquals(1, delayFault.getPriority());
+  }
+}
diff --git a/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectHandler.java b/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectHandler.java
new file mode 100644
index 0000000..7288f78
--- /dev/null
+++ b/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectHandler.java
@@ -0,0 +1,683 @@
+/*
+ * 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.faultinjection;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.Transport;
+import org.apache.servicecomb.core.definition.OperationMeta;
+import org.apache.servicecomb.swagger.invocation.AsyncResponse;
+import org.apache.servicecomb.swagger.invocation.Response;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Tests the fault injection handler functionality.
+ */
+public class TestFaultInjectHandler {
+  FaultInjectionHandler handler;
+
+  Invocation invocation;
+
+  AsyncResponse asyncResp;
+
+  OperationMeta operationMeta;
+
+  private Transport transport;
+
+  Response response;
+
+
+  @InjectMocks
+  FaultInjectionHandler faultHandler;
+
+  @InjectMocks
+  AbortFault abortFault;
+
+  @InjectMocks
+  DelayFault delayFault;
+
+  AsyncResponse ar = new AsyncResponse() {
+    @Override
+    public void handle(Response resp) {
+      response = resp;
+    }
+  };
+
+
+  @Before
+  public void setUp() throws Exception {
+    handler = new FaultInjectionHandler();
+
+    invocation = Mockito.mock(Invocation.class);
+
+    asyncResp = Mockito.mock(AsyncResponse.class);
+
+    operationMeta = Mockito.mock(OperationMeta.class);
+
+    transport = Mockito.mock(Transport.class);
+    MockitoAnnotations.initMocks(this);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    handler = null;
+
+    invocation = null;
+
+    asyncResp = null;
+
+    operationMeta = null;
+
+    transport = null;
+  }
+
+  /**
+   * Tests the fault injection handler functionality with default values for
+   * highway transport.
+   * 
+   * @throws Exception
+   */
+  @Test
+  public void testFaultInjectHandlerHighwayWithDefaultCfg() throws Exception {
+
+    Mockito.when(invocation.getMicroserviceQualifiedName()).thenReturn("MicroserviceQualifiedName1");
+    Mockito.when(invocation.getTransport()).thenReturn(transport);
+    Mockito.when(transport.getName()).thenReturn("highway");
+    Mockito.when(invocation.getOperationName()).thenReturn("sayHello");
+    Mockito.when(invocation.getSchemaId()).thenReturn("sayHelloSchema");
+    Mockito.when(invocation.getMicroserviceName()).thenReturn("hello");
+
+
+    List<Fault> faultInjectionFeatureList = Arrays.asList(abortFault, delayFault);
+    handler.setFaultFeature(faultInjectionFeatureList);
+
+    handler.handle(invocation, asyncResp);
+
+    AtomicLong count = FaultInjectionUtil.getOperMetTotalReq("highwayMicroserviceQualifiedName1");
+    assertEquals(2, count.get());
+  }
+
+  /**
+   * Tests the fault injection handler functionality with default values for rest
+   * transport.
+   * 
+   * @throws Exception
+   */
+  @Test
+  public void testFaultInjectHandlerRestWithDefaultCfg() throws Exception {
+
+    Mockito.when(invocation.getMicroserviceQualifiedName()).thenReturn("MicroserviceQualifiedName2");
+    Mockito.when(invocation.getTransport()).thenReturn(transport);
+    Mockito.when(transport.getName()).thenReturn("rest");
+    Mockito.when(invocation.getOperationName()).thenReturn("sayHello");
+    Mockito.when(invocation.getSchemaId()).thenReturn("sayHelloSchema");
+    Mockito.when(invocation.getMicroserviceName()).thenReturn("hello");
+
+    List<Fault> faultInjectionFeatureList = Arrays.asList(abortFault, delayFault);
+    handler.setFaultFeature(faultInjectionFeatureList);
+
+    handler.handle(invocation, asyncResp);
+
+    AtomicLong count = FaultInjectionUtil.getOperMetTotalReq("restMicroserviceQualifiedName2");
+    assertEquals(2, count.get());
+  }
+
+  /**
+   * Tests the fault injection handler functionality with global configuration
+   * with delay/abort condition.
+   * 
+   * @throws Exception
+   */
+  @Test
+  public void testFaultInjectHandlerConfigChangeGlobal() throws Exception {
+
+    System.setProperty("cse.governance.Consumer._global.policy.fault.protocols.rest.delay.fixedDelay", "5");
+    System.setProperty("cse.governance.Consumer._global.policy.fault.protocols.rest.delay.percent", "10");
+    System.setProperty("cse.governance.Consumer._global.policy.fault.protocols.rest.abort.percent", "10");
+    System.setProperty("cse.governance.Consumer._global.policy.fault.protocols.rest.abort.httpStatus", "421");
+
+    Mockito.when(invocation.getMicroserviceQualifiedName()).thenReturn("MicroserviceQualifiedName3");
+    Mockito.when(invocation.getTransport()).thenReturn(transport);
+    Mockito.when(transport.getName()).thenReturn("rest");
+    Mockito.when(invocation.getOperationName()).thenReturn("sayHello");
+    Mockito.when(invocation.getSchemaId()).thenReturn("sayHelloSchema");
+    Mockito.when(invocation.getMicroserviceName()).thenReturn("hello");
+
+    List<Fault> faultInjectionFeatureList = Arrays.asList(abortFault, delayFault);
+    handler.setFaultFeature(faultInjectionFeatureList);
+
+    boolean validAssert;
+    try {
+      validAssert = true;
+      handler.handle(invocation, asyncResp);
+    } catch (Exception e) {
+      validAssert = false;
+    }
+
+    System.getProperties().remove("cse.governance.Consumer._global.policy.fault.protocols.rest.delay.fixedDelay");
+    System.getProperties().remove("cse.governance.Consumer._global.policy.fault.protocols.rest.delay.percent");
+    System.getProperties().remove("cse.governance.Consumer._global.policy.fault.protocols.rest.abort.percent");
+    System.getProperties().remove("cse.governance.Consumer._global.policy.fault.protocols.rest.abort.httpStatus");
+
+    Assert.assertTrue(validAssert);
+    AtomicLong count = FaultInjectionUtil.getOperMetTotalReq("restMicroserviceQualifiedName3");
+    assertEquals(2, count.get());
+  }
+
+  /**
+   * Tests the fault injection handler functionality with service level configuration
+   * with delay/abort condition.
+   * 
+   * @throws Exception
+   */
+  @Test
+  public void testFaultInjectHandlerServiceCfgSuccess() throws Exception {
+
+    System.setProperty("cse.governance.Consumer.carts.policy.fault.protocols.rest.delay.fixedDelay", "1");
+    System.setProperty("cse.governance.Consumer.carts.policy.fault.protocols.rest.delay.percent", "10");
+    System.setProperty("cse.governance.Consumer.carts.policy.fault.protocols.rest.abort.percent", "10");
+    System.setProperty("cse.governance.Consumer.carts.policy.fault.protocols.rest.abort.httpStatus", "421");
+
+    Mockito.when(invocation.getMicroserviceQualifiedName()).thenReturn("MicroserviceQualifiedName4");
+    Mockito.when(invocation.getTransport()).thenReturn(transport);
+    Mockito.when(transport.getName()).thenReturn("rest");
+    Mockito.when(invocation.getOperationName()).thenReturn("sayHello");
+    Mockito.when(invocation.getSchemaId()).thenReturn("sayHelloSchema");
+    Mockito.when(invocation.getMicroserviceName()).thenReturn("carts");
+
+    List<Fault> faultInjectionFeatureList = Arrays.asList(abortFault, delayFault);
+    handler.setFaultFeature(faultInjectionFeatureList);
+
+    boolean validAssert;
+    try {
+      validAssert = true;
+      handler.handle(invocation, asyncResp);
+    } catch (Exception e) {
+      validAssert = false;
+    }
+
+    System.getProperties().remove("cse.governance.Consumer.carts.policy.fault.protocols.rest.delay.fixedDelay");
+    System.getProperties().remove("cse.governance.Consumer.carts.policy.fault.protocols.rest.delay.percent");
+    System.getProperties().remove("cse.governance.Consumer.carts.policy.fault.protocols.rest.abort.percent");
+    System.getProperties().remove("cse.governance.Consumer.carts.policy.fault.protocols.rest.abort.httpStatus");
+
+    Assert.assertTrue(validAssert);
+    AtomicLong count = FaultInjectionUtil.getOperMetTotalReq("restMicroserviceQualifiedName4");
+    assertEquals(2, count.get());
+  }
+
+  /**
+   * Tests the fault injection handler functionality with schema level configuration
+   * with delay/abort condition.
+   * 
+   * @throws Exception
+   */
+  @Test
+  public void testFaultInjectHandlerSchemaCfgSuccess() throws Exception {
+
+    System.setProperty("cse.governance.Consumer.carts.schemas.testSchema.policy.fault.protocols.rest.delay.fixedDelay",
+        "1");
+    System.setProperty("cse.governance.Consumer.carts.schemas.testSchema.policy.fault.protocols.rest.delay.percent",
+        "10");
+    System.setProperty("cse.governance.Consumer.carts.schemas.testSchema.policy.fault.protocols.rest.abort.percent",
+        "10");
+    System.setProperty("cse.governance.Consumer.carts.schemas.testSchema.policy.fault.protocols.rest.abort.httpStatus",
+        "421");
+
+    Mockito.when(invocation.getMicroserviceQualifiedName()).thenReturn("MicroserviceQualifiedName5");
+    Mockito.when(invocation.getTransport()).thenReturn(transport);
+    Mockito.when(transport.getName()).thenReturn("rest");
+    Mockito.when(invocation.getOperationName()).thenReturn("sayHello");
+    Mockito.when(invocation.getSchemaId()).thenReturn("testSchema");
+    Mockito.when(invocation.getMicroserviceName()).thenReturn("carts");
+
+    List<Fault> faultInjectionFeatureList = Arrays.asList(abortFault, delayFault);
+    handler.setFaultFeature(faultInjectionFeatureList);
+
+    boolean validAssert;
+    try {
+      validAssert = true;
+      handler.handle(invocation, asyncResp);
+    } catch (Exception e) {
+      validAssert = false;
+    }
+
+    System.getProperties()
+        .remove("cse.governance.Consumer.carts.schemas.testSchema.policy.fault.protocols.rest.delay.fixedDelay");
+    System.getProperties()
+        .remove("cse.governance.Consumer.carts.schemas.testSchema.policy.fault.protocols.rest.delay.percent");
+    System.getProperties()
+        .remove("cse.governance.Consumer.carts.schemas.testSchema.policy.fault.protocols.rest.abort.percent");
+    System.getProperties()
+        .remove("cse.governance.Consumer.carts.schemas.testSchema.policy.fault.protocols.rest.abort.httpStatus");
+
+    Assert.assertTrue(validAssert);
+    AtomicLong count = FaultInjectionUtil.getOperMetTotalReq("restMicroserviceQualifiedName5");
+    assertEquals(2, count.get());
+  }
+
+  /**
+   * Tests the fault injection handler functionality with operation level configuration
+   * with delay/abort condition.
+   * 
+   * @throws Exception
+   */
+  @Test
+  public void testFaultInjectHandlerOperationCfgSuccess() throws Exception {
+
+    System.setProperty(
+        "cse.governance.Consumer.carts.schemas.testSchema.operations.sayHi.policy.fault.protocols.rest.delay.fixedDelay",
+        "1");
+    System.setProperty(
+        "cse.governance.Consumer.carts.schemas.testSchema.operations.sayHi.policy.fault.protocols.rest.delay.percent",
+        "10");
+    System.setProperty(
+        "cse.governance.Consumer.carts.schemas.testSchema.operations.sayHi.policy.fault.protocols.rest.abort.percent",
+        "10");
+    System.setProperty(
+        "cse.governance.Consumer.carts.schemas.testSchema.operations.sayHi.policy.fault.protocols.rest.abort.httpStatus",
+        "421");
+
+    Mockito.when(invocation.getMicroserviceQualifiedName()).thenReturn("MicroserviceQualifiedName6");
+    Mockito.when(invocation.getTransport()).thenReturn(transport);
+    Mockito.when(transport.getName()).thenReturn("rest");
+    Mockito.when(invocation.getOperationName()).thenReturn("sayHi");
+    Mockito.when(invocation.getSchemaId()).thenReturn("testSchema");
+    Mockito.when(invocation.getMicroserviceName()).thenReturn("carts");
+
+    List<Fault> faultInjectionFeatureList = Arrays.asList(abortFault, delayFault);
+    handler.setFaultFeature(faultInjectionFeatureList);
+
+    boolean validAssert;
+    try {
+      validAssert = true;
+      handler.handle(invocation, asyncResp);
+    } catch (Exception e) {
+      validAssert = false;
+    }
+
+    System.getProperties()
+        .remove(
+            "cse.governance.Consumer.carts.schemas.testSchema.operations.sayHi.policy.fault.protocols.rest.delay.fixedDelay");
+    System.getProperties()
+        .remove(
+            "cse.governance.Consumer.carts.schemas.testSchema.operations.sayHi.policy.fault.protocols.rest.delay.percent");
+    System.getProperties()
+        .remove(
+            "cse.governance.Consumer.carts.schemas.testSchema.operations.sayHi.policy.fault.protocols.rest.abort.percent");
+    System.getProperties()
+        .remove(
+            "cse.governance.Consumer.carts.schemas.testSchema.operations.sayHi.policy.fault.protocols.rest.abort.httpStatus");
+    Assert.assertTrue(validAssert);
+    AtomicLong count = FaultInjectionUtil.getOperMetTotalReq("restMicroserviceQualifiedName6");
+    assertEquals(2, count.get());
+  }
+
+  /**
+   * Tests the fault injection handler functionality with configuration change event for global level config.
+   * 
+   * @throws Exception
+   */
+  @Test
+  public void testFaultInjectHandlerConfigChangeEvent1() throws Exception {
+
+    System.setProperty(
+        "cse.governance.Consumer._global.policy.fault.protocols.rest.delay.fixedDelay",
+        "1");
+    System.setProperty(
+        "cse.governance.Consumer._global.policy.fault.protocols.rest.delay.percent",
+        "100");
+    System.setProperty(
+        "cse.governance.Consumer._global.policy.fault.protocols.rest.abort.percent",
+        "100");
+    System.setProperty(
+        "cse.governance.Consumer._global.policy.fault.protocols.rest.abort.httpStatus",
+        "420");
+
+    Mockito.when(invocation.getMicroserviceQualifiedName()).thenReturn("MicroserviceQualifiedName7");
+    Mockito.when(invocation.getTransport()).thenReturn(transport);
+    Mockito.when(transport.getName()).thenReturn("rest");
+    Mockito.when(invocation.getOperationName()).thenReturn("sayBye1");
+    Mockito.when(invocation.getSchemaId()).thenReturn("testSchema1");
+    Mockito.when(invocation.getMicroserviceName()).thenReturn("carts1");
+    boolean validAssert;
+    long timeOld = System.currentTimeMillis();
+
+    List<Fault> faultInjectionFeatureList = Arrays.asList(delayFault, abortFault);
+    handler.setFaultFeature(faultInjectionFeatureList);
+
+    try {
+      validAssert = true;
+      handler.handle(invocation, ar);
+    } catch (Exception e) {
+      validAssert = false;
+    }
+    Assert.assertTrue(validAssert);
+    TestFaultInjectUtil
+        .updateProperty("cse.governance.Consumer._global.policy.fault.protocols.rest.delay.fixedDelay", 500);
+    TestFaultInjectUtil
+        .updateProperty("cse.governance.Consumer._global.policy.fault.protocols.rest.abort.httpStatus", 421);
+
+    handler.handle(invocation, ar -> {
+      //check whether error code return, defaut is 421.
+      assertEquals(421, response.getStatusCode());
+      assertEquals(true, response.isFailed());
+      long timeNow = System.currentTimeMillis();
+      //if really time delay is added it should be greater than 5s.
+      Assert.assertTrue((timeNow - timeOld) >= 500);
+    });
+
+
+    System.getProperties()
+        .remove(
+            "cse.governance.Consumer._global.policy.fault.protocols.rest.delay.fixedDelay");
+    System.getProperties()
+        .remove(
+            "cse.governance.Consumer._global.policy.fault.protocols.rest.delay.percent");
+    System.getProperties()
+        .remove(
+            "cse.governance.Consumer._global.policy.fault.protocols.rest.abort.percent");
+    System.getProperties()
+        .remove(
+            "cse.governance.Consumer._global.policy.fault.protocols.rest.abort.httpStatus");
+
+    AtomicLong count = FaultInjectionUtil.getOperMetTotalReq("restMicroserviceQualifiedName7");
+    assertEquals(3, count.get());
+
+  }
+
+  /**
+   * Tests the fault injection handler functionality with configuration change event for operation level config.
+   * 
+   * @throws Exception
+   */
+  @Test
+  public void testFaultInjectHandlerConfigChangeEvent2() throws Exception {
+
+    System.setProperty(
+        "cse.governance.Consumer.carts2.schemas.testSchema2.operations.sayBye2.policy.fault.protocols.rest.delay.fixedDelay",
+        "1");
+    System.setProperty(
+        "cse.governance.Consumer.carts2.schemas.testSchema2.operations.sayBye2.policy.fault.protocols.rest.delay.percent",
+        "100");
+    System.setProperty(
+        "cse.governance.Consumer.carts2.schemas.testSchema2.operations.sayBye2.policy.fault.protocols.rest.abort.percent",
+        "100");
+    System.setProperty(
+        "cse.governance.Consumer.carts2.schemas.testSchema2.operations.sayBye2.policy.fault.protocols.rest.abort.httpStatus",
+        "420");
+
+
+    Mockito.when(invocation.getMicroserviceQualifiedName()).thenReturn("MicroserviceQualifiedName8");
+    Mockito.when(invocation.getTransport()).thenReturn(transport);
+    Mockito.when(transport.getName()).thenReturn("rest");
+    Mockito.when(invocation.getOperationName()).thenReturn("sayBye2");
+    Mockito.when(invocation.getSchemaId()).thenReturn("testSchema2");
+    Mockito.when(invocation.getMicroserviceName()).thenReturn("carts2");
+    boolean validAssert;
+    long timeOld = System.currentTimeMillis();
+
+    List<Fault> faultInjectionFeatureList = Arrays.asList(delayFault, abortFault);
+    handler.setFaultFeature(faultInjectionFeatureList);
+
+    try {
+      validAssert = true;
+      handler.handle(invocation, ar);
+    } catch (Exception e) {
+      validAssert = false;
+    }
+    Assert.assertTrue(validAssert);
+    TestFaultInjectUtil
+        .updateProperty(
+            "cse.governance.Consumer.carts2.schemas.testSchema2.operations.sayBye2.policy.fault.protocols.rest.delay.fixedDelay",
+            500);
+
+    handler.handle(invocation, ar -> {
+      //check whether error code return
+      assertEquals(420, response.getStatusCode());
+      assertEquals(true, response.isFailed());
+      long timeNow = System.currentTimeMillis();
+      //if really time delay is added it should be greater than 5s.
+      Assert.assertTrue((timeNow - timeOld) >= 500);
+    });
+
+    System.getProperties()
+        .remove(
+            "cse.governance.Consumer.carts2.schemas.testSchema2.operations.sayBye2.policy.fault.protocols.rest.delay.fixedDelay");
+    System.getProperties()
+        .remove(
+            "cse.governance.Consumer.carts2.schemas.testSchema2.operations.sayBye2.policy.fault.protocols.rest.delay.percent");
+    System.getProperties()
+        .remove(
+            "cse.governance.Consumer.carts2.schemas.testSchema2.operations.sayBye2.policy.fault.protocols.rest.abort.percent");
+    System.getProperties()
+        .remove(
+            "cse.governance.Consumer.carts2.schemas.testSchema2.operations.sayBye2.policy.fault.protocols.rest.abort.httpStatus");
+
+
+    AtomicLong count = FaultInjectionUtil.getOperMetTotalReq("restMicroserviceQualifiedName8");
+    assertEquals(3, count.get());
+
+  }
+
+  /**
+   * Tests the fault injection handler functionality with configuration change event for schema level config.
+   * 
+   * @throws Exception
+   */
+  @Test
+  public void testFaultInjectHandlerConfigChangeEvent3() throws Exception {
+
+    System.setProperty(
+        "cse.governance.Consumer.carts3.schemas.testSchema3.policy.fault.protocols.rest.delay.fixedDelay",
+        "1");
+    System.setProperty(
+        "cse.governance.Consumer.carts3.schemas.testSchema3.policy.fault.protocols.rest.delay.percent",
+        "100");
+    System.setProperty(
+        "cse.governance.Consumer.carts3.schemas.testSchema3.policy.fault.protocols.rest.abort.percent",
+        "100");
+    System.setProperty(
+        "cse.governance.Consumer.carts3.schemas.testSchema3.policy.fault.protocols.rest.abort.httpStatus",
+        "421");
+
+    Mockito.when(invocation.getMicroserviceQualifiedName()).thenReturn("MicroserviceQualifiedName9");
+    Mockito.when(invocation.getTransport()).thenReturn(transport);
+    Mockito.when(transport.getName()).thenReturn("rest");
+    Mockito.when(invocation.getOperationName()).thenReturn("sayBye3");
+    Mockito.when(invocation.getSchemaId()).thenReturn("testSchema3");
+    Mockito.when(invocation.getMicroserviceName()).thenReturn("carts3");
+    boolean validAssert;
+    long timeOld = System.currentTimeMillis();
+
+    List<Fault> faultInjectionFeatureList = Arrays.asList(delayFault, abortFault);
+    handler.setFaultFeature(faultInjectionFeatureList);
+
+    try {
+      validAssert = true;
+      handler.handle(invocation, ar);
+    } catch (Exception e) {
+      validAssert = false;
+    }
+    Assert.assertTrue(validAssert);
+    TestFaultInjectUtil
+        .updateProperty(
+            "cse.governance.Consumer.carts3.schemas.testSchema3.policy.fault.protocols.rest.delay.fixedDelay",
+            500);
+
+    handler.handle(invocation, ar -> {
+      //check whether error code return, defaut is 421.
+      assertEquals(421, response.getStatusCode());
+      assertEquals(true, response.isFailed());
+      long timeNow = System.currentTimeMillis();
+      //if really time delay is added it should be greater than 5s.
+      Assert.assertTrue((timeNow - timeOld) >= 500);
+    });
+
+    System.getProperties()
+        .remove("cse.governance.Consumer.carts3.schemas.testSchema3.policy.fault.protocols.rest.delay.fixedDelay");
+    System.getProperties()
+        .remove("cse.governance.Consumer.carts3.schemas.testSchema3.policy.fault.protocols.rest.delay.percent");
+    System.getProperties()
+        .remove("cse.governance.Consumer.carts3.schemas.testSchema3.policy.fault.protocols.rest.abort.percent");
+    System.getProperties()
+        .remove("cse.governance.Consumer.carts3.schemas.testSchema3.policy.fault.protocols.rest.abort.httpStatus");
+
+
+    AtomicLong count = FaultInjectionUtil.getOperMetTotalReq("restMicroserviceQualifiedName9");
+    assertEquals(3, count.get());
+  }
+
+  /**
+   * Tests the fault injection handler functionality with configuration change event for service level config.
+   * 
+   * @throws Exception
+   */
+  @Test
+  public void testFaultInjectHandlerConfigChangeEvent4() throws Exception {
+    System.setProperty("cse.governance.Consumer.carts4.policy.fault.protocols.rest.delay.fixedDelay", "1");
+
+    System.setProperty(
+        "cse.governance.Consumer.carts4.policy.fault.protocols.rest.delay.percent",
+        "100");
+    System.setProperty(
+        "cse.governance.Consumer.carts4.policy.fault.protocols.rest.abort.percent",
+        "100");
+    System.setProperty(
+        "cse.governance.Consumer.carts4.policy.fault.protocols.rest.abort.httpStatus",
+        "421");
+
+    Mockito.when(invocation.getMicroserviceQualifiedName()).thenReturn("MicroserviceQualifiedName10");
+    Mockito.when(invocation.getTransport()).thenReturn(transport);
+    Mockito.when(transport.getName()).thenReturn("rest");
+    Mockito.when(invocation.getOperationName()).thenReturn("sayBye4");
+    Mockito.when(invocation.getSchemaId()).thenReturn("testSchema4");
+    Mockito.when(invocation.getMicroserviceName()).thenReturn("carts4");
+    boolean validAssert;
+    long timeOld = System.currentTimeMillis();
+
+    List<Fault> faultInjectionFeatureList = Arrays.asList(delayFault, abortFault);
+    handler.setFaultFeature(faultInjectionFeatureList);
+
+    try {
+      validAssert = true;
+      handler.handle(invocation, ar);
+    } catch (Exception e) {
+      validAssert = false;
+    }
+    Assert.assertTrue(validAssert);
+    TestFaultInjectUtil
+        .updateProperty("cse.governance.Consumer.carts4.policy.fault.protocols.rest.delay.fixedDelay", 500);
+
+    handler.handle(invocation, ar -> {
+      //check whether error code return,
+      assertEquals(421, response.getStatusCode());
+      assertEquals(true, response.isFailed());
+      long timeNow = System.currentTimeMillis();
+      //if really time delay is added it should be greater than 5s.
+      Assert.assertTrue((timeNow - timeOld) >= 500);
+    });
+
+
+    System.getProperties()
+        .remove("cse.governance.Consumer.carts4.policy.fault.protocols.rest.delay.fixedDelay");
+    System.getProperties()
+        .remove("cse.governance.Consumer.carts4.policy.fault.protocols.rest.delay.percent");
+    System.getProperties()
+        .remove("cse.governance.Consumer.carts4.policy.fault.protocols.rest.abort.percent");
+    System.getProperties()
+        .remove("cse.governance.Consumer.carts4.policy.fault.protocols.rest.abort.httpStatus");
+
+
+    AtomicLong count = FaultInjectionUtil.getOperMetTotalReq("restMicroserviceQualifiedName10");
+    assertEquals(3, count.get());
+
+  }
+
+  /**
+   * Tests the fault injection handler functionality with configuration change event for service level config.
+   * 
+   * @throws Exception
+   */
+  @Test
+  public void testFaultInjectHandlerConfigChangeEvent5() throws Exception {
+    System.setProperty(
+        "cse.governance.Consumer.carts5.policy.fault.protocols.rest.delay.percent",
+        "100");
+    System.setProperty(
+        "cse.governance.Consumer.carts5.policy.fault.protocols.rest.abort.percent",
+        "100");
+
+    Mockito.when(invocation.getMicroserviceQualifiedName()).thenReturn("MicroserviceQualifiedName11");
+    Mockito.when(invocation.getTransport()).thenReturn(transport);
+    Mockito.when(transport.getName()).thenReturn("rest");
+    Mockito.when(invocation.getOperationName()).thenReturn("sayBye4");
+    Mockito.when(invocation.getSchemaId()).thenReturn("testSchema4");
+    Mockito.when(invocation.getMicroserviceName()).thenReturn("carts5");
+    boolean validAssert;
+    long timeOld = System.currentTimeMillis();
+
+    List<Fault> faultInjectionFeatureList = Arrays.asList(delayFault, abortFault);
+    handler.setFaultFeature(faultInjectionFeatureList);
+
+    try {
+      validAssert = true;
+      handler.handle(invocation, ar);
+    } catch (Exception e) {
+      validAssert = false;
+    }
+    Assert.assertTrue(validAssert);
+    TestFaultInjectUtil
+        .updateProperty("cse.governance.Consumer.carts5.policy.fault.protocols.rest.abort.percent", 500);
+
+    handler.handle(invocation, ar -> {
+      //check whether error code return,
+      assertEquals(421, response.getStatusCode());
+      assertEquals(true, response.isFailed());
+      long timeNow = System.currentTimeMillis();
+      //if really time delay is added it should be greater than 5s.
+      Assert.assertTrue((timeNow - timeOld) >= 500);
+    });
+
+
+    System.getProperties()
+        .remove("cse.governance.Consumer.carts5.policy.fault.protocols.rest.delay.fixedDelay");
+    System.getProperties()
+        .remove("cse.governance.Consumer.carts5.policy.fault.protocols.rest.delay.percent");
+    System.getProperties()
+        .remove("cse.governance.Consumer.carts5.policy.fault.protocols.rest.abort.percent");
+    System.getProperties()
+        .remove("cse.governance.Consumer.carts5.policy.fault.protocols.rest.abort.httpStatus");
+
+
+    AtomicLong count = FaultInjectionUtil.getOperMetTotalReq("restMicroserviceQualifiedName11");
+    assertEquals(3, count.get());
+
+  }
+}
diff --git a/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectUtil.java b/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectUtil.java
new file mode 100644
index 0000000..46b428e
--- /dev/null
+++ b/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectUtil.java
@@ -0,0 +1,73 @@
+/*
+ * 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.faultinjection;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.springframework.util.ReflectionUtils;
+
+import com.netflix.config.DynamicProperty;
+
+/**
+ * Tests the fault inject util functionality.
+ */
+public class TestFaultInjectUtil {
+  private static Method updatePropertyMethod =
+      ReflectionUtils.findMethod(DynamicProperty.class, "updateProperty", String.class, Object.class);
+
+  static {
+    updatePropertyMethod.setAccessible(true);
+  }
+
+  DelayFault delayFault = Mockito.mock(DelayFault.class);
+
+  AbortFault abortFault = Mockito.mock(AbortFault.class);
+
+  public static void updateProperty(String key, Object value) {
+    ReflectionUtils.invokeMethod(updatePropertyMethod, null, key, value);
+  }
+
+  @Test
+  public void testFaultInjectUtil() throws Exception {
+    BeanHolder beanHolder = new BeanHolder();
+    List<Fault> faultInjectionFeatureList = Arrays.asList(delayFault, abortFault);
+    Field field = beanHolder.getClass().getDeclaredField("faultInjectionFeatureList");
+    field.setAccessible(true);
+    field.set(beanHolder, faultInjectionFeatureList);
+    Mockito.when(delayFault.getPriority()).thenReturn(1);
+    Mockito.when(abortFault.getPriority()).thenReturn(10);
+
+    beanHolder.init();
+    AtomicLong count1 = FaultInjectionUtil.getOperMetTotalReq("test");
+    Assert.assertEquals(1, count1.get());
+    count1.incrementAndGet();
+    AtomicLong count2 = FaultInjectionUtil.getOperMetTotalReq("test");
+    Assert.assertEquals(2, count2.get());
+    FaultInjectionUtil.setConfigCenterValue("sayHi", new AtomicInteger(123));
+    int value = FaultInjectionUtil.getConfigCenterMap().get("sayHi").get();
+    Assert.assertEquals(123, value);
+  }
+}
diff --git a/handlers/pom.xml b/handlers/pom.xml
index 2afaa77..a16e93e 100644
--- a/handlers/pom.xml
+++ b/handlers/pom.xml
@@ -36,6 +36,7 @@
     <module>handler-bizkeeper</module>
     <module>handler-flowcontrol-qps</module>
     <module>handler-loadbalance</module>
+    <module>handler-fault-injection</module>
     <module>handler-publickey-auth</module>
   </modules>
 
diff --git a/java-chassis-dependencies/pom.xml b/java-chassis-dependencies/pom.xml
index 5793296..e9ae9ec 100644
--- a/java-chassis-dependencies/pom.xml
+++ b/java-chassis-dependencies/pom.xml
@@ -836,6 +836,11 @@
       </dependency>
       <dependency>
         <groupId>org.apache.servicecomb</groupId>
+        <artifactId>handler-fault-injection</artifactId>
+        <version>1.0.0-m2-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.servicecomb</groupId>
         <artifactId>common-rest</artifactId>
         <version>1.0.0-m2-SNAPSHOT</version>
       </dependency>
diff --git a/java-chassis-distribution/pom.xml b/java-chassis-distribution/pom.xml
index 1b7f364..95b30e1 100644
--- a/java-chassis-distribution/pom.xml
+++ b/java-chassis-distribution/pom.xml
@@ -129,6 +129,10 @@
             <artifactId>handler-tracing-zipkin</artifactId>
         </dependency>
         <dependency>
+          <groupId>org.apache.servicecomb</groupId>
+          <artifactId>handler-fault-injection</artifactId>
+        </dependency>
+        <dependency>
             <groupId>org.apache.servicecomb</groupId>
             <artifactId>provider-jaxrs</artifactId>
         </dependency>

-- 
To stop receiving notification emails like this one, please contact
liubao@apache.org.

[incubator-servicecomb-java-chassis] 04/05: Review comments fix:Fault-Injection handler

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git

commit d382693b6e4edc188ba37669a41b84640a460197
Author: maheshrajus <ma...@huawei.com>
AuthorDate: Wed Mar 21 20:19:55 2018 +0530

    Review comments fix:Fault-Injection handler
---
 .../src/main/java/org/apache/servicecomb/faultinjection/DelayFault.java | 2 --
 1 file changed, 2 deletions(-)

diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/DelayFault.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/DelayFault.java
index e486ae3..3f5edb9 100644
--- a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/DelayFault.java
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/DelayFault.java
@@ -76,7 +76,5 @@ public class DelayFault extends AbstractFault {
         asynResponse.success(new FaultResponse());
       }
     }
-    asynResponse.success(new FaultResponse());
   }
-
 }

-- 
To stop receiving notification emails like this one, please contact
liubao@apache.org.

[incubator-servicecomb-java-chassis] 05/05: Review comments fix:Fault-Injection handler

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git

commit a7ea310ad268e07f504bd31ab2fb44f1b7f361fc
Author: maheshrajus <ma...@huawei.com>
AuthorDate: Thu Mar 22 13:14:58 2018 +0530

    Review comments fix:Fault-Injection handler
---
 handlers/handler-fault-injection/pom.xml           | 55 ++++++++++---------
 .../servicecomb/faultinjection/AbortFault.java     | 17 +++---
 .../servicecomb/faultinjection/BeanHolder.java     | 47 ----------------
 .../servicecomb/faultinjection/DelayFault.java     | 14 +++--
 .../apache/servicecomb/faultinjection/Fault.java   |  2 +-
 .../servicecomb/faultinjection/FaultExecutor.java  |  9 +---
 .../faultinjection/FaultInjectionHandler.java      | 18 ++-----
 .../faultinjection/FaultInjectionUtil.java         |  9 ++--
 .../servicecomb/faultinjection/FaultResponse.java  | 63 ----------------------
 .../org.apache.servicecomb.faultinjection.Fault    | 19 +++++++
 .../main/resources/META-INF/spring/cse.bean.xml    | 31 -----------
 .../faultinjection/TestFaultInjectConfig.java      | 18 +------
 .../faultinjection/TestFaultInjectUtil.java        | 12 -----
 13 files changed, 73 insertions(+), 241 deletions(-)

diff --git a/handlers/handler-fault-injection/pom.xml b/handlers/handler-fault-injection/pom.xml
index 3fda7b4..de176d4 100755
--- a/handlers/handler-fault-injection/pom.xml
+++ b/handlers/handler-fault-injection/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-m2-SNAPSHOT</version>
-	</parent>
-	<artifactId>handler-fault-injection</artifactId>
-	<name>Java Chassis::Handlers::Fault Injection</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-m2-SNAPSHOT</version>
+  </parent>
+  <artifactId>handler-fault-injection</artifactId>
+  <name>Java Chassis::Handlers::Fault Injection</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-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/AbortFault.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/AbortFault.java
index f53eef3..1135aa6 100644
--- a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/AbortFault.java
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/AbortFault.java
@@ -20,11 +20,10 @@ package org.apache.servicecomb.faultinjection;
 import org.apache.servicecomb.core.Invocation;
 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.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Component;
 
-@Component
 public class AbortFault extends AbstractFault {
   private static final Logger LOGGER = LoggerFactory.getLogger(AbortFault.class);
 
@@ -36,12 +35,12 @@ public class AbortFault extends AbstractFault {
 
     if (abortPercent == FaultInjectionConst.FAULT_INJECTION_DEFAULT_VALUE) {
       LOGGER.debug("Fault injection: Abort percentage is not configured");
-      asynResponse.success(new FaultResponse());
+      asynResponse.success("success");
       return;
     }
 
     // check fault abort condition.
-    boolean isAbort = FaultInjectionUtil.checkFaultInjectionDelayAndAbort(faultParam.getReqCount(), abortPercent);
+    boolean isAbort = FaultInjectionUtil.isFaultNeedToInject(faultParam.getReqCount(), abortPercent);
     if (isAbort) {
       // get the config values related to abort percentage.
       int errorCode = FaultInjectionUtil.getFaultInjectionConfig(invocation,
@@ -49,22 +48,20 @@ public class AbortFault extends AbstractFault {
 
       if (errorCode == FaultInjectionConst.FAULT_INJECTION_DEFAULT_VALUE) {
         LOGGER.debug("Fault injection: Abort error code is not configured");
-        asynResponse.success(new FaultResponse());
+        asynResponse.success("success");
         return;
       }
       // if request need to be abort then return failure with given error code
       CommonExceptionData errorData = new CommonExceptionData("aborted by fault inject");
-
-      FaultResponse response = new FaultResponse(FaultInjectionConst.FAULT_INJECTION_ERROR, errorCode, errorData);
-      asynResponse.success(response);
+      asynResponse.consumerFail(new InvocationException(errorCode, "aborted by fault inject", errorData));
       return;
     }
 
-    asynResponse.success(new FaultResponse());
+    asynResponse.success("success");
   }
 
   @Override
-  public int getPriority() {
+  public int getOrder() {
     return 200;
   }
 }
diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/BeanHolder.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/BeanHolder.java
deleted file mode 100644
index 756ad4b..0000000
--- a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/BeanHolder.java
+++ /dev/null
@@ -1,47 +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.faultinjection;
-
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-import javax.inject.Inject;
-
-import org.springframework.stereotype.Component;
-
-@Component
-public class BeanHolder {
-
-  @Inject
-  private List<Fault> faultInjectionFeatureList = Collections.emptyList();
-
-  public void init() {
-    //sort the fault injection feature list based on priority.
-    Collections.sort(faultInjectionFeatureList, new Comparator<Fault>() {
-
-      @Override
-      public int compare(Fault o1, Fault o2) {
-        return Integer.compare(o1.getPriority(), o2.getPriority());
-      }
-    });
-
-    FaultInjectionHandler.getFaultFeature().addAll(faultInjectionFeatureList);
-
-  }
-}
diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/DelayFault.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/DelayFault.java
index 3f5edb9..ecbb2e1 100644
--- a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/DelayFault.java
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/DelayFault.java
@@ -21,17 +21,15 @@ import org.apache.servicecomb.core.Invocation;
 import org.apache.servicecomb.swagger.invocation.AsyncResponse;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Component;
 
 import io.vertx.core.Handler;
 import io.vertx.core.Vertx;
 
-@Component
 public class DelayFault extends AbstractFault {
   private static final Logger LOGGER = LoggerFactory.getLogger(DelayFault.class);
 
   @Override
-  public int getPriority() {
+  public int getOrder() {
     return 100;
   }
 
@@ -42,12 +40,12 @@ public class DelayFault extends AbstractFault {
 
     if (delayPercent == FaultInjectionConst.FAULT_INJECTION_DEFAULT_VALUE) {
       LOGGER.debug("Fault injection: delay percentage is not configured");
-      asynResponse.success(new FaultResponse());
+      asynResponse.success("success");
       return;
     }
 
     // check fault delay condition.
-    boolean isDelay = FaultInjectionUtil.checkFaultInjectionDelayAndAbort(faultParam.getReqCount(), delayPercent);
+    boolean isDelay = FaultInjectionUtil.isFaultNeedToInject(faultParam.getReqCount(), delayPercent);
     if (isDelay) {
       LOGGER.debug("Fault injection: delay is added for the request by fault inject handler");
       long delay = FaultInjectionUtil.getFaultInjectionConfig(invocation,
@@ -55,7 +53,7 @@ public class DelayFault extends AbstractFault {
 
       if (delay == FaultInjectionConst.FAULT_INJECTION_DEFAULT_VALUE) {
         LOGGER.debug("Fault injection: delay is not configured");
-        asynResponse.success(new FaultResponse());
+        asynResponse.success("success");
         return;
       }
 
@@ -64,7 +62,7 @@ public class DelayFault extends AbstractFault {
         vertx.setTimer(delay, new Handler<Long>() {
           @Override
           public void handle(Long timeID) {
-            asynResponse.success(new FaultResponse());
+            asynResponse.success("success");
           }
         });
       } else {
@@ -73,7 +71,7 @@ public class DelayFault extends AbstractFault {
         } catch (InterruptedException e) {
           LOGGER.info("Interrupted exception is received");
         }
-        asynResponse.success(new FaultResponse());
+        asynResponse.success("success");
       }
     }
   }
diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/Fault.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/Fault.java
index 6f50c62..ddc4229 100644
--- a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/Fault.java
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/Fault.java
@@ -22,7 +22,7 @@ import org.apache.servicecomb.swagger.invocation.AsyncResponse;
 
 public interface Fault {
 
-  int getPriority();
+  int getOrder();
 
   void injectFault(Invocation invocation, FaultParam faultAttributes, AsyncResponse asynResponse);
 }
diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultExecutor.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultExecutor.java
index c5a0e9b..9a20f64 100644
--- a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultExecutor.java
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultExecutor.java
@@ -48,7 +48,7 @@ public class FaultExecutor {
 
   private void next(AsyncResponse asyncResponse) {
     if (handlerIndex >= faultInjectList.size()) {
-      asyncResponse.complete(Response.succResp(new FaultResponse()));
+      asyncResponse.complete(Response.succResp("success"));
       return;
     }
 
@@ -58,12 +58,7 @@ public class FaultExecutor {
       if (response.isFailed()) {
         asyncResponse.complete(response);
       } else {
-        FaultResponse r = response.getResult();
-        if (r.getStatusCode() == FaultInjectionConst.FAULT_INJECTION_ERROR) {
-          asyncResponse.complete(response);
-        } else {
-          FaultExecutor.this.next(asyncResponse);
-        }
+        FaultExecutor.this.next(asyncResponse);
       }
     });
   }
diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionHandler.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionHandler.java
index 204049c..8c29246 100755
--- a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionHandler.java
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionHandler.java
@@ -17,14 +17,13 @@
 
 package org.apache.servicecomb.faultinjection;
 
-import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.servicecomb.core.Handler;
 import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
 import org.apache.servicecomb.swagger.invocation.AsyncResponse;
-import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
 
 import io.vertx.core.Context;
 import io.vertx.core.Vertx;
@@ -37,27 +36,21 @@ import io.vertx.core.Vertx;
 
 public class FaultInjectionHandler implements Handler {
 
-  private static List<Fault> faultInjectionFeatureList = new ArrayList<>();
+  private List<Fault> faultInjectionFeatureList = SPIServiceUtils.getSortedService(Fault.class);
 
   //added only for unit testing
   public void setFaultFeature(List<Fault> faultFeature) {
     faultInjectionFeatureList = faultFeature;
   }
 
-  public static List<Fault> getFaultFeature() {
-    return faultInjectionFeatureList;
-  }
-
   @Override
   public void handle(Invocation invocation, AsyncResponse asyncResp) throws Exception {
 
     // prepare the key and lookup for request count.
     String key = invocation.getTransport().getName() + invocation.getMicroserviceQualifiedName();
     AtomicLong reqCount = FaultInjectionUtil.getOperMetTotalReq(key);
-    long reqCountCurrent = reqCount.get();
-
     // increment the request count here after checking the delay/abort condition.
-    reqCount.incrementAndGet();
+    long reqCountCurrent = reqCount.getAndIncrement();
 
     FaultParam param = new FaultParam(reqCountCurrent);
     Context currentContext = Vertx.currentContext();
@@ -71,11 +64,6 @@ public class FaultInjectionHandler implements Handler {
         if (response.isFailed()) {
           asyncResp.complete(response);
         } else {
-          FaultResponse r = response.getResult();
-          if (r.getStatusCode() == FaultInjectionConst.FAULT_INJECTION_ERROR) {
-            asyncResp.consumerFail(new InvocationException(r.getErrorCode(), "", r.getErrorData()));
-            return;
-          }
           invocation.next(asyncResp);
         }
       } catch (Exception e) {
diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionUtil.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionUtil.java
index 18dba50..05e85ae 100755
--- a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionUtil.java
+++ b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionUtil.java
@@ -142,9 +142,9 @@ public class FaultInjectionUtil {
    * @param reqCount
    * @param percentage
    * @param key
-   * @return true/false
+   * @return true: delay/abort is needed. false: delay/abort is not needed.
    */
-  public static boolean checkFaultInjectionDelayAndAbort(long reqCount, int percentage) {
+  public static boolean isFaultNeedToInject(long reqCount, int percentage) {
     /*
      * Example: delay/abort percentage configured is 10% and Get the count(suppose
      * if it is 10th request) from map and calculate resultNew(10th request) and
@@ -160,9 +160,6 @@ public class FaultInjectionUtil {
     long resultOld = ((reqCount - 1) * percentage) / 100;
 
     // if both are not matching then delay/abort should be added.
-    if (resultNew != resultOld) {
-      return true;
-    }
-    return false;
+    return (resultNew != resultOld);
   }
 }
diff --git a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultResponse.java b/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultResponse.java
deleted file mode 100644
index ee59d71..0000000
--- a/handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultResponse.java
+++ /dev/null
@@ -1,63 +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.faultinjection;
-
-/**
- * Fault response which contains status of fault injection.
- */
-public class FaultResponse {
-  private int statusCode;
-
-  private int errorCode;
-
-  private Object errorData;
-
-  FaultResponse(int statusCode, int errorCode, Object errorData) {
-    this.statusCode = statusCode;
-    this.errorCode = errorCode;
-    this.errorData = errorData;
-  }
-
-  FaultResponse() {
-  }
-
-  public int getStatusCode() {
-    return statusCode;
-  }
-
-  public void setStatusCode(int statusCode) {
-    this.statusCode = statusCode;
-  }
-
-  public int getErrorCode() {
-    return errorCode;
-  }
-
-  public void setErrorCode(int errorCode) {
-    this.errorCode = errorCode;
-  }
-
-  public Object getErrorData() {
-    return errorData;
-  }
-
-  public void setErrorData(Object errorData) {
-    this.errorData = errorData;
-  }
-
-}
diff --git a/handlers/handler-fault-injection/src/main/resources/META-INF/services/org.apache.servicecomb.faultinjection.Fault b/handlers/handler-fault-injection/src/main/resources/META-INF/services/org.apache.servicecomb.faultinjection.Fault
new file mode 100644
index 0000000..1da13d5
--- /dev/null
+++ b/handlers/handler-fault-injection/src/main/resources/META-INF/services/org.apache.servicecomb.faultinjection.Fault
@@ -0,0 +1,19 @@
+#
+# 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.
+#
+
+org.apache.servicecomb.faultinjection.DelayFault
+org.apache.servicecomb.faultinjection.AbortFault
diff --git a/handlers/handler-fault-injection/src/main/resources/META-INF/spring/cse.bean.xml b/handlers/handler-fault-injection/src/main/resources/META-INF/spring/cse.bean.xml
deleted file mode 100755
index b8f5c57..0000000
--- a/handlers/handler-fault-injection/src/main/resources/META-INF/spring/cse.bean.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  ~ 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.
-  -->
-
-  <beans xmlns = "http://www.springframework.org/schema/beans"
-   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
-   xmlns:context = "http://www.springframework.org/schema/context"
-   xsi:schemaLocation = "http://www.springframework.org/schema/beans
-   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
-   http://www.springframework.org/schema/context
-   http://www.springframework.org/schema/context/spring-context-3.0.xsd">
-  
-  <context:annotation-config />
-	<!-- <context:spring-configured /> -->
-  <context:component-scan base-package="org.apache.servicecomb.faultinjection" />
-  <bean class="org.apache.servicecomb.faultinjection.BeanHolder" init-method="init"/>
-</beans>
diff --git a/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectConfig.java b/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectConfig.java
index 4c2a08e..a9ea092 100644
--- a/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectConfig.java
+++ b/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectConfig.java
@@ -36,8 +36,6 @@ public class TestFaultInjectConfig {
 
   FaultParam faultParam;
 
-  FaultResponse faultResp;
-
   AbortFault abortFault;
 
   DelayFault delayFault;
@@ -48,7 +46,6 @@ public class TestFaultInjectConfig {
     faultConst = new FaultInjectionConst();
     faultUtil = new FaultInjectionUtil();
     faultParam = new FaultParam(10);
-    faultResp = new FaultResponse();
     abortFault = new AbortFault();
     delayFault = new DelayFault();
   }
@@ -85,19 +82,8 @@ public class TestFaultInjectConfig {
   }
 
   @Test
-  public void testFaultResponse() {
-    Object obj = new Object();
-    faultResp.setErrorCode(100);
-    faultResp.setErrorData(obj);
-    faultResp.setStatusCode(123);
-    assertEquals(123, faultResp.getStatusCode());
-    assertEquals(100, faultResp.getErrorCode());
-    assertEquals(obj, faultResp.getErrorData());
-  }
-
-  @Test
   public void testFaultPriority() {
-    assertEquals(200, abortFault.getPriority());
-    assertEquals(100, delayFault.getPriority());
+    assertEquals(200, abortFault.getOrder());
+    assertEquals(100, delayFault.getOrder());
   }
 }
diff --git a/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectUtil.java b/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectUtil.java
index 46b428e..ec619a7 100644
--- a/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectUtil.java
+++ b/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectUtil.java
@@ -17,10 +17,7 @@
 
 package org.apache.servicecomb.faultinjection;
 
-import java.lang.reflect.Field;
 import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 
@@ -52,15 +49,6 @@ public class TestFaultInjectUtil {
 
   @Test
   public void testFaultInjectUtil() throws Exception {
-    BeanHolder beanHolder = new BeanHolder();
-    List<Fault> faultInjectionFeatureList = Arrays.asList(delayFault, abortFault);
-    Field field = beanHolder.getClass().getDeclaredField("faultInjectionFeatureList");
-    field.setAccessible(true);
-    field.set(beanHolder, faultInjectionFeatureList);
-    Mockito.when(delayFault.getPriority()).thenReturn(1);
-    Mockito.when(abortFault.getPriority()).thenReturn(10);
-
-    beanHolder.init();
     AtomicLong count1 = FaultInjectionUtil.getOperMetTotalReq("test");
     Assert.assertEquals(1, count1.get());
     count1.incrementAndGet();

-- 
To stop receiving notification emails like this one, please contact
liubao@apache.org.