in gateway-discovery-ambari/src/main/java/org/apache/knox/gateway/topology/discovery/ambari/AmbariServiceDiscovery.java [199:327]
public Cluster discover(GatewayConfig gatewayConfig, ServiceDiscoveryConfig config, String clusterName) {
AmbariCluster cluster = null;
String discoveryAddress = config.getAddress();
String discoveryUser = config.getUser();
String discoveryPwdAlias = config.getPasswordAlias();
// Handle missing discovery address value with the default if it has been defined
if (discoveryAddress == null || discoveryAddress.isEmpty()) {
discoveryAddress = gatewayConfig.getDefaultDiscoveryAddress();
// If no default address could be determined
if (discoveryAddress == null) {
log.missingDiscoveryAddress();
}
}
// Handle missing discovery cluster value with the default if it has been defined
if (clusterName == null || clusterName.isEmpty()) {
clusterName = gatewayConfig.getDefaultDiscoveryCluster();
// If no default cluster could be determined
if (clusterName == null) {
log.missingDiscoveryCluster();
}
}
// There must be a discovery address and cluster or discovery cannot be performed
if (discoveryAddress != null && clusterName != null) {
cluster = new AmbariCluster(clusterName);
String encodedClusterName;
try {
encodedClusterName = URLEncoder.encode(clusterName, StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException e) {
e.printStackTrace(); // TODO: Logging
encodedClusterName = clusterName;
}
Map<String, String> serviceComponents = new HashMap<>();
init(gatewayConfig);
Map<String, List<String>> componentHostNames = new HashMap<>();
String hostRolesURL =
String.format(Locale.ROOT, "%s" + AMBARI_HOSTROLES_URI, discoveryAddress, encodedClusterName);
JSONObject hostRolesJSON = restClient.invoke(hostRolesURL, discoveryUser, discoveryPwdAlias);
if (hostRolesJSON != null) {
// Process the host roles JSON
JSONArray items = (JSONArray) hostRolesJSON.get("items");
for (Object obj : items) {
JSONArray components = (JSONArray) ((JSONObject) obj).get("components");
for (Object component : components) {
JSONArray hostComponents = (JSONArray) ((JSONObject) component).get("host_components");
for (Object hostComponent : hostComponents) {
JSONObject hostRoles = (JSONObject) ((JSONObject) hostComponent).get("HostRoles");
String serviceName = (String) hostRoles.get("service_name");
String componentName = (String) hostRoles.get("component_name");
serviceComponents.put(componentName, serviceName);
// Assuming public host name is more applicable than host_name
String hostName = (String) hostRoles.get("public_host_name");
if (hostName == null) {
// Some (even slightly) older versions of Ambari/HDP do not return public_host_name,
// so fall back to host_name in those cases.
hostName = (String) hostRoles.get("host_name");
}
if (hostName != null) {
log.discoveredServiceHost(serviceName, hostName);
if (!componentHostNames.containsKey(componentName)) {
componentHostNames.put(componentName, new ArrayList<>());
}
// Avoid duplicates
if (!componentHostNames.get(componentName).contains(hostName)) {
componentHostNames.get(componentName).add(hostName);
}
}
}
}
}
}
// Service configurations
Map<String, Map<String, AmbariCluster.ServiceConfiguration>> serviceConfigurations =
ambariClient.getActiveServiceConfigurations(discoveryAddress,
encodedClusterName,
discoveryUser,
discoveryPwdAlias);
if (serviceConfigurations.isEmpty()) {
log.failedToAccessServiceConfigs(clusterName);
}
for (Entry<String, Map<String, AmbariCluster.ServiceConfiguration>> serviceConfiguration : serviceConfigurations.entrySet()) {
for (Map.Entry<String, AmbariCluster.ServiceConfiguration> serviceConfig : serviceConfiguration.getValue().entrySet()) {
cluster.addServiceConfiguration(serviceConfiguration.getKey(), serviceConfig.getKey(), serviceConfig.getValue());
}
}
// Construct the AmbariCluster model
for (Entry<String, String> entry : serviceComponents.entrySet()) {
String componentName = entry.getKey();
String serviceName = entry.getValue();
List<String> hostNames = componentHostNames.get(componentName);
Map<String, AmbariCluster.ServiceConfiguration> configs = serviceConfigurations.get(serviceName);
String configType = componentServiceConfigs.get(componentName);
if (configType != null) {
AmbariCluster.ServiceConfiguration svcConfig = configs.get(configType);
if (svcConfig != null) {
AmbariComponent c = new AmbariComponent(componentName,
svcConfig.getVersion(),
encodedClusterName,
serviceName,
hostNames,
svcConfig.getProperties());
cluster.addComponent(c);
}
}
}
if (configChangeMonitor != null) {
// Notify the cluster config monitor about these cluster configuration details
configChangeMonitor.addClusterConfigVersions(cluster, config);
}
}
return cluster;
}