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); } }