private static void validateRequiredExtensions(StackInfo stack, ExtensionInfo extension) throws AmbariException {
    for (ExtensionMetainfoXml.Extension requiredExtension : extension.getExtensions()) {
      if (requiredExtension != null) {
        String message = "Stack has not linked required extension"
                    + ", stackName=" + stack.getName()
                    + ", stackVersion=" + stack.getVersion()
                    + ", extensionName=" + extension.getName()
                    + ", extensionVersion=" + extension.getVersion()
                    + ", requiredExtensionName=" + requiredExtension.getName()
                    + ", requiredExtensionVersion=" + requiredExtension.getVersion();
        try {
          ExtensionInfo stackExtension = stack.getExtension(requiredExtension.getName());
          if (stackExtension != null) {
            String version = requiredExtension.getVersion();
            if (version.endsWith("*")) {
              version = version.substring(0, version.length() - 1);
              if (!stackExtension.getVersion().startsWith(version)) {
                throw new AmbariException(message);
              }
            }
            else if (!stackExtension.getVersion().equals(version)) {
              throw new AmbariException(message);
            }
          }
        }
        catch (Exception e) {
          throw new AmbariException(message, e);
        }
      }
    }
  }
An extension version is like a stack version but it contains custom services.  Linking an extension
version to the current stack version allows the cluster to install the custom services contained in
the extension version.
ambari-server/src/main/java/org/apache/ambari/server/stack/ExtensionHelper.java