提交 cd358e57 编写于 作者: A ascrutae

Merge commit 'da1427bf' into feature/3.0

......@@ -8,7 +8,7 @@ import com.a.eye.skywalking.api.logging.api.ILog;
import com.a.eye.skywalking.api.logging.api.LogManager;
import com.a.eye.skywalking.api.plugin.AbstractClassEnhancePluginDefine;
import com.a.eye.skywalking.api.plugin.PluginBootstrap;
import com.a.eye.skywalking.api.plugin.PluginDefineCategory;
import com.a.eye.skywalking.api.plugin.PluginFinder;
import com.a.eye.skywalking.api.plugin.PluginException;
import net.bytebuddy.agent.builder.AgentBuilder;
......@@ -51,11 +51,11 @@ public class SkyWalkingAgent {
initConfig();
final PluginDefineCategory pluginDefineCategory = PluginDefineCategory.category(new PluginBootstrap().loadPlugins());
final PluginFinder pluginFinder = new PluginFinder(new PluginBootstrap().loadPlugins());
new AgentBuilder.Default().type(enhanceClassMatcher(pluginDefineCategory).and(not(isInterface()))).transform(new AgentBuilder.Transformer() {
new AgentBuilder.Default().type(enhanceClassMatcher(pluginFinder).and(not(isInterface()))).transform(new AgentBuilder.Transformer() {
public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassLoader classLoader) {
AbstractClassEnhancePluginDefine pluginDefine = pluginDefineCategory.findPluginDefine(typeDescription.getTypeName());
AbstractClassEnhancePluginDefine pluginDefine = pluginFinder.find(typeDescription.getTypeName());
return pluginDefine.define(typeDescription.getTypeName(), builder);
}
}).with(new AgentBuilder.Listener() {
......@@ -82,12 +82,12 @@ public class SkyWalkingAgent {
/**
* Get the enhance target classes matcher.
*
* @param pluginDefineCategory
* @param pluginFinder
* @param <T>
* @return class matcher.
*/
private static <T extends NamedElement> ElementMatcher.Junction<T> enhanceClassMatcher(PluginDefineCategory pluginDefineCategory) {
return new SkyWalkingEnhanceMatcher<T>(pluginDefineCategory);
private static <T extends NamedElement> ElementMatcher.Junction<T> enhanceClassMatcher(PluginFinder pluginFinder) {
return new SkyWalkingEnhanceMatcher<T>(pluginFinder);
}
private static String generateLocationPath() {
......
package com.a.eye.skywalking.agent.junction;
import com.a.eye.skywalking.api.plugin.PluginDefineCategory;
import com.a.eye.skywalking.api.plugin.PluginFinder;
import net.bytebuddy.description.NamedElement;
/**
......@@ -11,14 +11,14 @@ import net.bytebuddy.description.NamedElement;
*/
public class SkyWalkingEnhanceMatcher<T extends NamedElement> extends AbstractJunction<T> {
private final PluginDefineCategory pluginDefineCategory;
private final PluginFinder pluginFinder;
public SkyWalkingEnhanceMatcher(PluginDefineCategory pluginDefineCategory) {
this.pluginDefineCategory = pluginDefineCategory;
public SkyWalkingEnhanceMatcher(PluginFinder pluginFinder) {
this.pluginFinder = pluginFinder;
}
@Override
public boolean matches(T target) {
return pluginDefineCategory.findPluginDefine(target.getActualName()) != null ? true : false;
return pluginFinder.exist(target.getActualName());
}
}
......@@ -5,6 +5,7 @@ import com.a.eye.skywalking.api.logging.api.LogManager;
import com.a.eye.skywalking.api.plugin.interceptor.enhance.ClassEnhancePluginDefine;
import com.a.eye.skywalking.api.util.StringUtil;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.pool.TypePool;
import net.bytebuddy.pool.TypePool.Resolution;
/**
......@@ -16,6 +17,8 @@ import net.bytebuddy.pool.TypePool.Resolution;
public abstract class AbstractClassEnhancePluginDefine {
private static ILog logger = LogManager.getLogger(AbstractClassEnhancePluginDefine.class);
private TypePool classTypePool;
/**
* Main entrance of enhancing the class.
*
......@@ -40,7 +43,7 @@ public abstract class AbstractClassEnhancePluginDefine {
String[] witnessClasses = witnessClasses();
if (witnessClasses != null) {
for (String witnessClass : witnessClasses) {
Resolution witnessClassResolution = PluginBootstrap.CLASS_TYPE_POOL.describe(witnessClass);
Resolution witnessClassResolution = classTypePool.describe(witnessClass);
if (!witnessClassResolution.isResolved()) {
logger.warn("enhance class {} by plugin {} is not working. Because witness class {} is not existed.", transformClassName, interceptorDefineClassName,
witnessClass);
......@@ -85,4 +88,8 @@ public abstract class AbstractClassEnhancePluginDefine {
protected String[] witnessClasses() {
return new String[] {};
}
public void setClassTypePool(TypePool classTypePool) {
this.classTypePool = classTypePool;
}
}
......@@ -18,32 +18,30 @@ import java.util.List;
public class PluginBootstrap {
private static ILog logger = LogManager.getLogger(PluginBootstrap.class);
public static TypePool CLASS_TYPE_POOL = null;
/**
* load all plugins.
* @return plugin definition list.
*/
public List<AbstractClassEnhancePluginDefine> loadPlugins() {
CLASS_TYPE_POOL = TypePool.Default.ofClassPath();
TypePool classTypePool = TypePool.Default.ofClassPath();
PluginResourcesResolver resolver = new PluginResourcesResolver();
List<URL> resources = resolver.getResources();
if (resources == null || resources.size() == 0) {
logger.info("no plugin files (skywalking-plugin.properties) found, continue to start application.");
return new ArrayList<AbstractClassEnhancePluginDefine>();
return new ArrayList<>();
}
for (URL pluginUrl : resources) {
try {
PluginCfg.CFG.load(pluginUrl.openStream());
PluginCfg.INSTANCE.load(pluginUrl.openStream());
} catch (Throwable t) {
logger.error("plugin [{}] init failure.", new Object[] {pluginUrl}, t);
}
}
List<String> pluginClassList = PluginCfg.CFG.getPluginClassList();
List<String> pluginClassList = PluginCfg.INSTANCE.getPluginClassList();
List<AbstractClassEnhancePluginDefine> plugins = new ArrayList<AbstractClassEnhancePluginDefine>();
for (String pluginClassName : pluginClassList) {
......@@ -51,6 +49,7 @@ public class PluginBootstrap {
logger.debug("loading plugin class {}.", pluginClassName);
AbstractClassEnhancePluginDefine plugin =
(AbstractClassEnhancePluginDefine) Class.forName(pluginClassName).newInstance();
plugin.setClassTypePool(classTypePool);
plugins.add(plugin);
} catch (Throwable t) {
logger.error("loade plugin [{}] failure.", new Object[] {pluginClassName}, t);
......
......@@ -9,13 +9,11 @@ import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class PluginCfg {
public final static PluginCfg CFG = new PluginCfg();
public enum PluginCfg {
INSTANCE;
private List<String> pluginClassList = new ArrayList<String>();
private PluginCfg(){}
void load(InputStream input) throws IOException{
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
......
......@@ -5,16 +5,15 @@ import java.util.List;
import java.util.Map;
/**
* Just category the plugins.
* Change the store structure from {@link List} to {@link Map}
* The <code>PluginFinder</code> represents a finder , which assist to find the one
* from the given {@link AbstractClassEnhancePluginDefine} list, by name match.
*
* @author wusheng
*/
public class PluginDefineCategory {
public class PluginFinder {
private final Map<String, AbstractClassEnhancePluginDefine> pluginDefineMap = new HashMap<String, AbstractClassEnhancePluginDefine>();
private static PluginDefineCategory pluginDefineCategory;
private final Map<String, AbstractClassEnhancePluginDefine> exactClassEnhancePluginDefineMapping = new HashMap<String, AbstractClassEnhancePluginDefine>();
private PluginDefineCategory(List<AbstractClassEnhancePluginDefine> plugins) {
public PluginFinder(List<AbstractClassEnhancePluginDefine> plugins) {
for (AbstractClassEnhancePluginDefine plugin : plugins) {
String enhanceClassName = plugin.enhanceClassName();
......@@ -22,22 +21,19 @@ public class PluginDefineCategory {
continue;
}
exactClassEnhancePluginDefineMapping.put(enhanceClassName, plugin);
pluginDefineMap.put(enhanceClassName, plugin);
}
}
public static PluginDefineCategory category(List<AbstractClassEnhancePluginDefine> plugins) {
if (pluginDefineCategory == null) {
pluginDefineCategory = new PluginDefineCategory(plugins);
public AbstractClassEnhancePluginDefine find(String enhanceClassName) {
if (pluginDefineMap.containsKey(enhanceClassName)) {
return pluginDefineMap.get(enhanceClassName);
}
return pluginDefineCategory;
}
public AbstractClassEnhancePluginDefine findPluginDefine(String enhanceClassName) {
if (exactClassEnhancePluginDefineMapping.containsKey(enhanceClassName)) {
return exactClassEnhancePluginDefineMapping.get(enhanceClassName);
}
throw new PluginException("Can not find plugin:" + enhanceClassName);
}
return null;
public boolean exist(String enhanceClassName){
return pluginDefineMap.containsKey(enhanceClassName);
}
}
package com.a.eye.skywalking.api.plugin;
import net.bytebuddy.dynamic.DynamicType;
/**
* Created by wusheng on 2017/2/27.
*/
public class MockAbstractClassEnhancePluginDefine extends AbstractClassEnhancePluginDefine {
@Override
protected DynamicType.Builder<?> enhance(String enhanceOriginClassName,
DynamicType.Builder<?> newClassBuilder) throws PluginException {
return newClassBuilder;
}
@Override
protected String enhanceClassName() {
return "NotExistClass";
}
}
package com.a.eye.skywalking.api.plugin;
import java.util.List;
import org.junit.Assert;
import org.junit.Test;
/**
* @author wusheng
*/
public class PluginBootstrapTest {
@Test
public void testLoadPlugins(){
PluginBootstrap bootstrap = new PluginBootstrap();
List<AbstractClassEnhancePluginDefine> defines = bootstrap.loadPlugins();
Assert.assertEquals(1, defines.size());
Assert.assertEquals(MockAbstractClassEnhancePluginDefine.class, defines.get(0).getClass());
}
}
package com.a.eye.skywalking.api.plugin;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.powermock.api.support.membermodification.MemberModifier;
/**
* Created by wusheng on 2017/2/27.
*/
public class PluginCfgTest {
@Test
public void testLoad() throws IOException {
String data = "com.test.classA\r\ncom.test.ClassB";
final byte[] dataBytes = data.getBytes();
PluginCfg.INSTANCE.load(new InputStream() {
int index = 0;
@Override
public int read() throws IOException {
if (index == dataBytes.length) {
return -1;
}
return dataBytes[index++];
}
});
List<String> list = PluginCfg.INSTANCE.getPluginClassList();
Assert.assertEquals(2, list.size());
Assert.assertEquals("com.test.classA", list.get(0));
Assert.assertEquals("com.test.ClassB", list.get(1));
}
@Before
@After
public void clear() throws IllegalAccessException {
MemberModifier.field(PluginCfg.class, "pluginClassList").set(PluginCfg.INSTANCE, new ArrayList<String>());
}
}
package com.a.eye.skywalking.api.plugin;
import java.util.ArrayList;
import net.bytebuddy.dynamic.DynamicType;
import org.junit.Assert;
import org.junit.Test;
/**
* Created by wusheng on 2017/2/27.
*/
public class PluginFinderTest {
@Test
public void testFind(){
ArrayList<AbstractClassEnhancePluginDefine> defines = new ArrayList<>();
defines.add(new NewTestPlugin());
defines.add(new NewTestPlugin2());
PluginFinder finder = new PluginFinder(defines);
Assert.assertNotNull(finder.find("test.NewClass"));
Assert.assertTrue(finder.exist("test.NewClass"));
}
@Test(expected = PluginException.class)
public void testCanNotFind(){
ArrayList<AbstractClassEnhancePluginDefine> defines = new ArrayList<>();
defines.add(new NewTestPlugin());
PluginFinder finder = new PluginFinder(defines);
finder.find("test.NewClass2");
}
public class NewTestPlugin extends AbstractClassEnhancePluginDefine{
@Override
protected DynamicType.Builder<?> enhance(String enhanceOriginClassName,
DynamicType.Builder<?> newClassBuilder) throws PluginException {
return newClassBuilder;
}
@Override protected String enhanceClassName() {
return "test.NewClass";
}
}
public class NewTestPlugin2 extends AbstractClassEnhancePluginDefine{
@Override
protected DynamicType.Builder<?> enhance(String enhanceOriginClassName,
DynamicType.Builder<?> newClassBuilder) throws PluginException {
return newClassBuilder;
}
@Override protected String enhanceClassName() {
return null;
}
}
}
package com.a.eye.skywalking.api.plugin;
import org.junit.Assert;
import org.junit.Test;
/**
* @author wusheng
*/
public class PluginResourcesResolverTest {
@Test
public void testGetResources(){
PluginResourcesResolver resolver = new PluginResourcesResolver();
Assert.assertTrue(resolver.getResources().size() > 0);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d [%t](%F:%L) %-5level %logger{36} - %msg%n" />
</Console>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>
\ No newline at end of file
TestInterceptorDefine
TestMatcherDefine
com.a.eye.skywalking.api.plugin.MockAbstractClassEnhancePluginDefine
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册