package org.ovirt.engine.core.bll; import static java.util.stream.Collectors.toList; import static java.util.stream.StreamSupport.stream; import java.util.ArrayList; import java.util.List; import javax.enterprise.inject.Any; import javax.enterprise.inject.Instance; import javax.inject.Inject; import org.ovirt.engine.core.common.businessentities.Cluster; import org.ovirt.engine.core.common.businessentities.ClusterEditWarnings; import org.ovirt.engine.core.common.businessentities.Nameable; import org.ovirt.engine.core.common.businessentities.VDS; import org.ovirt.engine.core.common.businessentities.VM; import org.ovirt.engine.core.common.interfaces.BackendLocal; import org.ovirt.engine.core.common.queries.ClusterEditParameters; import org.ovirt.engine.core.common.queries.VdcQueryType; import org.ovirt.engine.core.dao.VdsDao; import org.ovirt.engine.core.dao.VmDao; public class GetClusterEditWarningsQuery<P extends ClusterEditParameters> extends QueriesCommandBase<P> { @Inject private VdsDao vdsDao; @Inject private VmDao vmDao; @Inject @Any private Instance<ClusterEditChecker<VDS>> hostCheckers; @Inject @Any private Instance<ClusterEditChecker<VM>> vmCheckers; @Inject private BackendLocal backend; public GetClusterEditWarningsQuery(P parameters) { super(parameters); } @Override protected void executeQueryCommand() { final Cluster oldCluster = backend.runQuery(VdcQueryType.GetClusterById, getParameters()).getReturnValue(); Cluster newCluster = getParameters().getNewCluster(); List<ClusterEditWarnings.Warning> hostWarnings = getProblematicEntities(oldCluster, newCluster, hostCheckers, cluster -> vdsDao.getAllForCluster(cluster.getId())); List<ClusterEditWarnings.Warning> vmWarnings = new ArrayList<>(); if (oldCluster.supportsVirtService() && newCluster.supportsVirtService()) { vmWarnings = getProblematicEntities(oldCluster, newCluster, vmCheckers, cluster -> vmDao.getAllForCluster(cluster.getId())); } setReturnValue(new ClusterEditWarnings(hostWarnings, vmWarnings)); } private static <T extends Nameable> List<ClusterEditWarnings.Warning> getProblematicEntities( Cluster oldCluster, Cluster newCluster, Iterable<ClusterEditChecker<T>> checkers, ClusterEntityResolver<T> entityResolver) { List<ClusterEditWarnings.Warning> warnings = new ArrayList<>(); List<ClusterEditChecker<T>> applicableChecks = stream(checkers.spliterator(), false) .filter(checker -> checker.isApplicable(oldCluster, newCluster)) .collect(toList()); if (!applicableChecks.isEmpty()) { List<T> entities = entityResolver.getClusterEntities(oldCluster); for (ClusterEditChecker<T> checker : applicableChecks) { ClusterEditWarnings.Warning warning = new ClusterEditWarnings.Warning(checker.getMainMessage()); entities.stream().filter(entity -> !checker.check(entity)).forEach(entity -> warning.getDetailsByName().put(entity.getName(), checker.getDetailMessage(entity))); if (!warning.isEmpty()) { warnings.add(warning); } } } return warnings; } @FunctionalInterface private interface ClusterEntityResolver<T> { List<T> getClusterEntities(Cluster cluster); } }