You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@skywalking.apache.org by wu...@apache.org on 2018/07/19 14:43:22 UTC

[incubator-skywalking] branch 6.0 updated: Restore module management.

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

wusheng pushed a commit to branch 6.0
in repository https://gitbox.apache.org/repos/asf/incubator-skywalking.git


The following commit(s) were added to refs/heads/6.0 by this push:
     new e05b99a  Restore module management.
e05b99a is described below

commit e05b99a9366582f396b86c032a4ba9d8a9cabca7
Author: Wu Sheng <wu...@foxmail.com>
AuthorDate: Thu Jul 19 22:43:14 2018 +0800

    Restore module management.
---
 .../ClusterModuleStandaloneProvider.java           |   5 +
 .../zookeeper/ClusterModuleZookeeperProvider.java  |   5 +
 .../oap/server/core/cluster/ClusterModule.java     |  37 -------
 .../oap/server/core/CoreModuleProvider.java        |   5 +
 .../oap/server/core/cluster/ModuleQuery.java       |   3 +-
 oap-server/server-library/library-module/pom.xml   |   8 ++
 .../library/module/ApplicationConfiguration.java   |  15 ++-
 .../oap/server/library/module/BootstrapFlow.java   | 118 +++++++++++++++++++++
 ...xception.java => CycleDependencyException.java} |   8 +-
 .../library/module/DuplicateProviderException.java |   1 +
 .../library/module/ModuleConfigException.java      |   4 -
 .../oap/server/library/module/ModuleDefine.java    |  53 +++++----
 .../oap/server/library/module/ModuleManager.java   |  65 ++++++++++--
 .../library/module/ModuleNotFoundException.java    |   1 +
 .../module/ModuleNotFoundRuntimeException.java     |   5 +
 .../oap/server/library/module/ModuleProvider.java  |  13 ++-
 .../oap/server/library/module/Service.java         |   3 +-
 .../module/ServiceNotProvidedRuntimeException.java |   3 +-
 .../oap/server/library/module/BaseModuleA.java     |   4 +-
 .../oap/server/library/module/BaseModuleB.java     |   4 +-
 .../oap/server/library/module/ModuleAProvider.java |   2 +-
 .../oap/server/starter/ModuleManagerImpl.java      |  75 -------------
 .../oap/server/starter/OAPServerStartUp.java       |  18 +---
 .../starter/config/ApplicationConfigLoader.java    |  39 ++++++-
 .../config/ConfigFileNotFoundException.java        |   2 +
 .../oap/server/starter/config/ConfigLoader.java    |   1 +
 .../StorageModuleElasticsearchProvider.java        |  23 ++--
 27 files changed, 332 insertions(+), 188 deletions(-)

diff --git a/oap-server/server-cluster-plugin/cluster-standalone-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/standalone/ClusterModuleStandaloneProvider.java b/oap-server/server-cluster-plugin/cluster-standalone-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/standalone/ClusterModuleStandaloneProvider.java
index fddd3f5..a6f4bef 100644
--- a/oap-server/server-cluster-plugin/cluster-standalone-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/standalone/ClusterModuleStandaloneProvider.java
+++ b/oap-server/server-cluster-plugin/cluster-standalone-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/standalone/ClusterModuleStandaloneProvider.java
@@ -58,4 +58,9 @@ public class ClusterModuleStandaloneProvider extends ModuleProvider {
 
     @Override public void notifyAfterCompleted() {
     }
+
+    @Override
+    public String[] requiredModules() {
+        return new String[0];
+    }
 }
diff --git a/oap-server/server-cluster-plugin/cluster-zookeeper-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/zookeeper/ClusterModuleZookeeperProvider.java b/oap-server/server-cluster-plugin/cluster-zookeeper-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/zookeeper/ClusterModuleZookeeperProvider.java
index 031c9ab..0c52a81 100644
--- a/oap-server/server-cluster-plugin/cluster-zookeeper-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/zookeeper/ClusterModuleZookeeperProvider.java
+++ b/oap-server/server-cluster-plugin/cluster-zookeeper-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/zookeeper/ClusterModuleZookeeperProvider.java
@@ -83,4 +83,9 @@ public class ClusterModuleZookeeperProvider extends ModuleProvider {
 
     @Override public void notifyAfterCompleted() {
     }
+
+    @Override
+    public String[] requiredModules() {
+        return new String[0];
+    }
 }
diff --git a/oap-server/server-core/core-cluster/src/main/java/org/apache/skywalking/oap/server/core/cluster/ClusterModule.java b/oap-server/server-core/core-cluster/src/main/java/org/apache/skywalking/oap/server/core/cluster/ClusterModule.java
deleted file mode 100644
index 992ed10..0000000
--- a/oap-server/server-core/core-cluster/src/main/java/org/apache/skywalking/oap/server/core/cluster/ClusterModule.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.skywalking.oap.server.core.cluster;
-
-import org.apache.skywalking.oap.server.library.module.ModuleDefine;
-
-/**
- * @author peng-yongsheng
- */
-public class ClusterModule extends ModuleDefine {
-
-    public static final String NAME = "cluster";
-
-    @Override public String name() {
-        return NAME;
-    }
-
-    @Override public Class[] services() {
-        return new Class[] {ModuleRegister.class, ModuleQuery.class};
-    }
-}
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 030742a..6a8ca4f 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
@@ -89,4 +89,9 @@ public class CoreModuleProvider extends ModuleProvider {
         restServerInstance.setContextPath(moduleConfig.getRestContextPath());
         this.getManager().find(ClusterModule.NAME).getService(ModuleRegister.class).register(CoreModule.NAME, "rest", restServerInstance);
     }
+
+    @Override
+    public String[] requiredModules() {
+        return new String[0];
+    }
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/cluster/ModuleQuery.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/cluster/ModuleQuery.java
index b3a4746..d44532a 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/cluster/ModuleQuery.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/cluster/ModuleQuery.java
@@ -18,9 +18,10 @@
 
 package org.apache.skywalking.oap.server.core.cluster;
 
-import java.util.List;
 import org.apache.skywalking.oap.server.library.module.Service;
 
+import java.util.List;
+
 /**
  * @author peng-yongsheng
  */
diff --git a/oap-server/server-library/library-module/pom.xml b/oap-server/server-library/library-module/pom.xml
index beeaa10..6df06f1 100644
--- a/oap-server/server-library/library-module/pom.xml
+++ b/oap-server/server-library/library-module/pom.xml
@@ -29,4 +29,12 @@
 
     <artifactId>library-module</artifactId>
     <packaging>jar</packaging>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.skywalking</groupId>
+            <artifactId>library-util</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
 </project>
\ No newline at end of file
diff --git a/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ApplicationConfiguration.java b/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ApplicationConfiguration.java
index ca685e9..0fe2d94 100644
--- a/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ApplicationConfiguration.java
+++ b/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ApplicationConfiguration.java
@@ -16,18 +16,19 @@
  *
  */
 
+
 package org.apache.skywalking.oap.server.library.module;
 
-import java.util.*;
+import java.util.HashMap;
+import java.util.Properties;
 
 /**
- * Modularization configurations. The {@link ModuleManager} is going to start, lookup, start modules based on this.
+ * Modulization configurations. The {@link ModuleManager} is going to start, lookup, start modules based on this.
  *
  * @author wu-sheng, peng-yongsheng
  */
 public class ApplicationConfiguration {
-
-    private final Map<String, ModuleConfiguration> modules = new HashMap<>();
+    private HashMap<String, ModuleConfiguration> modules = new HashMap<>();
 
     public String[] moduleList() {
         return modules.keySet().toArray(new String[0]);
@@ -51,7 +52,7 @@ public class ApplicationConfiguration {
      * The configurations about a certain module.
      */
     public class ModuleConfiguration {
-        private final Map<String, ProviderConfiguration> providers = new HashMap<>();
+        private HashMap<String, ProviderConfiguration> providers = new HashMap<>();
 
         private ModuleConfiguration() {
         }
@@ -64,10 +65,6 @@ public class ApplicationConfiguration {
             return providers.containsKey(name);
         }
 
-        public String[] providerList() {
-            return providers.keySet().toArray(new String[0]);
-        }
-
         public ModuleConfiguration addProviderConfiguration(String name, Properties properties) {
             ProviderConfiguration newProvider = new ProviderConfiguration(properties);
             providers.put(name, newProvider);
diff --git a/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/BootstrapFlow.java b/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/BootstrapFlow.java
new file mode 100644
index 0000000..187575f
--- /dev/null
+++ b/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/BootstrapFlow.java
@@ -0,0 +1,118 @@
+/*
+ * 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.skywalking.oap.server.library.module;
+
+import org.apache.skywalking.oap.server.library.util.CollectionUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author wu-sheng, peng-yongsheng
+ */
+class BootstrapFlow {
+    private static final Logger logger = LoggerFactory.getLogger(BootstrapFlow.class);
+
+    private Map<String, ModuleDefine> loadedModules;
+    private List<ModuleProvider> startupSequence;
+
+    BootstrapFlow(Map<String, ModuleDefine> loadedModules) throws CycleDependencyException {
+        this.loadedModules = loadedModules;
+        startupSequence = new LinkedList<>();
+
+        makeSequence();
+    }
+
+    @SuppressWarnings("unchecked")
+    void start(
+        ModuleManager moduleManager) throws ModuleNotFoundException, ServiceNotProvidedException, ModuleStartException {
+        for (ModuleProvider provider : startupSequence) {
+            String[] requiredModules = provider.requiredModules();
+            if (requiredModules != null) {
+                for (String module : requiredModules) {
+                    if (!moduleManager.has(module)) {
+                        throw new ModuleNotFoundException(module + " is required by " + provider.getModuleName()
+                            + "." + provider.name() + ", but not found.");
+                    }
+                }
+            }
+            logger.info("start the provider {} in {} module.", provider.name(), provider.getModuleName());
+            provider.requiredCheck(provider.getModule().services());
+
+            provider.start();
+        }
+    }
+
+    void notifyAfterCompleted() throws ServiceNotProvidedException {
+        for (ModuleProvider provider : startupSequence) {
+            provider.notifyAfterCompleted();
+        }
+    }
+
+    private void makeSequence() throws CycleDependencyException {
+        List<ModuleProvider> allProviders = new ArrayList<>();
+        loadedModules.forEach((moduleName, module) -> allProviders.addAll(module.providers()));
+
+        do {
+            int numOfToBeSequenced = allProviders.size();
+            for (int i = 0; i < allProviders.size(); i++) {
+                ModuleProvider provider = allProviders.get(i);
+                String[] requiredModules = provider.requiredModules();
+                if (CollectionUtils.isNotEmpty(requiredModules)) {
+                    boolean isAllRequiredModuleStarted = true;
+                    for (String module : requiredModules) {
+                        // find module in all ready existed startupSequence
+                        boolean exist = false;
+                        for (ModuleProvider moduleProvider : startupSequence) {
+                            if (moduleProvider.getModuleName().equals(module)) {
+                                exist = true;
+                                break;
+                            }
+                        }
+                        if (!exist) {
+                            isAllRequiredModuleStarted = false;
+                            break;
+                        }
+                    }
+
+                    if (isAllRequiredModuleStarted) {
+                        startupSequence.add(provider);
+                        allProviders.remove(i);
+                        i--;
+                    }
+                } else {
+                    startupSequence.add(provider);
+                    allProviders.remove(i);
+                    i--;
+                }
+            }
+
+            if (numOfToBeSequenced == allProviders.size()) {
+                StringBuilder unSequencedProviders = new StringBuilder();
+                allProviders.forEach(provider -> unSequencedProviders.append(provider.getModuleName()).append("[provider=").append(provider.getClass().getName()).append("]\n"));
+                throw new CycleDependencyException("Exist cycle module dependencies in \n" + unSequencedProviders.substring(0, unSequencedProviders.length() - 1));
+            }
+        }
+        while (allProviders.size() != 0);
+    }
+}
diff --git a/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/DuplicateProviderException.java b/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/CycleDependencyException.java
similarity index 85%
copy from oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/DuplicateProviderException.java
copy to oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/CycleDependencyException.java
index bf9c0c4..0897120 100644
--- a/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/DuplicateProviderException.java
+++ b/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/CycleDependencyException.java
@@ -16,10 +16,14 @@
  *
  */
 
+
 package org.apache.skywalking.oap.server.library.module;
 
-public class DuplicateProviderException extends Exception {
-    public DuplicateProviderException(String message) {
+/**
+ * @author wu-sheng
+ */
+public class CycleDependencyException extends RuntimeException {
+    public CycleDependencyException(String message) {
         super(message);
     }
 }
diff --git a/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/DuplicateProviderException.java b/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/DuplicateProviderException.java
index bf9c0c4..c313267 100644
--- a/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/DuplicateProviderException.java
+++ b/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/DuplicateProviderException.java
@@ -16,6 +16,7 @@
  *
  */
 
+
 package org.apache.skywalking.oap.server.library.module;
 
 public class DuplicateProviderException extends Exception {
diff --git a/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ModuleConfigException.java b/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ModuleConfigException.java
index 79ee829..428f1cb 100644
--- a/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ModuleConfigException.java
+++ b/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ModuleConfigException.java
@@ -23,10 +23,6 @@ package org.apache.skywalking.oap.server.library.module;
  */
 public class ModuleConfigException extends Exception {
 
-    public ModuleConfigException(String message) {
-        super(message);
-    }
-
     public ModuleConfigException(String message, Throwable cause) {
         super(message, cause);
     }
diff --git a/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ModuleDefine.java b/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ModuleDefine.java
index 04e5da7..3f6a80c 100644
--- a/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ModuleDefine.java
+++ b/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ModuleDefine.java
@@ -18,9 +18,11 @@
 
 package org.apache.skywalking.oap.server.library.module;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import java.lang.reflect.Field;
 import java.util.*;
-import org.slf4j.*;
 
 /**
  * A module definition.
@@ -29,9 +31,9 @@ import org.slf4j.*;
  */
 public abstract class ModuleDefine {
 
-    private static final Logger logger = LoggerFactory.getLogger(ModuleDefine.class);
+    private final Logger logger = LoggerFactory.getLogger(ModuleDefine.class);
 
-    private ModuleProvider moduleProvider;
+    private LinkedList<ModuleProvider> loadedProviders = new LinkedList<>();
 
     /**
      * @return the module name
@@ -50,13 +52,9 @@ public abstract class ModuleDefine {
      * @param configuration of this module
      * @throws ProviderNotFoundException when even don't find a single one providers.
      */
-    public void prepare(ModuleManager moduleManager,
+    void prepare(ModuleManager moduleManager,
         ApplicationConfiguration.ModuleConfiguration configuration) throws ProviderNotFoundException, ServiceNotProvidedException, ModuleConfigException {
         ServiceLoader<ModuleProvider> moduleProviderLoader = ServiceLoader.load(ModuleProvider.class);
-        if (configuration.providerList().length != 1) {
-            throw new ModuleConfigException("Just a single provider configuration allowed to open in one module.");
-        }
-
         boolean providerExist = false;
         for (ModuleProvider provider : moduleProviderLoader) {
             if (!configuration.has(provider.name())) {
@@ -65,13 +63,15 @@ public abstract class ModuleDefine {
 
             providerExist = true;
             if (provider.module().equals(getClass())) {
+                ModuleProvider newProvider;
                 try {
-                    moduleProvider = provider.getClass().newInstance();
+                    newProvider = provider.getClass().newInstance();
                 } catch (InstantiationException | IllegalAccessException e) {
                     throw new ProviderNotFoundException(e);
                 }
-                moduleProvider.setManager(moduleManager);
-                moduleProvider.setModule(this);
+                newProvider.setManager(moduleManager);
+                newProvider.setModule(this);
+                loadedProviders.add(newProvider);
             }
         }
 
@@ -79,13 +79,15 @@ public abstract class ModuleDefine {
             throw new ProviderNotFoundException(this.name() + " module no provider exists.");
         }
 
-        logger.info("Prepare the {} provider in {} module.", moduleProvider.name(), this.name());
-        try {
-            copyProperties(moduleProvider.createConfigBeanIfAbsent(), configuration.getProviderConfiguration(moduleProvider.name()), this.name(), moduleProvider.name());
-        } catch (IllegalAccessException e) {
-            throw new ModuleConfigException(this.name() + " module config transport to config bean failure.", e);
+        for (ModuleProvider moduleProvider : loadedProviders) {
+            logger.info("Prepare the {} provider in {} module.", moduleProvider.name(), this.name());
+            try {
+                copyProperties(moduleProvider.createConfigBeanIfAbsent(), configuration.getProviderConfiguration(moduleProvider.name()), this.name(), moduleProvider.name());
+            } catch (IllegalAccessException e) {
+                throw new ModuleConfigException(this.name() + " module config transport to config bean failure.", e);
+            }
+            moduleProvider.prepare();
         }
-        moduleProvider.prepare();
     }
 
     private void copyProperties(ModuleConfig dest, Properties src, String moduleName,
@@ -119,14 +121,25 @@ public abstract class ModuleDefine {
         throw new NoSuchFieldException();
     }
 
-    public final ModuleProvider provider() {
-        return moduleProvider;
+    /**
+     * @return providers of this module
+     */
+    final List<ModuleProvider> providers() {
+        return loadedProviders;
+    }
+
+    final ModuleProvider provider() throws DuplicateProviderException {
+        if (loadedProviders.size() > 1) {
+            throw new DuplicateProviderException(this.name() + " module exist " + loadedProviders.size() + " providers");
+        }
+
+        return loadedProviders.getFirst();
     }
 
     public final <T extends Service> T getService(Class<T> serviceType) throws ServiceNotProvidedRuntimeException {
         try {
             return provider().getService(serviceType);
-        } catch (ServiceNotProvidedException e) {
+        } catch (DuplicateProviderException | ServiceNotProvidedException e) {
             throw new ServiceNotProvidedRuntimeException(e.getMessage());
         }
     }
diff --git a/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ModuleManager.java b/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ModuleManager.java
index 6e9aba9..02f09dc 100644
--- a/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ModuleManager.java
+++ b/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ModuleManager.java
@@ -18,15 +18,68 @@
 
 package org.apache.skywalking.oap.server.library.module;
 
+import java.util.*;
+
 /**
- * @author peng-yongsheng
+ * The <code>ModuleManager</code> takes charge of all {@link ModuleDefine}s in collector.
+ *
+ * @author wu-sheng, peng-yongsheng
  */
-public interface ModuleManager {
+public class ModuleManager {
+    private boolean isInPrepareStage = true;
+    private Map<String, ModuleDefine> loadedModules = new HashMap<>();
+
+    /**
+     * Init the given modules
+     */
+    public void init(
+        ApplicationConfiguration applicationConfiguration) throws ModuleNotFoundException, ProviderNotFoundException, ServiceNotProvidedException, CycleDependencyException, ModuleConfigException, ModuleStartException {
+        String[] moduleNames = applicationConfiguration.moduleList();
+        ServiceLoader<ModuleDefine> moduleServiceLoader = ServiceLoader.load(ModuleDefine.class);
+        LinkedList<String> moduleList = new LinkedList<>(Arrays.asList(moduleNames));
+        for (ModuleDefine module : moduleServiceLoader) {
+            for (String moduleName : moduleNames) {
+                if (moduleName.equals(module.name())) {
+                    ModuleDefine newInstance;
+                    try {
+                        newInstance = module.getClass().newInstance();
+                    } catch (InstantiationException | IllegalAccessException e) {
+                        throw new ModuleNotFoundException(e);
+                    }
+                    newInstance.prepare(this, applicationConfiguration.getModuleConfiguration(moduleName));
+                    loadedModules.put(moduleName, newInstance);
+                    moduleList.remove(moduleName);
+                }
+            }
+        }
+        // Finish prepare stage
+        isInPrepareStage = false;
+
+        if (moduleList.size() > 0) {
+            throw new ModuleNotFoundException(moduleList.toString() + " missing.");
+        }
+
+        BootstrapFlow bootstrapFlow = new BootstrapFlow(loadedModules);
+
+        bootstrapFlow.start(this);
+        bootstrapFlow.notifyAfterCompleted();
+    }
 
-    void init(
-        ModuleDefine moduleDefine) throws ServiceNotProvidedException, ModuleConfigException, ProviderNotFoundException;
+    public boolean has(String moduleName) {
+        return loadedModules.get(moduleName) != null;
+    }
 
-    void start() throws ServiceNotProvidedException, ModuleConfigException, ProviderNotFoundException, ModuleStartException;
+    public ModuleDefine find(String moduleName) throws ModuleNotFoundRuntimeException {
+        assertPreparedStage();
+        ModuleDefine module = loadedModules.get(moduleName);
+        if (module != null)
+            return module;
+        throw new ModuleNotFoundRuntimeException(moduleName + " missing.");
+    }
 
-    ModuleDefine find(String moduleName) throws ModuleNotFoundRuntimeException;
+    private void assertPreparedStage() {
+        if (isInPrepareStage) {
+            throw new AssertionError("Still in preparing stage.");
+        }
+    }
 }
diff --git a/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ModuleNotFoundException.java b/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ModuleNotFoundException.java
index 3ca8e68..6564c87 100644
--- a/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ModuleNotFoundException.java
+++ b/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ModuleNotFoundException.java
@@ -16,6 +16,7 @@
  *
  */
 
+
 package org.apache.skywalking.oap.server.library.module;
 
 public class ModuleNotFoundException extends Exception {
diff --git a/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ModuleNotFoundRuntimeException.java b/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ModuleNotFoundRuntimeException.java
index 2ca0c0c..1dbb591 100644
--- a/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ModuleNotFoundRuntimeException.java
+++ b/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ModuleNotFoundRuntimeException.java
@@ -16,6 +16,7 @@
  *
  */
 
+
 package org.apache.skywalking.oap.server.library.module;
 
 /**
@@ -23,6 +24,10 @@ package org.apache.skywalking.oap.server.library.module;
  */
 public class ModuleNotFoundRuntimeException extends RuntimeException {
 
+    public ModuleNotFoundRuntimeException(Throwable cause) {
+        super(cause);
+    }
+
     public ModuleNotFoundRuntimeException(String message) {
         super(message);
     }
diff --git a/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ModuleProvider.java b/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ModuleProvider.java
index f7d4b51..8e9e659 100644
--- a/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ModuleProvider.java
+++ b/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ModuleProvider.java
@@ -18,7 +18,8 @@
 
 package org.apache.skywalking.oap.server.library.module;
 
-import java.util.*;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * The <code>ModuleProvider</code> is an implementation of a {@link ModuleDefine}.
@@ -55,7 +56,7 @@ public abstract class ModuleProvider {
     /**
      * @return the module name
      */
-    public abstract Class module();
+    public abstract Class<? extends ModuleDefine> module();
 
     /**
      * @return ModuleConfig
@@ -78,6 +79,11 @@ public abstract class ModuleProvider {
     public abstract void notifyAfterCompleted() throws ServiceNotProvidedException;
 
     /**
+     * @return module names which does this module require?
+     */
+    public abstract String[] requiredModules();
+
+    /**
      * Register a implementation for the service of this module provider.
      */
     protected final void registerServiceImplementation(Class<? extends Service> serviceType,
@@ -110,8 +116,7 @@ public abstract class ModuleProvider {
         }
     }
 
-    @SuppressWarnings("unchecked")
-    public <T extends Service> T getService(
+    @SuppressWarnings("unchecked") <T extends Service> T getService(
         Class<T> serviceType) throws ServiceNotProvidedException {
         Service serviceImpl = services.get(serviceType);
         if (serviceImpl != null) {
diff --git a/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/Service.java b/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/Service.java
index 18547ce..4061202 100644
--- a/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/Service.java
+++ b/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/Service.java
@@ -16,6 +16,7 @@
  *
  */
 
+
 package org.apache.skywalking.oap.server.library.module;
 
 /**
@@ -26,4 +27,4 @@ package org.apache.skywalking.oap.server.library.module;
  * @author wu-sheng
  */
 public interface Service {
-}
\ No newline at end of file
+}
diff --git a/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ServiceNotProvidedRuntimeException.java b/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ServiceNotProvidedRuntimeException.java
index 0135376..340ed78 100644
--- a/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ServiceNotProvidedRuntimeException.java
+++ b/oap-server/server-library/library-module/src/main/java/org/apache/skywalking/oap/server/library/module/ServiceNotProvidedRuntimeException.java
@@ -16,10 +16,11 @@
  *
  */
 
+
 package org.apache.skywalking.oap.server.library.module;
 
 public class ServiceNotProvidedRuntimeException extends RuntimeException {
     public ServiceNotProvidedRuntimeException(String message) {
         super(message);
     }
-}
\ No newline at end of file
+}
diff --git a/oap-server/server-library/library-module/src/test/java/org/apache/skywalking/oap/server/library/module/BaseModuleA.java b/oap-server/server-library/library-module/src/test/java/org/apache/skywalking/oap/server/library/module/BaseModuleA.java
index ebf50a2..74124a2 100644
--- a/oap-server/server-library/library-module/src/test/java/org/apache/skywalking/oap/server/library/module/BaseModuleA.java
+++ b/oap-server/server-library/library-module/src/test/java/org/apache/skywalking/oap/server/library/module/BaseModuleA.java
@@ -33,11 +33,11 @@ public class BaseModuleA extends ModuleDefine {
         return new Class[] {ServiceABusiness1.class, ServiceABusiness2.class};
     }
 
-    public interface ServiceABusiness1 extends Service {
+    public interface ServiceABusiness1 {
         void print();
     }
 
-    public interface ServiceABusiness2 extends Service {
+    public interface ServiceABusiness2 {
 
     }
 }
diff --git a/oap-server/server-library/library-module/src/test/java/org/apache/skywalking/oap/server/library/module/BaseModuleB.java b/oap-server/server-library/library-module/src/test/java/org/apache/skywalking/oap/server/library/module/BaseModuleB.java
index 1f56a87..18a2fae 100644
--- a/oap-server/server-library/library-module/src/test/java/org/apache/skywalking/oap/server/library/module/BaseModuleB.java
+++ b/oap-server/server-library/library-module/src/test/java/org/apache/skywalking/oap/server/library/module/BaseModuleB.java
@@ -33,11 +33,11 @@ public class BaseModuleB extends ModuleDefine {
         return new Class[] {BaseModuleB.ServiceBBusiness1.class, BaseModuleB.ServiceBBusiness2.class};
     }
 
-    public interface ServiceBBusiness1 extends Service {
+    public interface ServiceBBusiness1 {
 
     }
 
-    public interface ServiceBBusiness2 extends Service {
+    public interface ServiceBBusiness2 {
 
     }
 }
diff --git a/oap-server/server-library/library-module/src/test/java/org/apache/skywalking/oap/server/library/module/ModuleAProvider.java b/oap-server/server-library/library-module/src/test/java/org/apache/skywalking/oap/server/library/module/ModuleAProvider.java
index 52c3b78..8f3d6e4 100644
--- a/oap-server/server-library/library-module/src/test/java/org/apache/skywalking/oap/server/library/module/ModuleAProvider.java
+++ b/oap-server/server-library/library-module/src/test/java/org/apache/skywalking/oap/server/library/module/ModuleAProvider.java
@@ -53,7 +53,7 @@ public class ModuleAProvider extends ModuleProvider {
     @Override public void notifyAfterCompleted() {
     }
 
-    public class Config extends ModuleConfig {
+    public class Config {
         private String host;
 
         public String getHost() {
diff --git a/oap-server/server-starter/src/main/java/org/apache/skywalking/oap/server/starter/ModuleManagerImpl.java b/oap-server/server-starter/src/main/java/org/apache/skywalking/oap/server/starter/ModuleManagerImpl.java
deleted file mode 100644
index 1448e70..0000000
--- a/oap-server/server-starter/src/main/java/org/apache/skywalking/oap/server/starter/ModuleManagerImpl.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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.skywalking.oap.server.starter;
-
-import java.util.*;
-import org.apache.skywalking.oap.server.core.CoreModule;
-import org.apache.skywalking.oap.server.core.cluster.ClusterModule;
-import org.apache.skywalking.oap.server.core.storage.StorageModule;
-import org.apache.skywalking.oap.server.library.module.*;
-
-/**
- * @author peng-yongsheng
- */
-public class ModuleManagerImpl implements ModuleManager {
-
-    private final ApplicationConfiguration applicationConfiguration;
-    private final Map<String, ModuleDefine> modules;
-
-    public ModuleManagerImpl(ApplicationConfiguration applicationConfiguration) {
-        this.applicationConfiguration = applicationConfiguration;
-        this.modules = new HashMap<>();
-    }
-
-    @Override
-    public void start() throws ServiceNotProvidedException, ModuleConfigException, ProviderNotFoundException, ModuleStartException {
-        CoreModule coreModule = new CoreModule();
-        ClusterModule clusterModule = new ClusterModule();
-        StorageModule storageModule = new StorageModule();
-
-        init(coreModule);
-        init(clusterModule);
-        init(storageModule);
-
-        coreModule.provider().start();
-        storageModule.provider().start();
-        clusterModule.provider().start();
-
-        coreModule.provider().notifyAfterCompleted();
-        storageModule.provider().notifyAfterCompleted();
-        clusterModule.provider().notifyAfterCompleted();
-    }
-
-    @Override public void init(
-        ModuleDefine moduleDefine) throws ServiceNotProvidedException, ModuleConfigException, ProviderNotFoundException {
-        if (!applicationConfiguration.has(moduleDefine.name())) {
-            throw new ModuleConfigException("Can't found core module configuration, please check the application.yml file.");
-        }
-
-        moduleDefine.prepare(this, applicationConfiguration.getModuleConfiguration(moduleDefine.name()));
-        modules.put(moduleDefine.name(), moduleDefine);
-    }
-
-    @Override public ModuleDefine find(String moduleName) throws ModuleNotFoundRuntimeException {
-        ModuleDefine module = modules.get(moduleName);
-        if (module != null)
-            return module;
-        throw new ModuleNotFoundRuntimeException(moduleName + " missing.");
-    }
-}
diff --git a/oap-server/server-starter/src/main/java/org/apache/skywalking/oap/server/starter/OAPServerStartUp.java b/oap-server/server-starter/src/main/java/org/apache/skywalking/oap/server/starter/OAPServerStartUp.java
index 668aa5e..f1e4219 100644
--- a/oap-server/server-starter/src/main/java/org/apache/skywalking/oap/server/starter/OAPServerStartUp.java
+++ b/oap-server/server-starter/src/main/java/org/apache/skywalking/oap/server/starter/OAPServerStartUp.java
@@ -18,9 +18,9 @@
 
 package org.apache.skywalking.oap.server.starter;
 
-import java.util.concurrent.TimeUnit;
-import org.apache.skywalking.oap.server.library.module.ApplicationConfiguration;
+import org.apache.skywalking.oap.server.library.module.*;
 import org.apache.skywalking.oap.server.starter.config.ApplicationConfigLoader;
+import org.apache.skywalking.oap.server.starter.config.ConfigFileNotFoundException;
 import org.slf4j.*;
 
 /**
@@ -32,21 +32,13 @@ public class OAPServerStartUp {
 
     public static void main(String[] args) {
         ApplicationConfigLoader configLoader = new ApplicationConfigLoader();
-
+        ModuleManager manager = new ModuleManager();
         try {
             ApplicationConfiguration applicationConfiguration = configLoader.load();
-            ModuleManagerImpl moduleManager = new ModuleManagerImpl(applicationConfiguration);
-            moduleManager.start();
-        } catch (Throwable e) {
+            manager.init(applicationConfiguration);
+        } catch (ConfigFileNotFoundException | ModuleNotFoundException | ProviderNotFoundException | ServiceNotProvidedException | ModuleConfigException | ModuleStartException e) {
             logger.error(e.getMessage(), e);
             System.exit(1);
         }
-
-        logger.info("OAP server start up successful.");
-        try {
-            TimeUnit.MINUTES.sleep(5);
-        } catch (InterruptedException e) {
-            e.printStackTrace();
-        }
     }
 }
diff --git a/oap-server/server-starter/src/main/java/org/apache/skywalking/oap/server/starter/config/ApplicationConfigLoader.java b/oap-server/server-starter/src/main/java/org/apache/skywalking/oap/server/starter/config/ApplicationConfigLoader.java
index 4c40ae8..ea4caff 100644
--- a/oap-server/server-starter/src/main/java/org/apache/skywalking/oap/server/starter/config/ApplicationConfigLoader.java
+++ b/oap-server/server-starter/src/main/java/org/apache/skywalking/oap/server/starter/config/ApplicationConfigLoader.java
@@ -18,13 +18,18 @@
 
 package org.apache.skywalking.oap.server.starter.config;
 
-import java.io.*;
-import java.util.*;
 import org.apache.skywalking.oap.server.library.module.ApplicationConfiguration;
-import org.apache.skywalking.oap.server.library.util.*;
-import org.slf4j.*;
+import org.apache.skywalking.oap.server.library.util.CollectionUtils;
+import org.apache.skywalking.oap.server.library.util.ResourceUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.yaml.snakeyaml.Yaml;
 
+import java.io.FileNotFoundException;
+import java.io.Reader;
+import java.util.Map;
+import java.util.Properties;
+
 /**
  * Initialize collector settings with following sources.
  * Use application.yml as primary setting,
@@ -43,6 +48,7 @@ public class ApplicationConfigLoader implements ConfigLoader<ApplicationConfigur
     @Override public ApplicationConfiguration load() throws ConfigFileNotFoundException {
         ApplicationConfiguration configuration = new ApplicationConfiguration();
         this.loadConfig(configuration);
+        this.loadDefaultConfig(configuration);
         this.overrideConfigBySystemEnv(configuration);
         return configuration;
     }
@@ -78,6 +84,31 @@ public class ApplicationConfigLoader implements ConfigLoader<ApplicationConfigur
         }
     }
 
+    @SuppressWarnings("unchecked")
+    private void loadDefaultConfig(ApplicationConfiguration configuration) throws ConfigFileNotFoundException {
+        try {
+            Reader applicationReader = ResourceUtils.read("application-default.yml");
+            Map<String, Map<String, Map<String, ?>>> moduleConfig = yaml.loadAs(applicationReader, Map.class);
+            if (CollectionUtils.isNotEmpty(moduleConfig)) {
+                moduleConfig.forEach((moduleName, providerConfig) -> {
+                    if (!configuration.has(moduleName)) {
+                        logger.warn("The {} module did't define in application.yml, use default", moduleName);
+                        ApplicationConfiguration.ModuleConfiguration moduleConfiguration = configuration.addModule(moduleName);
+                        providerConfig.forEach((name, propertiesConfig) -> {
+                            Properties properties = new Properties();
+                            if (propertiesConfig != null) {
+                                propertiesConfig.forEach(properties::put);
+                            }
+                            moduleConfiguration.addProviderConfiguration(name, properties);
+                        });
+                    }
+                });
+            }
+        } catch (FileNotFoundException e) {
+            throw new ConfigFileNotFoundException(e.getMessage(), e);
+        }
+    }
+
     private void overrideConfigBySystemEnv(ApplicationConfiguration configuration) {
         for (Map.Entry<Object, Object> prop : System.getProperties().entrySet()) {
             overrideModuleSettings(configuration, prop.getKey().toString(), prop.getValue().toString());
diff --git a/oap-server/server-starter/src/main/java/org/apache/skywalking/oap/server/starter/config/ConfigFileNotFoundException.java b/oap-server/server-starter/src/main/java/org/apache/skywalking/oap/server/starter/config/ConfigFileNotFoundException.java
index 1c79e03..c4fc8fb 100644
--- a/oap-server/server-starter/src/main/java/org/apache/skywalking/oap/server/starter/config/ConfigFileNotFoundException.java
+++ b/oap-server/server-starter/src/main/java/org/apache/skywalking/oap/server/starter/config/ConfigFileNotFoundException.java
@@ -16,8 +16,10 @@
  *
  */
 
+
 package org.apache.skywalking.oap.server.starter.config;
 
+
 /**
  * @author peng-yongsheng
  */
diff --git a/oap-server/server-starter/src/main/java/org/apache/skywalking/oap/server/starter/config/ConfigLoader.java b/oap-server/server-starter/src/main/java/org/apache/skywalking/oap/server/starter/config/ConfigLoader.java
index 790afa8..2345984 100644
--- a/oap-server/server-starter/src/main/java/org/apache/skywalking/oap/server/starter/config/ConfigLoader.java
+++ b/oap-server/server-starter/src/main/java/org/apache/skywalking/oap/server/starter/config/ConfigLoader.java
@@ -16,6 +16,7 @@
  *
  */
 
+
 package org.apache.skywalking.oap.server.starter.config;
 
 /**
diff --git a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/StorageModuleElasticsearchProvider.java b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/StorageModuleElasticsearchProvider.java
index 2a7a875..23367a5 100644
--- a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/StorageModuleElasticsearchProvider.java
+++ b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/StorageModuleElasticsearchProvider.java
@@ -36,24 +36,35 @@ public class StorageModuleElasticsearchProvider extends ModuleProvider {
         this.storageConfig = new StorageModuleElasticsearchConfig();
     }
 
-    @Override public String name() {
+    @Override
+    public String name() {
         return "elasticsearch";
     }
 
-    @Override public Class module() {
+    @Override
+    public Class module() {
         return StorageModule.class;
     }
 
-    @Override public ModuleConfig createConfigBeanIfAbsent() {
+    @Override
+    public ModuleConfig createConfigBeanIfAbsent() {
         return storageConfig;
     }
 
-    @Override public void prepare() throws ServiceNotProvidedException {
+    @Override
+    public void prepare() throws ServiceNotProvidedException {
     }
 
-    @Override public void start() throws ModuleStartException {
+    @Override
+    public void start() throws ModuleStartException {
     }
 
-    @Override public void notifyAfterCompleted() {
+    @Override
+    public void notifyAfterCompleted() {
+    }
+
+    @Override
+    public String[] requiredModules() {
+        return new String[0];
     }
 }