package com.sequenceiq.cloudbreak.service.image;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import com.sequenceiq.cloudbreak.cloud.model.AmbariCatalog;
import com.sequenceiq.cloudbreak.cloud.model.CloudbreakImageCatalog;
import com.sequenceiq.cloudbreak.cloud.model.HDPInfo;
import com.sequenceiq.cloudbreak.core.CloudbreakImageNotFoundException;
@Service
public class HdpInfoSearchService {
private static final Logger LOGGER = LoggerFactory.getLogger(HdpInfoSearchService.class);
@Value("${info.app.version:}")
private String cbVersion;
@Inject
private ImageCatalogProvider imageCatalogProvider;
public HDPInfo searchHDPInfo(String platform, String ambariVersion, String hdpVersion, String imageCatalogUrl) throws CloudbreakImageNotFoundException {
HDPInfo hdpInfo = null;
if (ambariVersion != null && hdpVersion != null) {
CloudbreakImageCatalog imageCatalog = imageCatalogProvider.getImageCatalog(imageCatalogUrl);
hdpInfo = prefixSearch(imageCatalog, platform, cbVersion, ambariVersion, hdpVersion);
if (hdpInfo == null) {
throw new CloudbreakImageNotFoundException(
String.format("Failed to determine VM image from catalog! Cloudbreak version: %s, "
+ "Ambari version: %s, HDP Version: %s, Image Catalog Url: %s",
cbVersion, ambariVersion, hdpVersion,
imageCatalogUrl != null ? imageCatalogUrl : imageCatalogProvider.getDefaultCatalogUrl()));
}
}
return hdpInfo;
}
private List<AmbariCatalog> ambariPrefixMatch(CloudbreakImageCatalog imageCatalog, String platform, String cbVersion, String ambariVersion,
String hdpVersion) {
if (imageCatalog == null) {
return null;
}
List<AmbariCatalog> ambariCatalog;
if (StringUtils.isEmpty(cbVersion) || "unspecified".equals(cbVersion)) {
ambariCatalog = imageCatalog.getAmbariVersions().stream().collect(Collectors.toList());
} else {
ambariCatalog = imageCatalog.getAmbariVersions().stream().filter(p -> p.getAmbariInfo().getCbVersions().contains(cbVersion))
.collect(Collectors.toList());
if (CollectionUtils.isEmpty(ambariCatalog) && cbVersion.contains("dev")) {
ambariCatalog = imageCatalog.getAmbariVersions().stream().collect(Collectors.toList());
}
}
List<AmbariCatalog> ambariCatalogs = ambariCatalog.stream()
.filter(p -> p.getAmbariInfo().getVersion().startsWith(ambariVersion))
.filter(p -> p.getAmbariInfo().getHdp().stream().anyMatch(hdp -> hdp.getVersion().startsWith(hdpVersion)))
.filter(p -> p.getAmbariInfo().getHdp().stream().anyMatch(hdp -> hdp.getImages().containsKey(platform)))
.collect(Collectors.toList());
Collections.sort(ambariCatalogs, new VersionComparator());
LOGGER.info("Prefix matched Ambari versions: {}. Ambari search prefix: {}", ambariCatalogs, ambariVersion);
return ambariCatalogs;
}
private AmbariCatalog selectLatestAmbariCatalog(List<AmbariCatalog> ambariCatalogs) {
if (ambariCatalogs == null || ambariCatalogs.isEmpty()) {
return null;
}
return ambariCatalogs.get(ambariCatalogs.size() - 1);
}
private List<HDPInfo> hdpPrefixMatch(AmbariCatalog ambariCatalog, String hdpVersion) {
if (ambariCatalog == null) {
return null;
}
List<HDPInfo> hdpInfos = ambariCatalog.getAmbariInfo().getHdp().stream()
.filter(p -> p.getVersion().startsWith(hdpVersion)).collect(Collectors.toList());
Collections.sort(hdpInfos, new VersionComparator());
LOGGER.info("Prefix matched HDP versions: {} for Ambari version: {}. HDP search prefix: {}", hdpInfos, ambariCatalog.getVersion(), hdpVersion);
return hdpInfos;
}
private HDPInfo selectLatestHdpInfo(List<HDPInfo> hdpInfos) {
if (hdpInfos == null || hdpInfos.isEmpty()) {
return null;
}
return hdpInfos.get(hdpInfos.size() - 1);
}
private HDPInfo prefixSearch(CloudbreakImageCatalog imageCatalog, String platform, String cbVersion, String ambariVersion, String hdpVersion) {
List<AmbariCatalog> ambariCatalogs = ambariPrefixMatch(imageCatalog, platform, cbVersion, ambariVersion, hdpVersion);
AmbariCatalog ambariCatalog = selectLatestAmbariCatalog(ambariCatalogs);
List<HDPInfo> hdpInfos = hdpPrefixMatch(ambariCatalog, hdpVersion);
return selectLatestHdpInfo(hdpInfos);
}
}