This is an automated email from the ASF dual-hosted git repository. wusheng pushed a commit to branch rt-oal in repository https://gitbox.apache.org/repos/asf/skywalking.git
commit e966f35bfef92a35a713dab1fcd1e5e6dd9f6d4f Author: Wu Sheng <[email protected]> AuthorDate: Wed Jul 17 17:48:47 2019 +0800 Support dispatcher generation. --- .../org/apache/skywalking/oal/rt/OALRuntime.java | 81 +++++++++++++++++++++- .../oap/server/core/CoreModuleProvider.java | 1 + .../DispatcherDetectorListener.java} | 15 +--- .../server/core/analysis/DispatcherManager.java | 3 +- .../oap/server/core/oal/rt/OALEngine.java | 3 + .../oap/server/core/source/SourceReceiverImpl.java | 3 +- 6 files changed, 89 insertions(+), 17 deletions(-) diff --git a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/OALRuntime.java b/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/OALRuntime.java index d4f5268..7c9d5c0 100644 --- a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/OALRuntime.java +++ b/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/OALRuntime.java @@ -31,6 +31,7 @@ import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; import java.util.Locale; +import java.util.Map; import javassist.CannotCompileException; import javassist.ClassPool; import javassist.CtClass; @@ -42,6 +43,7 @@ import javassist.NotFoundException; import javassist.bytecode.AnnotationsAttribute; import javassist.bytecode.ClassFile; import javassist.bytecode.ConstPool; +import javassist.bytecode.SignatureAttribute; import javassist.bytecode.annotation.Annotation; import javassist.bytecode.annotation.ClassMemberValue; import javassist.bytecode.annotation.IntegerMemberValue; @@ -59,11 +61,14 @@ import org.apache.skywalking.oal.rt.parser.ScriptParser; import org.apache.skywalking.oal.rt.parser.SourceColumn; import org.apache.skywalking.oal.rt.parser.SourceColumnsFactory; import org.apache.skywalking.oap.server.core.WorkPath; +import org.apache.skywalking.oap.server.core.analysis.DispatcherDetectorListener; +import org.apache.skywalking.oap.server.core.analysis.SourceDispatcher; import org.apache.skywalking.oap.server.core.analysis.Stream; import org.apache.skywalking.oap.server.core.analysis.StreamAnnotationListener; import org.apache.skywalking.oap.server.core.oal.rt.OALCompileException; import org.apache.skywalking.oap.server.core.oal.rt.OALEngine; import org.apache.skywalking.oap.server.core.storage.annotation.Column; +import org.apache.skywalking.oap.server.core.storage.annotation.IDColumn; import org.apache.skywalking.oap.server.library.module.ModuleStartException; import org.apache.skywalking.oap.server.library.util.ResourceUtils; import org.slf4j.Logger; @@ -81,10 +86,12 @@ public class OALRuntime implements OALEngine { private static final Charset CLASS_FILE_CHARSET = Charset.forName("UTF-8"); private static final String METRICS_FUNCTION_PACKAGE = "org.apache.skywalking.oap.server.core.analysis.metrics."; private static final String DYNAMIC_METRICS_CLASS_PACKAGE = "org.apache.skywalking.oal.rt.metrics."; - private static final String DYNAMIC_METRICS_BUILDER_CLASS_PACKAGE = "org.apache.skywalking.oal.rt.metrics.builder"; + private static final String DYNAMIC_METRICS_BUILDER_CLASS_PACKAGE = "org.apache.skywalking.oal.rt.metrics.builder."; + private static final String DYNAMIC_DISPATCHER_CLASS_PACKAGE = "org.apache.skywalking.oal.rt.dispatcher."; private static final String WITH_METADATA_INTERFACE = "org.apache.skywalking.oap.server.core.analysis.metrics.WithMetadata"; private static final String STORAGE_BUILDER_INTERFACE = "org.apache.skywalking.oap.server.core.storage.StorageBuilder"; - private static final String SOURCE_DISPATCHER_INTERFACE = "org.apache.skywalking.oap.server.core.analysis.SourceDispatcher"; + private static final String DISPATCHER_INTERFACE = "org.apache.skywalking.oap.server.core.analysis.SourceDispatcher"; + private static final String SOURCE_PACKAGE = "org.apache.skywalking.oap.server.core.source."; private static final String METRICS_STREAM_PROCESSOR = "org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor"; private static final String[] METRICS_CLASS_METHODS = {"id", "hashCode", "remoteHashCode", "equals", "serialize", "deserialize", "getMeta", "toDay"}; @@ -95,7 +102,9 @@ public class OALRuntime implements OALEngine { private Configuration configuration; private AllDispatcherContext allDispatcherContext; private StreamAnnotationListener streamAnnotationListener; + private DispatcherDetectorListener dispatcherDetectorListener; private final List<Class> metricsClasses; + private final List<Class> dispatcherClasses; public OALRuntime() { classPool = ClassPool.getDefault(); @@ -104,12 +113,17 @@ public class OALRuntime implements OALEngine { configuration.setClassLoaderForTemplateLoading(FileGenerator.class.getClassLoader(), "/code-templates"); allDispatcherContext = new AllDispatcherContext(); metricsClasses = new ArrayList<>(); + dispatcherClasses = new ArrayList<>(); } @Override public void setStreamListener(StreamAnnotationListener listener) throws ModuleStartException { this.streamAnnotationListener = listener; } + @Override public void setDispatcherListener(DispatcherDetectorListener listener) throws ModuleStartException { + dispatcherDetectorListener = listener; + } + @Override public void start(ClassLoader currentClassLoader) throws ModuleStartException, OALCompileException { prepareRTTempFoler(); @@ -150,6 +164,13 @@ public class OALRuntime implements OALEngine { @Override public void notifyAllListeners() throws ModuleStartException { metricsClasses.forEach(streamAnnotationListener::notify); + for (Class dispatcherClass : dispatcherClasses) { + try { + dispatcherDetectorListener.addIfAsSourceDispatcher(dispatcherClass); + } catch (Exception e) { + throw new ModuleStartException(e.getMessage(), e); + } + } } private void generateClassAtRuntime(OALScripts oalScripts) throws OALCompileException { @@ -161,6 +182,9 @@ public class OALRuntime implements OALEngine { generateMetricsBuilderClass(metricsStmt); } + for (Map.Entry<String, DispatcherContext> entry : allDispatcherContext.getAllContext().entrySet()) { + dispatcherClasses.add(generateDispatcherClass(entry.getKey(), entry.getValue())); + } } /** @@ -227,7 +251,7 @@ public class OALRuntime implements OALEngine { /** * Add @IDColumn */ - Annotation idAnnotation = new Annotation(Column.class.getName(), constPool); + Annotation idAnnotation = new Annotation(IDColumn.class.getName(), constPool); annotationsAttribute.addAnnotation(idAnnotation); } @@ -336,6 +360,53 @@ public class OALRuntime implements OALEngine { writeGeneratedFile(metricsBuilderClass, className, "metrics/builder"); } + /** + * Generate SourceDispatcher class and inject it to classloader + * + * @throws OALCompileException + */ + private Class generateDispatcherClass(String scopeName, + DispatcherContext dispatcherContext) throws OALCompileException { + + String className = dispatcherClassName(scopeName, false); + CtClass dispatcherClass = classPool.makeClass(dispatcherClassName(scopeName, true)); + try { + CtClass dispatcherInterface = classPool.get(DISPATCHER_INTERFACE); + + dispatcherClass.addInterface(dispatcherInterface); + + /** + * Set generic signature + */ + String sourceClassName = SOURCE_PACKAGE + dispatcherContext.getSource(); + SignatureAttribute.ClassSignature dispatcherSignature = new SignatureAttribute.ClassSignature(null, null, + // Set interface and its generic params + new SignatureAttribute.ClassType[] { + new SignatureAttribute.ClassType(SourceDispatcher.class.getCanonicalName(), + new SignatureAttribute.TypeArgument[] {new SignatureAttribute.TypeArgument(new SignatureAttribute.ClassType(sourceClassName))} + )}); + + dispatcherClass.setGenericSignature(dispatcherSignature.encode()); + } catch (NotFoundException e) { + logger.error("Can't find Dispatcher interface for " + className + ".", e); + throw new OALCompileException(e.getMessage(), e); + } + + /** + * Generate methods + */ + Class targetClass; + try { + targetClass = dispatcherClass.toClass(currentClassLoader, null); + } catch (CannotCompileException e) { + logger.error("Can't compile/load " + className + ".", e); + throw new OALCompileException(e.getMessage(), e); + } + + writeGeneratedFile(dispatcherClass, className, "dispatcher"); + return targetClass; + } + private String metricsClassName(AnalysisResult metricsStmt, boolean fullName) { return (fullName ? DYNAMIC_METRICS_CLASS_PACKAGE : "") + metricsStmt.getMetricsName() + "Metrics"; } @@ -344,6 +415,10 @@ public class OALRuntime implements OALEngine { return (fullName ? DYNAMIC_METRICS_BUILDER_CLASS_PACKAGE : "") + metricsStmt.getMetricsName() + "MetricsBuilder"; } + private String dispatcherClassName(String scopeName, boolean fullName) { + return (fullName ? DYNAMIC_DISPATCHER_CLASS_PACKAGE : "") + scopeName + "Dispatcher"; + } + private void buildDispatcherContext(AnalysisResult metricsStmt) { String sourceName = metricsStmt.getSourceName(); diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModuleProvider.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModuleProvider.java index 3fc1127..2c8f78a 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModuleProvider.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModuleProvider.java @@ -92,6 +92,7 @@ public class CoreModuleProvider extends ModuleProvider { oalEngine = OALEngineLoader.get(); oalEngine.setStreamListener(streamAnnotationListener); + oalEngine.setDispatcherListener(receiver.getDispatcherManager()); oalEngine.start(getClass().getClassLoader()); } catch (Exception e) { throw new ModuleStartException(e.getMessage(), e); diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/oal/rt/OALEngine.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/DispatcherDetectorListener.java similarity index 59% copy from oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/oal/rt/OALEngine.java copy to oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/DispatcherDetectorListener.java index ae1a0dc..0c29033 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/oal/rt/OALEngine.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/DispatcherDetectorListener.java @@ -16,20 +16,11 @@ * */ -package org.apache.skywalking.oap.server.core.oal.rt; - -import org.apache.skywalking.oap.server.core.analysis.StreamAnnotationListener; -import org.apache.skywalking.oap.server.library.module.ModuleStartException; +package org.apache.skywalking.oap.server.core.analysis; /** - * OALEngine defines the main entrance of the oal script engine runtime. - * * @author wusheng */ -public interface OALEngine { - void setStreamListener(StreamAnnotationListener listener) throws ModuleStartException; - - void start(ClassLoader currentClassLoader) throws ModuleStartException, OALCompileException; - - void notifyAllListeners() throws ModuleStartException; +public interface DispatcherDetectorListener { + void addIfAsSourceDispatcher(Class aClass) throws IllegalAccessException, InstantiationException; } diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/DispatcherManager.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/DispatcherManager.java index 46e82f2..3ca642f 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/DispatcherManager.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/DispatcherManager.java @@ -35,7 +35,7 @@ import org.slf4j.LoggerFactory; /** * @author peng-yongsheng, wusheng */ -public class DispatcherManager { +public class DispatcherManager implements DispatcherDetectorListener{ private static final Logger logger = LoggerFactory.getLogger(DispatcherManager.class); @@ -84,6 +84,7 @@ public class DispatcherManager { } } + @Override public void addIfAsSourceDispatcher(Class aClass) throws IllegalAccessException, InstantiationException { if (!aClass.isInterface() && SourceDispatcher.class.isAssignableFrom(aClass)) { Type[] genericInterfaces = aClass.getGenericInterfaces(); diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/oal/rt/OALEngine.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/oal/rt/OALEngine.java index ae1a0dc..7eaf814 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/oal/rt/OALEngine.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/oal/rt/OALEngine.java @@ -18,6 +18,7 @@ package org.apache.skywalking.oap.server.core.oal.rt; +import org.apache.skywalking.oap.server.core.analysis.DispatcherDetectorListener; import org.apache.skywalking.oap.server.core.analysis.StreamAnnotationListener; import org.apache.skywalking.oap.server.library.module.ModuleStartException; @@ -29,6 +30,8 @@ import org.apache.skywalking.oap.server.library.module.ModuleStartException; public interface OALEngine { void setStreamListener(StreamAnnotationListener listener) throws ModuleStartException; + void setDispatcherListener(DispatcherDetectorListener listener) throws ModuleStartException; + void start(ClassLoader currentClassLoader) throws ModuleStartException, OALCompileException; void notifyAllListeners() throws ModuleStartException; diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/SourceReceiverImpl.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/SourceReceiverImpl.java index 4c48efd..425e7b5 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/SourceReceiverImpl.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/SourceReceiverImpl.java @@ -19,13 +19,14 @@ package org.apache.skywalking.oap.server.core.source; import java.io.IOException; +import lombok.Getter; import org.apache.skywalking.oap.server.core.analysis.DispatcherManager; /** * @author peng-yongsheng */ public class SourceReceiverImpl implements SourceReceiver { - + @Getter private final DispatcherManager dispatcherManager; public SourceReceiverImpl() {
