package io.cattle.platform.object.purge.impl;
import io.cattle.platform.archaius.util.ArchaiusUtil;
import io.cattle.platform.engine.manager.ProcessManager;
import io.cattle.platform.engine.manager.ProcessNotFoundException;
import io.cattle.platform.engine.process.ProcessDefinition;
import io.cattle.platform.engine.process.ProcessInstanceException;
import io.cattle.platform.engine.process.util.ProcessEngineUtils;
import io.cattle.platform.object.ObjectManager;
import io.cattle.platform.object.meta.ObjectMetaDataManager;
import io.cattle.platform.object.process.ObjectProcessManager;
import io.cattle.platform.object.process.StandardProcess;
import io.cattle.platform.object.purge.RemoveMonitor;
import io.cattle.platform.object.util.ObjectUtils;
import io.cattle.platform.task.Task;
import io.github.ibuildthecloud.gdapi.condition.Condition;
import io.github.ibuildthecloud.gdapi.condition.ConditionType;
import io.github.ibuildthecloud.gdapi.factory.SchemaFactory;
import io.github.ibuildthecloud.gdapi.model.Schema;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Named;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.netflix.config.DynamicLongProperty;
public class RemoveMonitorImpl implements RemoveMonitor, Task {
@Inject
@Named("CoreSchemaFactory")
SchemaFactory schemaFactory;
@Inject
ObjectMetaDataManager objectMetaDataManager;
@Inject
ObjectProcessManager objectProcessManager;
@Inject
ProcessManager processManager;
@Inject
ObjectManager objectManager;
private static final String ERROR_STATE = "error";
private static final Logger log = LoggerFactory.getLogger(RemoveMonitorImpl.class);
private static final DynamicLongProperty REMOVE_DELAY = ArchaiusUtil.getLong("remove.resources.after");
@Override
public void run() {
if (!ProcessEngineUtils.enabled()) {
return;
}
for (String type : findRemovableTypes()) {
Class<?> schemaClass = schemaFactory.getSchemaClass(type);
if (schemaClass == null) {
continue;
}
List<?> objects = objectManager.find(schemaClass, ObjectMetaDataManager.STATE_FIELD, ERROR_STATE,
ObjectMetaDataManager.CREATED_FIELD,
new Condition(ConditionType.NOTNULL), ObjectMetaDataManager.CREATED_FIELD, new Condition(
ConditionType.LT, new Date(System.currentTimeMillis() - REMOVE_DELAY.get() * 1000)));
for (Object obj : objects) {
try {
Map<String, Object> data = new HashMap<>();
data.put("errorState", true);
objectProcessManager.scheduleStandardProcess(StandardProcess.REMOVE, obj, data);
log.info("Scheduling remove for [{}] id [{}]", type, ObjectUtils.getId(obj));
} catch (ProcessNotFoundException e) {
} catch (ProcessInstanceException e) {
log.info("Failed to scheduling remove for [{}] id [{}]", type, ObjectUtils.getId(obj), e);
}
}
}
}
@Override
public String getName() {
return "remove.resources";
}
protected synchronized Set<String> findRemovableTypes() {
Set<String> types = new HashSet<String>();
for (Schema schema : schemaFactory.listSchemas()) {
while (schema.getParent() != null) {
schema = schemaFactory.getSchema(schema.getParent());
}
String type = schema.getId();
if (types.contains(type)) {
continue;
}
// restricting it to instance for now
if (!type.equalsIgnoreCase("instance")) {
continue;
}
Object stateField = objectMetaDataManager.convertFieldNameFor(type, ObjectMetaDataManager.STATE_FIELD);
if (stateField == null) {
continue;
}
String processName = objectProcessManager.getStandardProcessName(StandardProcess.REMOVE, type);
ProcessDefinition def = processManager.getProcessDefinition(processName);
if (def != null) {
types.add(type);
}
}
return types;
}
}