private static void validateServicesNotInstalled(Clusters clusters, StackInfo stack, ExtensionInfo extension) throws AmbariException {
    for (Cluster cluster : clusters.getClusters().values()) {
      for (ServiceInfo service : extension.getServices()) {
        try {
          if (service != null && cluster.getService(service.getName()) != null) {
            String message = "Extension service is still installed"
                        + ", stackName=" + stack.getName()
                        + ", stackVersion=" + stack.getVersion()
                        + ", service=" + service.getName()
                        + ", extensionName=" + extension.getName()
                        + ", extensionVersion=" + extension.getVersion();

            throw new AmbariException(message);
          }
        }
        catch (ServiceNotFoundException e) {
          //Eat the exception
        }
      }
    }
  }
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