package com.sequenceiq.cloudbreak.cloud.init;
import static com.sequenceiq.cloudbreak.cloud.model.Platform.platform;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import com.google.common.base.Strings;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.sequenceiq.cloudbreak.cloud.CloudConnector;
import com.sequenceiq.cloudbreak.cloud.model.CloudPlatformVariant;
import com.sequenceiq.cloudbreak.cloud.model.Platform;
import com.sequenceiq.cloudbreak.cloud.model.PlatformVariants;
import com.sequenceiq.cloudbreak.cloud.model.Variant;
@Component
public class CloudPlatformConnectors {
private static final Logger LOGGER = LoggerFactory.getLogger(CloudPlatformConnectors.class);
@Value("${cb.platform.default.variants:}")
private String platformDefaultVariants;
private Map<Platform, Variant> defaultVariants = new HashMap<>();
@Inject
private List<CloudConnector> cloudConnectors;
private Map<CloudPlatformVariant, CloudConnector> map = new HashMap<>();
private Multimap<Platform, Variant> platformToVariants;
@PostConstruct
public void cloudPlatformConnectors() {
platformToVariants = HashMultimap.create();
for (CloudConnector connector : cloudConnectors) {
map.put(new CloudPlatformVariant(connector.platform(), connector.variant()), connector);
platformToVariants.put(connector.platform(), connector.variant());
}
Map<Platform, Variant> environmentDefaults = extractEnvironmentDefaultVariants();
setupDefaultVariants(platformToVariants, environmentDefaults);
LOGGER.debug(map.toString());
LOGGER.debug(defaultVariants.toString());
}
private Map<Platform, Variant> extractEnvironmentDefaultVariants() {
return toMap(platformDefaultVariants);
}
private Map<Platform, Variant> toMap(String s) {
Map<Platform, Variant> result = Maps.newHashMap();
if (!Strings.isNullOrEmpty(s)) {
for (String entry : s.split(",")) {
String[] keyValue = entry.split(":");
result.put(platform(keyValue[0]), Variant.variant(keyValue[1]));
}
}
return result;
}
private void setupDefaultVariants(Multimap<Platform, Variant> platformToVariants, Map<Platform, Variant> environmentDefaults) {
for (Map.Entry<Platform, Collection<Variant>> platformVariants : platformToVariants.asMap().entrySet()) {
if (platformVariants.getValue().size() == 1) {
defaultVariants.put(platformVariants.getKey(), platformVariants.getValue().toArray(new Variant[]{})[0]);
} else {
if (platformVariants.getValue().contains(environmentDefaults.get(platformVariants.getKey()))) {
defaultVariants.put(platformVariants.getKey(), environmentDefaults.get(platformVariants.getKey()));
} else {
throw new IllegalStateException(String.format("No default variant is specified for platform: '%s'", platformVariants.getKey()));
}
}
}
}
public Variant getDefaultVariant(Platform platform) {
return defaultVariants.get(platform);
}
public CloudConnector getDefault(Platform platform) {
Variant variant = getDefaultVariant(platform);
return map.get(new CloudPlatformVariant(platform, variant));
}
public CloudConnector get(Platform platform, Variant variant) {
return get(new CloudPlatformVariant(platform, variant));
}
public CloudConnector get(CloudPlatformVariant variant) {
CloudConnector cc = map.get(variant);
return cc == null ? getDefault(variant.getPlatform()) : cc;
}
public PlatformVariants getPlatformVariants() {
return new PlatformVariants(platformToVariants.asMap(), defaultVariants);
}
}