Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP]pre execution of fault injection #269

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 1999-2019 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.chaosblade.exec.common.model.action;

import com.alibaba.chaosblade.exec.common.aop.EnhancerModel;
import com.alibaba.chaosblade.exec.common.exception.ExperimentException;

public interface PreActionExecutor {

/**
* Pre run executor
*
* @param enhancerModel
* @throws Exception
*/
void preRun(EnhancerModel enhancerModel) throws ExperimentException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright 1999-2019 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.chaosblade.exec.common.model.action.exception;

import java.util.concurrent.ConcurrentHashMap;

public class CommThrowException {
public static final String DEFAULT_EXCEPTION_MESSAGE = "chaosblade-mock-exception";

private static final ConcurrentHashMap<String, Exception> exceptionPool = new ConcurrentHashMap<String, Exception>();

public static void putException(String message, Exception e) {
exceptionPool.put(message, e);
}

public static Exception getException(String message) {
return exceptionPool.get(message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,21 @@

package com.alibaba.chaosblade.exec.common.model.action.exception;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

import com.alibaba.chaosblade.exec.common.aop.EnhancerModel;
import com.alibaba.chaosblade.exec.common.exception.ExperimentException;
import com.alibaba.chaosblade.exec.common.exception.InterruptProcessException;
import com.alibaba.chaosblade.exec.common.model.FlagSpec;
import com.alibaba.chaosblade.exec.common.model.action.PreActionExecutor;
import com.alibaba.chaosblade.exec.common.util.StringUtil;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
* @author Changjun Xiao
*/
public class DefaultThrowExceptionExecutor implements ThrowExceptionExecutor {
private static final String DEFAULT_EXCEPTION_MESSAGE = "chaosblade-mock-exception";

public class DefaultThrowExceptionExecutor implements PreActionExecutor, ThrowExceptionExecutor {
private FlagSpec exceptionFlag;
private FlagSpec exceptionMessageFlag;

Expand All @@ -51,14 +50,17 @@ public void run(EnhancerModel enhancerModel) throws Exception {
exceptionMessage = enhancerModel.getActionFlag(exceptionMessageFlag.getName());
}
if (StringUtil.isBlank(exceptionMessage)) {
exceptionMessage = DEFAULT_EXCEPTION_MESSAGE;
exceptionMessage = CommThrowException.DEFAULT_EXCEPTION_MESSAGE;
}
if (enhancerModel.getAction().equals(THROW_CUSTOM_EXCEPTION)) {
exception = throwCustomException(enhancerModel.getClassLoader(), enhancerModel.getActionFlag(exceptionFlag
.getName()), exceptionMessage);
exception = CommThrowException.getException(exceptionMessage);
if (exception == null) {
exception = throwCustomException(enhancerModel.getClassLoader(), enhancerModel.getActionFlag(exceptionFlag
.getName()), exceptionMessage);
}
} else if (enhancerModel.getAction().equals(THROW_DECLARED_EXCEPTION)) {
exception = throwDeclaredException(enhancerModel.getClassLoader(), enhancerModel.getMethod(),
exceptionMessage);
exceptionMessage);
}
if (exception != null) {
InterruptProcessException.throwThrowsImmediately(exception);
Expand All @@ -79,7 +81,7 @@ public Exception throwCustomException(ClassLoader classLoader, String exception,
return instantiateException(clazz, exceptionMessage);
} catch (Throwable e) {
return new RuntimeException(
"mock custom exception: " + exception + " occurs error", e);
"mock custom exception: " + exception + " occurs error", e);
}
}

Expand Down Expand Up @@ -114,7 +116,7 @@ public Exception throwDeclaredException(ClassLoader classLoader, Method method,
* @throws InvocationTargetException
* @throws InstantiationException
*/
private Exception instantiateException (Class exceptionClass, String exceptionMessage) throws IllegalAccessException, InvocationTargetException, InstantiationException {
private Exception instantiateException(Class exceptionClass, String exceptionMessage) throws IllegalAccessException, InvocationTargetException, InstantiationException {
if (Exception.class.isAssignableFrom(exceptionClass)) {
Constructor<?>[] constructors = exceptionClass.getConstructors();
//cache default constructor, if any
Expand All @@ -135,4 +137,15 @@ private Exception instantiateException (Class exceptionClass, String exceptionMe
}
return new RuntimeException("the " + exceptionClass.getName() + " not assign from java.lang.Exception");
}

@Override
public void preRun(EnhancerModel enhancerModel) throws ExperimentException {
String exception = enhancerModel.getActionFlag(new ExceptionFlagSpec().getName());
String exceptionMessage = enhancerModel.getActionFlag(new ExceptionMessageFlagSpec().getName());
if (StringUtil.isBlank(exceptionMessage)) {
exceptionMessage = CommThrowException.DEFAULT_EXCEPTION_MESSAGE;
}
Exception e = throwCustomException(this.getClass().getClassLoader(), exception, exceptionMessage);
CommThrowException.putException(exceptionMessage, e);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,42 +16,60 @@

package com.alibaba.chaosblade.exec.plugin.jvm.script.model;

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.chaosblade.exec.common.aop.EnhancerModel;
import com.alibaba.chaosblade.exec.common.exception.ExperimentException;
import com.alibaba.chaosblade.exec.common.exception.InterruptProcessException;
import com.alibaba.chaosblade.exec.common.model.action.ActionExecutor;
import com.alibaba.chaosblade.exec.common.model.action.PreActionExecutor;
import com.alibaba.chaosblade.exec.common.model.matcher.MatcherModel;
import com.alibaba.chaosblade.exec.common.plugin.MethodConstant;
import com.alibaba.chaosblade.exec.common.util.StringUtil;
import com.alibaba.chaosblade.exec.common.util.StringUtils;
import com.alibaba.chaosblade.exec.plugin.jvm.Base64Util;
import com.alibaba.chaosblade.exec.plugin.jvm.JvmConstant;
import com.alibaba.chaosblade.exec.plugin.jvm.StoppableActionExecutor;
import com.alibaba.chaosblade.exec.plugin.jvm.script.base.CompiledScript;
import com.alibaba.chaosblade.exec.plugin.jvm.script.base.DefaultScriptEngineService;
import com.alibaba.chaosblade.exec.plugin.jvm.script.base.ExecutableScript;
import com.alibaba.chaosblade.exec.plugin.jvm.script.base.Script;
import com.alibaba.chaosblade.exec.plugin.jvm.script.base.ScriptException;
import com.alibaba.chaosblade.exec.plugin.jvm.script.base.*;

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* @author Changjun Xiao
*/
public class DynamicScriptExecutor implements ActionExecutor, StoppableActionExecutor {
public class DynamicScriptExecutor implements PreActionExecutor, ActionExecutor, StoppableActionExecutor {

private static DefaultScriptEngineService engineService = new DefaultScriptEngineService();

static {
engineService.initialize();
}

public void preRun(EnhancerModel enhancerModel) throws ExperimentException {
String scriptId = createScriptId(enhancerModel.getMatcherModel());
if (scriptId == null) {
throw new IllegalArgumentException("can not get script id from matcher model");
}
ScriptTypeEnum scriptType = getScriptType(enhancerModel);
String scriptContent = getScriptContent(enhancerModel);
String scriptName = getScriptName(scriptId, enhancerModel);
// create script object
Script script = new Script(scriptId, "", scriptName, scriptContent, scriptType.getName());
ClassLoader classLoader = null;
try {
classLoader = getClassLoader(scriptType, enhancerModel);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

需要获取目标类的类加载器

} catch (Exception e) {
throw new RuntimeException(e);
}
// compile script content
engineService.compile(classLoader.getParent(), script, null);
}

/**
* @param enhancerModel
* @throws Exception
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,17 @@

package com.alibaba.chaosblade.exec.service.handler;

import com.alibaba.chaosblade.exec.common.aop.PluginBean;
import com.alibaba.chaosblade.exec.common.aop.PluginBeans;
import com.alibaba.chaosblade.exec.common.aop.PluginLifecycleListener;
import com.alibaba.chaosblade.exec.common.aop.PredicateResult;
import com.alibaba.chaosblade.exec.common.aop.*;
import com.alibaba.chaosblade.exec.common.center.ManagerFactory;
import com.alibaba.chaosblade.exec.common.center.ModelSpecManager;
import com.alibaba.chaosblade.exec.common.center.RegisterResult;
import com.alibaba.chaosblade.exec.common.center.StatusManager;
import com.alibaba.chaosblade.exec.common.exception.ExperimentException;
import com.alibaba.chaosblade.exec.common.model.Model;
import com.alibaba.chaosblade.exec.common.model.ModelSpec;
import com.alibaba.chaosblade.exec.common.model.action.ActionExecutor;
import com.alibaba.chaosblade.exec.common.model.action.ActionSpec;
import com.alibaba.chaosblade.exec.common.model.action.PreActionExecutor;
import com.alibaba.chaosblade.exec.common.model.handler.PreCreateInjectionModelHandler;
import com.alibaba.chaosblade.exec.common.transport.Request;
import com.alibaba.chaosblade.exec.common.transport.Response;
Expand Down Expand Up @@ -145,6 +144,7 @@ private Response handleInjection(String suid, Model model, ModelSpec modelSpec)
if (result.isSuccess()) {
// handle injection
try {
applyPreActionExecutorHandler(modelSpec, model);
applyPreInjectionModelHandler(suid, modelSpec, model);
} catch (ExperimentException ex) {
this.statusManager.removeExp(suid);
Expand Down Expand Up @@ -172,6 +172,23 @@ private void applyPreInjectionModelHandler(String suid, ModelSpec modelSpec, Mod
}
}

/**
* Pre-handle for injection
*
* @param modelSpec
* @param model
* @throws ExperimentException
*/
private void applyPreActionExecutorHandler(ModelSpec modelSpec, Model model)
throws ExperimentException {
ActionExecutor actionExecutor = modelSpec.getActionSpec(model.getActionName()).getActionExecutor();
if (actionExecutor instanceof PreActionExecutor) {
EnhancerModel enhancerModel = new EnhancerModel(EnhancerModel.class.getClassLoader(), model.getMatcher());
enhancerModel.merge(model);
((PreActionExecutor) actionExecutor).preRun(enhancerModel);
}
}

private void lazyLoadPlugin(ModelSpec modelSpec) throws ExperimentException {
PluginLifecycleListener listener = ManagerFactory.getListenerManager().getPluginLifecycleListener();
if (listener == null) {
Expand Down