diff --git a/skywalking-sniffer/skywalking-agent/src/main/java/com/a/eye/skywalking/agent/SkyWalkingAgent.java b/skywalking-sniffer/skywalking-agent/src/main/java/com/a/eye/skywalking/agent/SkyWalkingAgent.java index 74a72a64b..21226d285 100644 --- a/skywalking-sniffer/skywalking-agent/src/main/java/com/a/eye/skywalking/agent/SkyWalkingAgent.java +++ b/skywalking-sniffer/skywalking-agent/src/main/java/com/a/eye/skywalking/agent/SkyWalkingAgent.java @@ -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 * @return class matcher. */ - private static ElementMatcher.Junction enhanceClassMatcher(PluginDefineCategory pluginDefineCategory) { - return new SkyWalkingEnhanceMatcher(pluginDefineCategory); + private static ElementMatcher.Junction enhanceClassMatcher(PluginFinder pluginFinder) { + return new SkyWalkingEnhanceMatcher(pluginFinder); } private static String generateLocationPath() { diff --git a/skywalking-sniffer/skywalking-agent/src/main/java/com/a/eye/skywalking/agent/junction/SkyWalkingEnhanceMatcher.java b/skywalking-sniffer/skywalking-agent/src/main/java/com/a/eye/skywalking/agent/junction/SkyWalkingEnhanceMatcher.java index 340608860..3c70eb073 100644 --- a/skywalking-sniffer/skywalking-agent/src/main/java/com/a/eye/skywalking/agent/junction/SkyWalkingEnhanceMatcher.java +++ b/skywalking-sniffer/skywalking-agent/src/main/java/com/a/eye/skywalking/agent/junction/SkyWalkingEnhanceMatcher.java @@ -1,6 +1,6 @@ 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 extends AbstractJunction { - 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()); } } diff --git a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/plugin/AbstractClassEnhancePluginDefine.java b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/plugin/AbstractClassEnhancePluginDefine.java index 7d6de38fe..611544a1e 100644 --- a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/plugin/AbstractClassEnhancePluginDefine.java +++ b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/plugin/AbstractClassEnhancePluginDefine.java @@ -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; + } } diff --git a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/plugin/PluginBootstrap.java b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/plugin/PluginBootstrap.java index c5349b3d6..168c2409d 100644 --- a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/plugin/PluginBootstrap.java +++ b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/plugin/PluginBootstrap.java @@ -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 loadPlugins() { - CLASS_TYPE_POOL = TypePool.Default.ofClassPath(); + TypePool classTypePool = TypePool.Default.ofClassPath(); PluginResourcesResolver resolver = new PluginResourcesResolver(); List 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(); + 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 pluginClassList = PluginCfg.CFG.getPluginClassList(); + List pluginClassList = PluginCfg.INSTANCE.getPluginClassList(); List plugins = new ArrayList(); 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); diff --git a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/plugin/PluginCfg.java b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/plugin/PluginCfg.java index 2c31816b1..7481cda6b 100644 --- a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/plugin/PluginCfg.java +++ b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/plugin/PluginCfg.java @@ -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 pluginClassList = new ArrayList(); - private PluginCfg(){} - void load(InputStream input) throws IOException{ try{ BufferedReader reader = new BufferedReader(new InputStreamReader(input)); diff --git a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/plugin/PluginDefineCategory.java b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/plugin/PluginDefineCategory.java deleted file mode 100644 index 75f45d81b..000000000 --- a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/plugin/PluginDefineCategory.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.a.eye.skywalking.api.plugin; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Just category the plugins. - * Change the store structure from {@link List} to {@link Map} - */ -public class PluginDefineCategory { - - private static PluginDefineCategory pluginDefineCategory; - - private final Map exactClassEnhancePluginDefineMapping = new HashMap(); - - private PluginDefineCategory(List plugins) { - for (AbstractClassEnhancePluginDefine plugin : plugins) { - String enhanceClassName = plugin.enhanceClassName(); - - if (enhanceClassName == null) { - continue; - } - - exactClassEnhancePluginDefineMapping.put(enhanceClassName, plugin); - } - } - - public static PluginDefineCategory category(List plugins) { - if (pluginDefineCategory == null) { - pluginDefineCategory = new PluginDefineCategory(plugins); - } - return pluginDefineCategory; - } - - public AbstractClassEnhancePluginDefine findPluginDefine(String enhanceClassName) { - if (exactClassEnhancePluginDefineMapping.containsKey(enhanceClassName)) { - return exactClassEnhancePluginDefineMapping.get(enhanceClassName); - } - - return null; - } -} diff --git a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/plugin/PluginFinder.java b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/plugin/PluginFinder.java new file mode 100644 index 000000000..7e1579a02 --- /dev/null +++ b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/plugin/PluginFinder.java @@ -0,0 +1,39 @@ +package com.a.eye.skywalking.api.plugin; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * The PluginFinder represents a finder , which assist to find the one + * from the given {@link AbstractClassEnhancePluginDefine} list, by name match. + * + * @author wusheng + */ +public class PluginFinder { + private final Map pluginDefineMap = new HashMap(); + + public PluginFinder(List plugins) { + for (AbstractClassEnhancePluginDefine plugin : plugins) { + String enhanceClassName = plugin.enhanceClassName(); + + if (enhanceClassName == null) { + continue; + } + + pluginDefineMap.put(enhanceClassName, plugin); + } + } + + public AbstractClassEnhancePluginDefine find(String enhanceClassName) { + if (pluginDefineMap.containsKey(enhanceClassName)) { + return pluginDefineMap.get(enhanceClassName); + } + + throw new PluginException("Can not find plugin:" + enhanceClassName); + } + + public boolean exist(String enhanceClassName){ + return pluginDefineMap.containsKey(enhanceClassName); + } +} diff --git a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/plugin/MockAbstractClassEnhancePluginDefine.java b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/plugin/MockAbstractClassEnhancePluginDefine.java new file mode 100644 index 000000000..e0b0c30b0 --- /dev/null +++ b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/plugin/MockAbstractClassEnhancePluginDefine.java @@ -0,0 +1,19 @@ +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"; + } +} diff --git a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/plugin/PluginBootstrapTest.java b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/plugin/PluginBootstrapTest.java new file mode 100644 index 000000000..8e67cdff2 --- /dev/null +++ b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/plugin/PluginBootstrapTest.java @@ -0,0 +1,19 @@ +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 defines = bootstrap.loadPlugins(); + + Assert.assertEquals(1, defines.size()); + Assert.assertEquals(MockAbstractClassEnhancePluginDefine.class, defines.get(0).getClass()); + } +} diff --git a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/plugin/PluginCfgTest.java b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/plugin/PluginCfgTest.java new file mode 100644 index 000000000..4dca3c75c --- /dev/null +++ b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/plugin/PluginCfgTest.java @@ -0,0 +1,44 @@ +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 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()); + } +} diff --git a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/plugin/PluginFinderTest.java b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/plugin/PluginFinderTest.java new file mode 100644 index 000000000..f63e46eb4 --- /dev/null +++ b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/plugin/PluginFinderTest.java @@ -0,0 +1,55 @@ +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 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 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; + } + } +} diff --git a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/plugin/PluginResourcesResolverTest.java b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/plugin/PluginResourcesResolverTest.java new file mode 100644 index 000000000..9cd4b1c6f --- /dev/null +++ b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/plugin/PluginResourcesResolverTest.java @@ -0,0 +1,17 @@ +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); + } + +} diff --git a/skywalking-sniffer/skywalking-api/src/test/resources/log4j2.xml b/skywalking-sniffer/skywalking-api/src/test/resources/log4j2.xml deleted file mode 100644 index c7735f44e..000000000 --- a/skywalking-sniffer/skywalking-api/src/test/resources/log4j2.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/skywalking-sniffer/skywalking-api/src/test/resources/skywalking-plugin.def b/skywalking-sniffer/skywalking-api/src/test/resources/skywalking-plugin.def index bbf397505..df15cbdab 100644 --- a/skywalking-sniffer/skywalking-api/src/test/resources/skywalking-plugin.def +++ b/skywalking-sniffer/skywalking-api/src/test/resources/skywalking-plugin.def @@ -1,2 +1 @@ -TestInterceptorDefine -TestMatcherDefine +com.a.eye.skywalking.api.plugin.MockAbstractClassEnhancePluginDefine