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

xiaoyu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new d20bd5e  Implemented Pluginloader (#8429)
d20bd5e is described below

commit d20bd5e41244d346efa50379c4610c8eced9d5f3
Author: Daming <[email protected]>
AuthorDate: Tue Dec 1 11:33:34 2020 +0800

    Implemented Pluginloader (#8429)
    
    * feature: implemented plugin loader
    
    * feature: implemented plugin loader
    
    * improvement
    
    * remove final keyword
---
 .../agent/bootstrap/ShardingSphereAgent.java       |  12 +-
 .../agent/core/ShardingSphereTransformer.java      |   6 +-
 .../core/exception/AdviceNotFoundException.java    |  25 +++
 .../agent/core/plugin/PluginAdviceDefine.java      | 113 ++++++-------
 .../agent/core/plugin/PluginDefine.java            |  80 +++++++++
 .../agent/core/plugin/PluginLoader.java            | 180 ++++++++++++++++++++-
 .../shardingsphere/agent/core/plugin/Service.java  |  40 +++++
 7 files changed, 386 insertions(+), 70 deletions(-)

diff --git 
a/shardingsphere-agent/shardingsphere-agent-bootstrap/src/main/java/org/apache/shardingsphere/agent/bootstrap/ShardingSphereAgent.java
 
b/shardingsphere-agent/shardingsphere-agent-bootstrap/src/main/java/org/apache/shardingsphere/agent/bootstrap/ShardingSphereAgent.java
index 360dfa3..76cce23 100644
--- 
a/shardingsphere-agent/shardingsphere-agent-bootstrap/src/main/java/org/apache/shardingsphere/agent/bootstrap/ShardingSphereAgent.java
+++ 
b/shardingsphere-agent/shardingsphere-agent-bootstrap/src/main/java/org/apache/shardingsphere/agent/bootstrap/ShardingSphereAgent.java
@@ -49,19 +49,23 @@ public class ShardingSphereAgent {
         SingletonHolder.INSTANCE.put(agentConfiguration);
 
         ByteBuddy byteBuddy = new ByteBuddy().with(TypeValidation.ENABLED);
-
+    
         AgentBuilder builder = new AgentBuilder.Default()
             .with(byteBuddy)
             .ignore(ElementMatchers.isSynthetic())
             
.or(ElementMatchers.nameStartsWith("org.apache.shardingsphere.agent."))
             
.or(ElementMatchers.not(ElementMatchers.nameStartsWith("org.apache.shardingsphere.")));
-
-        PluginLoader pluginLoader = new PluginLoader();
-
+    
+        PluginLoader pluginLoader = PluginLoader.getInstance();
+        pluginLoader.initialAllServices();
+    
         builder.type(pluginLoader.typeMatcher())
                .transform(new ShardingSphereTransformer(pluginLoader))
                .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
                .with(new LoggingListener())
                .installOn(instrumentation);
+    
+        pluginLoader.startAllServices();
+        Runtime.getRuntime().addShutdownHook(new 
Thread(pluginLoader::shutdownAllServices));
     }
 }
diff --git 
a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/ShardingSphereTransformer.java
 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/ShardingSphereTransformer.java
index 0e352c9..65de521 100644
--- 
a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/ShardingSphereTransformer.java
+++ 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/ShardingSphereTransformer.java
@@ -62,7 +62,7 @@ public class ShardingSphereTransformer implements 
AgentBuilder.Transformer {
             final PluginAdviceDefine define = 
pluginLoader.loadPluginAdviceDefine(typeDescription);
             for (ConstructorPoint point : define.getConstructorPoints()) {
                 try {
-                    final ConstructorMethodInterceptor interceptor = new 
ConstructorMethodInterceptor(pluginLoader.getInstance(point.getAdvice()));
+                    final ConstructorMethodInterceptor interceptor = new 
ConstructorMethodInterceptor(pluginLoader.getOrCreateInstance(point.getAdvice()));
                     newBuilder = 
newBuilder.constructor(point.getConstructorMatcher())
                             
.intercept(SuperMethodCall.INSTANCE.andThen(MethodDelegation.withDefaultConfiguration().to(interceptor)));
                     // CHECKSTYLE:OFF
@@ -74,7 +74,7 @@ public class ShardingSphereTransformer implements 
AgentBuilder.Transformer {
 
             for (ClassStaticMethodPoint point : 
define.getClassStaticMethodPoints()) {
                 try {
-                    final StaticMethodAroundInterceptor interceptor = new 
StaticMethodAroundInterceptor(pluginLoader.getInstance(point.getAdvice()));
+                    final StaticMethodAroundInterceptor interceptor = new 
StaticMethodAroundInterceptor(pluginLoader.getOrCreateInstance(point.getAdvice()));
                     newBuilder = newBuilder.method(point.getMethodsMatcher())
                             
.intercept(MethodDelegation.withDefaultConfiguration().to(interceptor));
                     // CHECKSTYLE:OFF
@@ -86,7 +86,7 @@ public class ShardingSphereTransformer implements 
AgentBuilder.Transformer {
 
             for (InstanceMethodPoint point : define.getInstanceMethodPoints()) 
{
                 try {
-                    final MethodAroundInterceptor interceptor = new 
MethodAroundInterceptor(pluginLoader.getInstance(point.getAdvice()));
+                    final MethodAroundInterceptor interceptor = new 
MethodAroundInterceptor(pluginLoader.getOrCreateInstance(point.getAdvice()));
                     newBuilder = newBuilder.method(point.getMethodMatcher())
                             
.intercept(MethodDelegation.withDefaultConfiguration().to(interceptor));
                     // CHECKSTYLE:OFF
diff --git 
a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/exception/AdviceNotFoundException.java
 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/exception/AdviceNotFoundException.java
new file mode 100644
index 0000000..1c59c54
--- /dev/null
+++ 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/exception/AdviceNotFoundException.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.shardingsphere.agent.core.exception;
+
+/**
+ * Advice not found exception.
+ */
+public class AdviceNotFoundException extends RuntimeException {
+}
diff --git 
a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/PluginAdviceDefine.java
 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/PluginAdviceDefine.java
index fcc7b19..cbb74e2 100644
--- 
a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/PluginAdviceDefine.java
+++ 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/PluginAdviceDefine.java
@@ -40,21 +40,33 @@ import java.util.List;
  * </code>
  */
 public final class PluginAdviceDefine {
-
+    
+    private final String classNameOfTarget;
+    
     private final List<ConstructorPoint> constructorPoints;
-
+    
     private final List<InstanceMethodPoint> instanceMethodPoints;
-
+    
     private final List<ClassStaticMethodPoint> classStaticMethodPoints;
-
-    private PluginAdviceDefine(final List<ConstructorPoint> constructorPoints,
+    
+    private PluginAdviceDefine(final String classNameOfTarget,
+                               final List<ConstructorPoint> constructorPoints,
                                final List<InstanceMethodPoint> 
instanceMethodPoints,
                                final List<ClassStaticMethodPoint> 
classStaticMethodPoints) {
+        this.classNameOfTarget = classNameOfTarget;
         this.constructorPoints = constructorPoints;
         this.instanceMethodPoints = instanceMethodPoints;
         this.classStaticMethodPoints = classStaticMethodPoints;
     }
-
+    
+    /**
+     * Get class name of target.
+     * @return class name.
+     */
+    public String getClassNameOfTarget() {
+        return classNameOfTarget;
+    }
+    
     /**
      * Intercept target class.
      *
@@ -64,7 +76,7 @@ public final class PluginAdviceDefine {
     public static Builder intercept(final String classNameOfTarget) {
         return new Builder(classNameOfTarget);
     }
-
+    
     /**
      * To get static method point configurations.
      *
@@ -73,7 +85,7 @@ public final class PluginAdviceDefine {
     public List<ClassStaticMethodPoint> getClassStaticMethodPoints() {
         return classStaticMethodPoints;
     }
-
+    
     /**
      * To get constructor point configurations.
      *
@@ -82,7 +94,7 @@ public final class PluginAdviceDefine {
     public List<ConstructorPoint> getConstructorPoints() {
         return constructorPoints;
     }
-
+    
     /**
      * To get instance point configurations.
      *
@@ -91,34 +103,23 @@ public final class PluginAdviceDefine {
     public List<InstanceMethodPoint> getInstanceMethodPoints() {
         return instanceMethodPoints;
     }
-
+    
     /**
      * Plugin advice configuration builder.
      */
     public static final class Builder {
         private final List<ConstructorPoint> constructorPoints = 
Lists.newArrayList();
-
+        
         private final List<InstanceMethodPoint> instanceMethodPoints = 
Lists.newArrayList();
-
+        
         private final List<ClassStaticMethodPoint> classStaticMethodPoints = 
Lists.newArrayList();
-
+        
         private final String classNameOfTarget;
-
+        
         private Builder(final String classNameOfTarget) {
             this.classNameOfTarget = classNameOfTarget;
         }
-
-        /**
-         * Intercept the new target.
-         *
-         * @param classNameOfTarget the class name of target.
-         * @return configuration builder.
-         */
-        public Builder intercept(final String classNameOfTarget) {
-            // TODO not-implemented yet
-            return this;
-        }
-
+        
         /**
          * Configure the intercepting point on constructor.
          *
@@ -128,54 +129,54 @@ public final class PluginAdviceDefine {
         public ConstructorPointBuilder onConstructor(final ElementMatcher<? 
super MethodDescription> matcher) {
             return new ConstructorPointBuilder(this, matcher);
         }
-
+        
         /**
          * Configure the intercepting point around instance method.
          *
          * @param matcher constraints
          * @return configuration builder
          */
-        public InstanceMethodPointBuilder method(final ElementMatcher<? super 
MethodDescription> matcher) {
+        public InstanceMethodPointBuilder aroundInstanceMethod(final 
ElementMatcher<? super MethodDescription> matcher) {
             return new InstanceMethodPointBuilder(this, matcher);
         }
-
+        
         /**
          * Configure the intercepting point around instance method.
          *
          * @param matcher constraints
          * @return configuration builder
          */
-        public StaticMethodPointBuilder staticMethod(final ElementMatcher<? 
super MethodDescription> matcher) {
+        public StaticMethodPointBuilder aroundClassStaticMethod(final 
ElementMatcher<? super MethodDescription> matcher) {
             return new StaticMethodPointBuilder(this, matcher);
         }
-
-
+        
+        
         /**
          * Build configuration.
          *
          * @return plugin advice definition.
          */
         public PluginAdviceDefine install() {
-            return new PluginAdviceDefine(constructorPoints, 
instanceMethodPoints, classStaticMethodPoints);
+            return new PluginAdviceDefine(classNameOfTarget, 
constructorPoints, instanceMethodPoints, classStaticMethodPoints);
         }
-
+        
         /**
          * Instance method intercepting point configuration builder.
          */
         public static final class InstanceMethodPointBuilder {
             private final Builder builder;
-
+            
             private String classNameOfAdvice;
-
+            
             private boolean overrideArgs;
-
+            
             private ElementMatcher<? super MethodDescription> matcher;
-
+            
             private InstanceMethodPointBuilder(final Builder builder, final 
ElementMatcher<? super MethodDescription> matcher) {
                 this.builder = builder;
                 this.matcher = matcher;
             }
-
+            
             /**
              * Configure implementation for interceptor point.
              *
@@ -186,7 +187,7 @@ public final class PluginAdviceDefine {
                 this.classNameOfAdvice = classNameOfAdvice;
                 return this;
             }
-
+            
             /**
              * Configure whether or not override the origin method arguments.
              *
@@ -197,7 +198,7 @@ public final class PluginAdviceDefine {
                 this.overrideArgs = overrideArgs;
                 return this;
             }
-
+            
             /**
              * Build instance methods configuration.
              *
@@ -208,24 +209,24 @@ public final class PluginAdviceDefine {
                 return builder;
             }
         }
-
+        
         /**
          * Static method intercepting point configuration builder.
          */
         public static final class StaticMethodPointBuilder {
             private final Builder builder;
-
+            
             private String classNameOfAdvice;
-
+            
             private boolean overrideArgs;
-
+            
             private ElementMatcher<? super MethodDescription> matcher;
-
+            
             private StaticMethodPointBuilder(final Builder builder, final 
ElementMatcher<? super MethodDescription> matcher) {
                 this.builder = builder;
                 this.matcher = ElementMatchers.isStatic().and(matcher);
             }
-
+            
             /**
              * Configure implementation for intercepting point.
              *
@@ -236,7 +237,7 @@ public final class PluginAdviceDefine {
                 this.classNameOfAdvice = classNameOfAdvice;
                 return this;
             }
-
+            
             /**
              * Configure whether or not override the origin method arguments.
              *
@@ -247,7 +248,7 @@ public final class PluginAdviceDefine {
                 this.overrideArgs = overrideArgs;
                 return this;
             }
-
+            
             /**
              * Build static methods configuration.
              *
@@ -257,24 +258,24 @@ public final class PluginAdviceDefine {
                 builder.classStaticMethodPoints.add(new 
ClassStaticMethodPoint(matcher, classNameOfAdvice, overrideArgs));
                 return builder;
             }
-
+            
         }
-
+        
         /**
          * Instance constructor intercepting point configuration builder.
          */
         public static final class ConstructorPointBuilder {
             private final Builder builder;
-
+            
             private String classNameOfAdvice;
-
+            
             private ElementMatcher<? super MethodDescription> matcher;
-
+            
             private ConstructorPointBuilder(final Builder builder, final 
ElementMatcher<? super MethodDescription> matcher) {
                 this.builder = builder;
                 this.matcher = ElementMatchers.isConstructor().and(matcher);
             }
-
+            
             /**
              * Configure implementation for intercepting point.
              *
@@ -285,7 +286,7 @@ public final class PluginAdviceDefine {
                 this.classNameOfAdvice = classNameOfAdvice;
                 return this;
             }
-
+            
             /**
              * Build constructor point configuration.
              *
diff --git 
a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/PluginDefine.java
 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/PluginDefine.java
new file mode 100644
index 0000000..5490542
--- /dev/null
+++ 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/PluginDefine.java
@@ -0,0 +1,80 @@
+/*
+ * 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.shardingsphere.agent.core.plugin;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * Plugin definition.
+ */
+public abstract class PluginDefine {
+
+    private final Map<String, PluginAdviceDefine.Builder> defineMap = 
Maps.newHashMap();
+
+    private final List<Class<? extends Service>> services = 
Lists.newArrayList();
+
+    /**
+     * Configure the plugin here.
+     */
+    protected abstract void define();
+
+    protected PluginAdviceDefine.Builder intercept(final String 
classNameOfTarget) {
+        if (defineMap.containsKey(classNameOfTarget)) {
+            return defineMap.get(classNameOfTarget);
+        }
+        PluginAdviceDefine.Builder builder = 
PluginAdviceDefine.intercept(classNameOfTarget);
+        defineMap.put(classNameOfTarget, builder);
+        return builder;
+    }
+
+    /**
+     * Register service to agent.
+     *
+     * @param service the class of Service.
+     */
+    protected void registerService(final Class<? extends Service> service) {
+        services.add(service);
+    }
+
+    /**
+     * To build Plugin definition.
+     *
+     * @return configurations.
+     */
+    public final List<PluginAdviceDefine> build() {
+        define();
+        return defineMap.values().stream()
+                .map(PluginAdviceDefine.Builder::install)
+                .collect(Collectors.toList());
+    }
+
+    /**
+     * To get all services.
+     *
+     * @return all services.
+     */
+    public List<Class<? extends Service>> getAllServics() {
+        return services;
+    }
+}
diff --git 
a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/PluginLoader.java
 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/PluginLoader.java
index 7a7f548..d35cff8 100644
--- 
a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/PluginLoader.java
+++ 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/PluginLoader.java
@@ -18,31 +18,149 @@
 
 package org.apache.shardingsphere.agent.core.plugin;
 
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import com.google.common.io.ByteStreams;
 import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
 import net.bytebuddy.description.type.TypeDescription;
 import net.bytebuddy.matcher.ElementMatcher;
+import net.bytebuddy.matcher.ElementMatchers;
+import org.apache.shardingsphere.agent.core.common.AgentPathLocator;
+import org.apache.shardingsphere.agent.core.exception.AdviceNotFoundException;
 
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.locks.ReentrantLock;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
 
 /**
  * Plugins loader.
- * TODO not-implemented yet
  */
-public class PluginLoader extends ClassLoader {
+@Slf4j
+public final class PluginLoader extends ClassLoader implements Closeable {
+
+    private static final PluginLoader INSTANCE = new PluginLoader();
 
     private final ConcurrentHashMap<String, Object> objectPool = new 
ConcurrentHashMap<>();
 
     private final ReentrantLock lock = new ReentrantLock();
 
+    private final List<JarFile> jars = Lists.newArrayList();
+
+    private final List<Service> services = Lists.newArrayList();
+
+    private Map<String, PluginAdviceDefine> pluginDefineMap;
+
+    private PluginLoader() {
+        try {
+            pluginDefineMap = loadAllPlugins();
+        } catch (IOException ioe) {
+            log.error("Failed to load plugins.");
+        }
+    }
+
+    @Override
+    protected Class<?> findClass(final String name) throws 
ClassNotFoundException {
+        String path = classNameToPath(name);
+        for (JarFile jar : jars) {
+            ZipEntry entry = jar.getEntry(path);
+            if (Objects.nonNull(entry)) {
+                try {
+                    byte[] data = 
ByteStreams.toByteArray(jar.getInputStream(entry));
+                    return defineClass(name, data, 0, data.length);
+                } catch (IOException ioe) {
+                    log.error("Failed to load class {}.", name, ioe);
+                }
+            }
+        }
+        throw new ClassNotFoundException("Class " + name + " not found.");
+    }
+
+    @Override
+    public void close() {
+        for (JarFile jar : jars) {
+            try {
+                jar.close();
+            } catch (IOException ioe) {
+                log.error("", ioe);
+            }
+        }
+    }
+
+    /**
+     * To get plugin loader instance.
+     *
+     * @return plugin loader
+     */
+    public static PluginLoader getInstance() {
+        return INSTANCE;
+    }
+
+    private Map<String, PluginAdviceDefine> loadAllPlugins() throws 
IOException {
+        File[] jarFiles = AgentPathLocator.getAgentPath().listFiles(file -> 
file.getName().endsWith(".jar"));
+        ImmutableMap.Builder<String, PluginAdviceDefine> pluginDefineMap = 
ImmutableMap.builder();
+        if (jarFiles == null) {
+            return pluginDefineMap.build();
+        }
+
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+
+        for (File jarFile : jarFiles) {
+            outputStream.reset();
+
+            JarFile jar = new JarFile(jarFile, true);
+            jars.add(jar);
+
+            Attributes attributes = jar.getManifest().getMainAttributes();
+            String entrypoint = attributes.getValue("Entrypoint");
+            if (Strings.isNullOrEmpty(entrypoint)) {
+                log.warn("Entrypoint is not setting in {}.", 
jarFile.getName());
+                continue;
+            }
+
+            
ByteStreams.copy(jar.getInputStream(jar.getEntry(classNameToPath(entrypoint))), 
outputStream);
+
+            try {
+                PluginDefine config = (PluginDefine) defineClass(entrypoint, 
outputStream.toByteArray(), 0, outputStream.size())
+                        .newInstance();
+
+                config.getAllServics().forEach(klass -> {
+                    try {
+                        services.add(klass.newInstance());
+                    } catch (InstantiationException | IllegalAccessException 
e) {
+                        log.error("Failed to create service instance, {}.", 
klass.getTypeName(), e);
+                    }
+                });
+
+                config.build().forEach(plugin -> 
pluginDefineMap.put(plugin.getClassNameOfTarget(), plugin));
+            } catch (InstantiationException | IllegalAccessException e) {
+                log.error("Failed to load plugin definition, {}.", entrypoint, 
e);
+            }
+        }
+        return pluginDefineMap.build();
+    }
+
+    private String classNameToPath(final String className) {
+        return className.replace(".", "/") + ".class";
+    }
+
     /**
      * To find all intercepting target classes then to build TypeMatcher.
      *
      * @return type matcher
      */
     public ElementMatcher<? super TypeDescription> typeMatcher() {
-        return null;
+        return 
ElementMatchers.anyOf(pluginDefineMap.keySet().stream().map(ElementMatchers::named).toArray());
     }
 
     /**
@@ -52,7 +170,7 @@ public class PluginLoader extends ClassLoader {
      * @return contains when it is true.
      */
     public boolean containsType(final TypeDescription typeDescription) {
-        return false;
+        return pluginDefineMap.containsKey(typeDescription.getTypeName());
     }
 
     /**
@@ -62,18 +180,21 @@ public class PluginLoader extends ClassLoader {
      * @return the plugin definition configurations.
      */
     public PluginAdviceDefine loadPluginAdviceDefine(final TypeDescription 
typeDescription) {
-        return null;
+        if (pluginDefineMap.containsKey(typeDescription.getTypeName())) {
+            return pluginDefineMap.get(typeDescription.getTypeName());
+        }
+        throw new AdviceNotFoundException();
     }
 
     /**
      * To get or create instance of the advice class. Create new one and 
caching when it is not exist.
      *
      * @param classNameOfAdvice the class name of advice
-     * @param <T> the advice type.
+     * @param <T>               the advice type.
      * @return instance of advice
      */
     @SneakyThrows({ClassNotFoundException.class, IllegalAccessException.class, 
InstantiationException.class})
-    public <T> T getInstance(final String classNameOfAdvice) {
+    public <T> T getOrCreateInstance(final String classNameOfAdvice) {
 
         if (objectPool.containsKey(classNameOfAdvice)) {
             return (T) objectPool.get(classNameOfAdvice);
@@ -92,4 +213,49 @@ public class PluginLoader extends ClassLoader {
             lock.unlock();
         }
     }
+
+    /**
+     * Initial all services.
+     */
+    public void initialAllServices() {
+        services.forEach(service -> {
+            try {
+                service.setup();
+                // CHECKSTYLE:OFF
+            } catch (Exception e) {
+                // CHECKSTYLE:ON
+                log.error("Failed to initial service.");
+            }
+        });
+    }
+
+    /**
+     * Start all services.
+     */
+    public void startAllServices() {
+        services.forEach(service -> {
+            try {
+                service.start();
+                // CHECKSTYLE:OFF
+            } catch (Exception e) {
+                // CHECKSTYLE:ON
+                log.error("Failed to start service.");
+            }
+        });
+    }
+
+    /**
+     * Shutdown all services.
+     */
+    public void shutdownAllServices() {
+        services.forEach(service -> {
+            try {
+                service.cleanup();
+                // CHECKSTYLE:OFF
+            } catch (Exception e) {
+                // CHECKSTYLE:ON
+                log.error("Failed to shutdown service.");
+            }
+        });
+    }
 }
diff --git 
a/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/Service.java
 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/Service.java
new file mode 100644
index 0000000..da30bd1
--- /dev/null
+++ 
b/shardingsphere-agent/shardingsphere-agent-core/src/main/java/org/apache/shardingsphere/agent/core/plugin/Service.java
@@ -0,0 +1,40 @@
+/*
+ * 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.shardingsphere.agent.core.plugin;
+
+/**
+ * Service that the lifecycle is from the agent startup to shutdown.
+ */
+public interface Service {
+    
+    /**
+     * Setup the service, like to configure or to initial.
+     */
+    void setup();
+    
+    /**
+     * Start up the service.
+     */
+    void start();
+    
+    /**
+     * Cleanup the service.
+     */
+    void cleanup();
+}

Reply via email to