package io.cattle.platform.core.cleanup;
import io.cattle.platform.archaius.util.ArchaiusUtil;
import io.cattle.platform.core.constants.VolumeConstants;
import io.cattle.platform.core.dao.AccountDao;
import io.cattle.platform.core.dao.InstanceDao;
import io.cattle.platform.core.dao.IpAddressDao;
import io.cattle.platform.core.dao.NetworkDao;
import io.cattle.platform.core.dao.ServiceDao;
import io.cattle.platform.core.dao.StoragePoolDao;
import io.cattle.platform.core.dao.VolumeDao;
import io.cattle.platform.core.model.Instance;
import io.cattle.platform.core.model.InstanceLink;
import io.cattle.platform.core.model.Volume;
import io.cattle.platform.db.jooq.dao.impl.AbstractJooqDao;
import io.cattle.platform.engine.manager.ProcessNotFoundException;
import io.cattle.platform.engine.process.impl.ProcessCancelException;
import io.cattle.platform.object.ObjectManager;
import io.cattle.platform.object.process.ObjectProcessManager;
import io.cattle.platform.object.process.StandardProcess;
import io.cattle.platform.object.util.DataAccessor;
import io.cattle.platform.object.util.ObjectUtils;
import io.cattle.platform.task.Task;
import java.util.Collection;
import java.util.concurrent.ExecutorService;
import javax.inject.Inject;
import javax.inject.Named;
import org.apache.cloudstack.managed.context.NoExceptionRunnable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.netflix.config.DynamicIntProperty;
public class BadDataCleanup extends AbstractJooqDao implements Task {
private static final DynamicIntProperty LIMIT = ArchaiusUtil.getInt("bad.data.batch.size");
private static final Logger log = LoggerFactory.getLogger(BadDataCleanup.class);
@Inject
ObjectManager objectManager;
@Inject
ObjectProcessManager processManager;
@Inject
InstanceDao instanceDao;
@Inject
NetworkDao networkDao;
@Inject
StoragePoolDao storagePoolDao;
@Inject
AccountDao accountDao;
@Inject
VolumeDao volumeDao;
@Inject
IpAddressDao ipAddressDao;
@Inject
ServiceDao serviceDao;
@Inject
@Named("CoreExecutorService")
ExecutorService executorService;
@Override
public void run() {
for (final Instance instance : instanceDao.findBadInstances(LIMIT.get())) {
executorService.execute(new NoExceptionRunnable() {
@Override
protected void doRun() throws Exception {
log.warn("Removing invalid instance [{}]", ObjectUtils.toStringWrapper(instance));
processManager.scheduleStandardChainedProcessAsync(StandardProcess.STOP, StandardProcess.REMOVE, instance, null);
}
});
}
for (final Volume vol : volumeDao.findBadVolumes(LIMIT.get())) {
executorService.execute(new NoExceptionRunnable() {
@Override
protected void doRun() throws Exception {
log.warn("Removing invalid volume [{}]", ObjectUtils.toStringWrapper(vol));
if (VolumeConstants.STATE_DETACHED.equals(vol.getState())) {
processManager.scheduleStandardProcessAsync(StandardProcess.REMOVE, vol, null);
} else {
processManager.scheduleStandardChainedProcessAsync(StandardProcess.DEACTIVATE, StandardProcess.REMOVE, vol, null);
}
}
});
}
for (final Volume vol : volumeDao.findBadNativeVolumes(LIMIT.get())) {
executorService.execute(new NoExceptionRunnable() {
@Override
protected void doRun() throws Exception {
log.warn("Removing invalid volume [{}]", ObjectUtils.toStringWrapper(vol));
DataAccessor.setField(vol, VolumeConstants.FIELD_DOCKER_IS_NATIVE, true);
processManager.scheduleStandardChainedProcessAsync(StandardProcess.DEACTIVATE, StandardProcess.REMOVE, vol, null);
}
});
}
removeAll(instanceDao.findBadNics(LIMIT.get()));
removeAll(instanceDao.findBadInstanceHostMaps(LIMIT.get()));
removeAll(networkDao.findBadNetworks(LIMIT.get()));
removeAll(storagePoolDao.findBadPools(LIMIT.get()));
removeAll(storagePoolDao.findBadDockerPools(LIMIT.get()));
removeAll(accountDao.findBadGO(LIMIT.get()));
removeAll(accountDao.findBadUserPreference(LIMIT.get()));
removeAll(accountDao.findBadProjectMembers(LIMIT.get()));
removeAll(ipAddressDao.findBadHostIpAddress(LIMIT.get()));
removeAll(serviceDao.findBadHealthcheckInstance(LIMIT.get()));
removeAll(volumeDao.findBadMounts(LIMIT.get()));
removeAll(volumeDao.findBandVolumeStoragePoolMap(LIMIT.get()));
removeAll(storagePoolDao.findBadPoolMapss(LIMIT.get()));
for (InstanceLink link : instanceDao.findBadInstanceLinks(LIMIT.get())) {
log.warn("Removing invalid resource [{}]", ObjectUtils.toStringWrapper(link));
link.setTargetInstanceId(null);
objectManager.persist(link);
}
removeAll(volumeDao.findBadImages(LIMIT.get()));
removeAll(volumeDao.findBadImageStoragePoolMaps(LIMIT.get()));
}
protected void removeAll(Collection<?> objects) {
for (final Object obj : objects) {
executorService.execute(new NoExceptionRunnable() {
@Override
protected void doRun() throws Exception {
try {
log.warn("Removing invalid resource [{}]", ObjectUtils.toStringWrapper(obj));
processManager.scheduleStandardChainedProcessAsync(StandardProcess.DEACTIVATE, StandardProcess.REMOVE, obj, null);
} catch (ProcessNotFoundException e) {
processManager.scheduleStandardProcessAsync(StandardProcess.REMOVE, obj, null);
} catch (ProcessCancelException e) {
log.warn("Failed to schedule remove for [{}]: {}", ObjectUtils.toStringWrapper(obj), e.getMessage());
}
}
});
}
}
@Override
public String getName() {
return "bad.data";
}
}