package io.cattle.platform.allocator.constraint;
import io.cattle.platform.allocator.dao.AllocatorDao;
import io.cattle.platform.allocator.service.AllocationAttempt;
import io.cattle.platform.allocator.service.AllocationLog;
import io.cattle.platform.core.constants.InstanceConstants;
import io.cattle.platform.core.constants.VolumeConstants;
import io.cattle.platform.core.dao.GenericMapDao;
import io.cattle.platform.core.dao.StoragePoolDao;
import io.cattle.platform.core.model.Host;
import io.cattle.platform.core.model.Instance;
import io.cattle.platform.core.model.StoragePool;
import io.cattle.platform.core.model.Volume;
import io.cattle.platform.object.ObjectManager;
import io.cattle.platform.object.util.DataAccessor;
import io.cattle.platform.util.type.Priority;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
import org.apache.commons.lang3.StringUtils;
public class BaseConstraintsProvider implements AllocationConstraintsProvider, Priority {
@Inject
AllocatorDao allocatorDao;
@Inject
ObjectManager objectManager;
@Inject
GenericMapDao mapDao;
@Inject
StoragePoolDao storagePoolDao;
@Override
public void appendConstraints(AllocationAttempt attempt, AllocationLog log, List<Constraint> constraints) {
populateConstraints(attempt, log);
}
protected void populateConstraints(AllocationAttempt attempt, AllocationLog log) {
List<Constraint> constraints = attempt.getConstraints();
addLogConstraints(attempt, log);
addComputeConstraints(attempt, constraints);
addStorageConstraints(attempt, constraints);
}
protected void addLogConstraints(AllocationAttempt attempt, AllocationLog log) {
}
protected void addComputeConstraints(AllocationAttempt attempt, List<Constraint> constraints) {
ValidHostsConstraint hostSet = new ValidHostsConstraint();
if (attempt.getHostId() != null) {
hostSet.addHost(attempt.getHostId());
}
if (attempt.getRequestedHostId() != null) {
hostSet.addHost(attempt.getRequestedHostId());
}
if (hostSet.getHosts().size() > 0) {
constraints.add(hostSet);
}
}
protected void addStorageConstraints(AllocationAttempt attempt, List<Constraint> constraints) {
for (Map.Entry<Volume, Set<StoragePool>> entry : attempt.getPools().entrySet()) {
Volume volume = entry.getKey();
boolean alreadyMappedToPool = entry.getValue().size() > 0;
Set<Long> storagePoolIds = new HashSet<>();
for (StoragePool pool : entry.getValue()) {
storagePoolIds.add(pool.getId());
storagePoolToHostConstraint(constraints, pool);
}
boolean restrictToUnmanagedPool = false;
if (!alreadyMappedToPool) {
String driver = DataAccessor.fieldString(volume, VolumeConstants.FIELD_VOLUME_DRIVER);
restrictToUnmanagedPool = true;
if (StringUtils.isNotEmpty(driver) && !VolumeConstants.LOCAL_DRIVER.equals(driver)) {
List<? extends StoragePool> pools = storagePoolDao.findStoragePoolByDriverName(volume.getAccountId(), driver);
if (pools.size() > 0) {
Set<Long> poolIds = new HashSet<>();
for (StoragePool pool : pools) {
poolIds.add(pool.getId());
}
constraints.add(new VolumeValidStoragePoolConstraint(volume, false, poolIds));
storagePoolToHostConstraint(constraints, pools);
restrictToUnmanagedPool = false;
}
}
Instance instance = objectManager.loadResource(Instance.class, volume.getInstanceId());
if (instance != null) {
Host host = allocatorDao.getHost(instance);
if (host != null) {
for (StoragePool pool : allocatorDao.getAssociatedUnmanagedPools(host)) {
storagePoolIds.add(pool.getId());
}
}
}
}
if (storagePoolIds.size() > 0) {
constraints.add(new VolumeValidStoragePoolConstraint(volume, alreadyMappedToPool, storagePoolIds));
}
if (restrictToUnmanagedPool || volume.getImageId() != null) {
constraints.add(new UnmanagedStoragePoolKindConstraint(volume));
}
}
for (Instance instance : attempt.getInstances()) {
String driver = DataAccessor.fieldString(instance, InstanceConstants.FIELD_VOLUME_DRIVER);
if (StringUtils.isNotEmpty(driver) && !VolumeConstants.LOCAL_DRIVER.equals(driver)) {
List<? extends StoragePool> pools = storagePoolDao.findStoragePoolByDriverName(instance.getAccountId(), driver);
if (pools.size() > 0) {
storagePoolToHostConstraint(constraints, pools.get(0));
}
}
}
}
void storagePoolToHostConstraint(List<Constraint> constraints, Collection<? extends StoragePool> pools) {
ValidHostsConstraint hostSet = new ValidHostsConstraint();
for (Host host : allocatorDao.getHosts(pools)) {
hostSet.addHost(host.getId());
}
constraints.add(hostSet);
}
void storagePoolToHostConstraint(List<Constraint> constraints, StoragePool pool) {
Set<StoragePool> p = new HashSet<>();
p.add(pool);
storagePoolToHostConstraint(constraints, p);
}
@Override
public int getPriority() {
return Priority.PRE;
}
@Override
public boolean isCritical() {
return true;
}
}