private Map<String, ExtensionModule> parseExtensionDirectory(File extensionRoot) throws AmbariException {
    Map<String, ExtensionModule> extensionModules = new HashMap<>();
    if (extensionRoot == null || !extensionRoot.exists()) {
      return extensionModules;
    }

    File[] extensionFiles = extensionRoot.listFiles(StackDirectory.FILENAME_FILTER);
    for (File extensionNameFolder : extensionFiles) {
      if (extensionNameFolder.isFile()) {
        continue;
      }
      for (File extensionVersionFolder : extensionNameFolder.listFiles(StackDirectory.FILENAME_FILTER)) {
        if (extensionVersionFolder.isFile()) {
          continue;
        }
        String extensionName = extensionNameFolder.getName();
        String extensionVersion = extensionVersionFolder.getName();

        ExtensionModule extensionModule = new ExtensionModule(new ExtensionDirectory(extensionVersionFolder.getPath()), stackContext);
        String extensionKey = extensionName + StackManager.PATH_DELIMITER + extensionVersion;
        extensionModules.put(extensionKey, extensionModule);
        extensionMap.put(extensionKey, extensionModule.getModuleInfo());
      }
    }

    if (stackMap.isEmpty()) {
      throw new AmbariException("Unable to find extension definitions under " +
          "extensionRoot = " + extensionRoot.getAbsolutePath());
    }
    return extensionModules;
  }
Parse the specified extension root directory

@param extensionRoot  the extension root directory to parse
@return map of extension id which contains name and version to extension module.
@throws AmbariException if unable to parse all extensions
ambari-server/src/main/java/org/apache/ambari/server/stack/StackManager.java