package io.cattle.platform.object.purge.impl; import io.cattle.platform.deferred.util.DeferredUtils; 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.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.PurgeMonitor; 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.HashSet; import java.util.List; import java.util.Set; import javax.inject.Inject; import javax.inject.Named; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class PurgeMonitorImpl implements PurgeMonitor, Task { private static final Logger log = LoggerFactory.getLogger(PurgeMonitorImpl.class); SchemaFactory schemaFactory; ObjectProcessManager objectProcessManager; ObjectManager objectManager; ObjectMetaDataManager objectMetaDataManager; List<String> purgeTypes = null; String removedState = "removed"; ProcessManager processManager; @Override public String getName() { return "purge.resources"; } @Override public void run() { DeferredUtils.nest(new Runnable() { @Override public void run() { runInternal(); /* We only want purged to be ran as part of replay */ DeferredUtils.resetDeferred(); } }); } public void runInternal() { for (String type : findPurgableTypes()) { Class<?> schemaClass = schemaFactory.getSchemaClass(type); if (schemaClass == null) { continue; } List<?> objects = objectManager.find(schemaClass, ObjectMetaDataManager.STATE_FIELD, removedState, ObjectMetaDataManager.REMOVED_FIELD, new Condition(ConditionType.NOTNULL), ObjectMetaDataManager.REMOVE_TIME_FIELD, new Condition(ConditionType.LT, new Date())); for (Object obj : objects) { try { objectProcessManager.scheduleStandardProcess(StandardProcess.PURGE, obj, null); log.debug("Scheduling purge for [{}] id [{}]", type, ObjectUtils.getId(obj)); } catch (ProcessNotFoundException e) { } catch (ProcessInstanceException e) { log.info("Failed to scheduling purge for [{}] id [{}]", type, ObjectUtils.getId(obj), e); } } } } protected synchronized Set<String> findPurgableTypes() { 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; } Object fieldObj = objectMetaDataManager.convertFieldNameFor(type, ObjectMetaDataManager.REMOVED_FIELD); if (fieldObj == null) { /* This means there is no DB table with a removed field */ continue; } String processName = objectProcessManager.getStandardProcessName(StandardProcess.PURGE, type); ProcessDefinition def = processManager.getProcessDefinition(processName); if (def != null) { types.add(type); } } return types; } public SchemaFactory getSchemaFactory() { return schemaFactory; } @Inject @Named("CoreSchemaFactory") public void setSchemaFactory(SchemaFactory schemaFactory) { this.schemaFactory = schemaFactory; } public ObjectMetaDataManager getObjectMetaDataManager() { return objectMetaDataManager; } @Inject public void setObjectMetaDataManager(ObjectMetaDataManager objectMetaDataManager) { this.objectMetaDataManager = objectMetaDataManager; } public ObjectManager getObjectManager() { return objectManager; } @Inject public void setObjectManager(ObjectManager objectManager) { this.objectManager = objectManager; } public String getRemovedState() { return removedState; } public void setRemovedState(String removedState) { this.removedState = removedState; } public ObjectProcessManager getObjectProcessManager() { return objectProcessManager; } @Inject public void setObjectProcessManager(ObjectProcessManager objectProcessManager) { this.objectProcessManager = objectProcessManager; } public ProcessManager getProcessManager() { return processManager; } @Inject public void setProcessManager(ProcessManager processManager) { this.processManager = processManager; } }