package com.sequenceiq.cloudbreak.service.cluster.filter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.databind.JsonNode;
import com.sequenceiq.cloudbreak.domain.HostMetadata;
import com.sequenceiq.cloudbreak.service.cluster.ConfigParam;
import com.sequenceiq.cloudbreak.util.JsonUtil;
@Component
public class AppMasterFilter implements HostFilter {
private static final String AM_KEY = "amHostHttpAddress";
private static final String APPS_NODE = "apps";
private static final String APP_NODE = "app";
@Inject
private Client restClient;
@Override
@SuppressWarnings("unchecked")
public List<HostMetadata> filter(long clusterId, Map<String, String> config, List<HostMetadata> hosts) throws HostFilterException {
List<HostMetadata> result = new ArrayList<>(hosts);
try {
String resourceManagerAddress = config.get(ConfigParam.YARN_RM_WEB_ADDRESS.key());
WebTarget target = restClient.target("http://" + resourceManagerAddress + HostFilterService.RM_WS_PATH).path("apps").queryParam("state", "RUNNING");
String appResponse = target.request(MediaType.APPLICATION_JSON).get(String.class);
JsonNode jsonNode = JsonUtil.readTree(appResponse);
JsonNode apps = jsonNode.get(APPS_NODE);
if (apps != null && apps.has(APP_NODE)) {
JsonNode app = apps.get(APP_NODE);
Set<String> hostsWithAM = new HashSet<>();
for (JsonNode node : app) {
String hostName = node.get(AM_KEY).textValue();
hostsWithAM.add(hostName.substring(0, hostName.lastIndexOf(':')));
}
result = filter(hostsWithAM, result);
}
} catch (Exception e) {
throw new HostFilterException("Error filtering based on ApplicationMaster location", e);
}
return result;
}
private List<HostMetadata> filter(Set<String> hostsWithAM, List<HostMetadata> hosts) {
Iterator<HostMetadata> iterator = hosts.iterator();
while (iterator.hasNext()) {
HostMetadata host = iterator.next();
if (hostsWithAM.contains(host.getHostName())) {
iterator.remove();
}
}
return hosts;
}
}