package org.ovirt.engine.core.bll.migration;
import static java.util.function.Function.identity;
import static java.util.stream.Collectors.toMap;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.inject.Singleton;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.type.CollectionType;
import org.ovirt.engine.core.common.config.Config;
import org.ovirt.engine.core.common.config.ConfigValues;
import org.ovirt.engine.core.common.migration.MigrationPolicy;
import org.ovirt.engine.core.common.migration.NoMigrationPolicy;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.compat.Version;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Singleton
public class ConvergenceConfigProvider {
/** Compatibility version to policy ID to policy */
private Map<Version, Map<Guid, MigrationPolicy>> migrationPoliciesByVersion = new HashMap<>();
protected Logger log = LoggerFactory.getLogger(getClass());
@PostConstruct
public void initialize() {
for (Version version : Version.ALL) {
initMigrationPolicies(Config.getValue(ConfigValues.MigrationPolicies, version.toString()), version);
}
}
private Map<Guid, MigrationPolicy> getMigrationPolicies(Version version) {
Map<Guid, MigrationPolicy> migrationPolicies = migrationPoliciesByVersion.get(version);
if (migrationPolicies == null) {
migrationPolicies = Collections.singletonMap(NoMigrationPolicy.ID, new NoMigrationPolicy());
}
return migrationPolicies;
}
public Map<Version, List<MigrationPolicy>> getAllMigrationPolicies() {
Map<Version, List<MigrationPolicy>> result = new HashMap<>();
for (Version version : Version.ALL) {
result.put(version, new ArrayList<>(getMigrationPolicies(version).values()));
}
return result;
}
public MigrationPolicy getMigrationPolicy(Guid id, Version compatibilityVersion) {
Map<Guid, MigrationPolicy> migrationPolicies = getMigrationPolicies(compatibilityVersion);
if (migrationPolicies.containsKey(id)) {
return migrationPolicies.get(id);
} else {
// this can happen since there is no guarantee on the cluster object that the policy is not going to be
// deleted later on. In that case return the "no policy".
return migrationPolicies.get(NoMigrationPolicy.ID);
}
}
void initMigrationPolicies(String policiesStr, Version version) {
List<MigrationPolicy> policies = Collections.emptyList();
try {
policies = parse(policiesStr);
} catch (IOException e) {
log.error("The provided migration policies: '{}' are not valid, ignoring", policiesStr);
}
// init it to an empty map even the parsing failed
Map<Guid, MigrationPolicy> migrationPolicies =
policies.stream().collect(toMap(MigrationPolicy::getId, identity()));
// the null object
migrationPolicies.put(NoMigrationPolicy.ID, new NoMigrationPolicy());
migrationPoliciesByVersion.put(version, migrationPolicies);
}
List<MigrationPolicy> parse(String policy) throws IOException {
ObjectMapper mapper = new ObjectMapper();
CollectionType type = mapper.getTypeFactory().constructCollectionType(List.class, MigrationPolicy.class);
return mapper.readValue(policy, type);
}
}