package io.cattle.platform.process.driver;
import io.cattle.platform.core.constants.CommonStatesConstants;
import io.cattle.platform.core.constants.ServiceConstants;
import io.cattle.platform.core.dao.GenericResourceDao;
import io.cattle.platform.core.model.Service;
import io.cattle.platform.core.model.Stack;
import io.cattle.platform.engine.handler.AbstractProcessLogic;
import io.cattle.platform.engine.handler.HandlerResult;
import io.cattle.platform.engine.handler.ProcessPreListener;
import io.cattle.platform.engine.process.ProcessInstance;
import io.cattle.platform.engine.process.ProcessState;
import io.cattle.platform.json.JsonMapper;
import io.cattle.platform.lock.LockCallbackNoReturn;
import io.cattle.platform.lock.LockManager;
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.util.DataAccessor;
import io.cattle.platform.object.util.ObjectUtils;
import io.cattle.platform.process.lock.DriverLock;
import io.cattle.platform.util.type.CollectionUtils;
import java.util.Collections;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Named;
@Named
public class DriverServiceActivate extends AbstractProcessLogic implements ProcessPreListener {
public static String[] DRIVERS = new String[]{"networkDriver", "storageDriver"};
@Inject
JsonMapper jsonMapper;
@Inject
LockManager lockManager;
@Inject
ObjectManager objectManager;
@Inject
ObjectProcessManager processManager;
@Inject
GenericResourceDao resourceDao;
@Override
public String[] getProcessNames() {
return new String[]{"service.create", "service.update", "service.activate"};
}
@Override
public HandlerResult handle(ProcessState state, ProcessInstance process) {
final Service service = (Service)state.getResource();
for (final String driverKey : DRIVERS) {
@SuppressWarnings("unchecked")
final Map<String, Object> driverMap = DataAccessor.fields(service).withKey(driverKey)
.withDefault(Collections.EMPTY_MAP).as(Map.class);
if (driverMap.size() == 0) {
continue;
}
Stack stack = objectManager.loadResource(Stack.class, service.getStackId());
if (stack == null) {
continue;
}
if (ServiceConstants.isSystem(stack)) {
lockManager.lock(new DriverLock(service, driverKey), new LockCallbackNoReturn() {
@Override
public void doWithLockNoResult() {
addDriver(driverKey, service, driverMap);
}
});
}
}
return null;
}
protected Object findDriver(String driverKey, Service service, Map<String, Object> fields) {
Class<?> driverClass = objectManager.getSchemaFactory().getSchemaClass(driverKey);
return objectManager.findAny(driverClass,
"serviceId", service.getId(),
ObjectMetaDataManager.REMOVED_FIELD, null);
}
protected void addDriver(String driverKey, Service service, Map<String, Object> fields) {
Object driver = findDriver(driverKey, service, fields);
if (driver == null) {
driver = createDriver(driverKey, service, fields);
}
if (!CommonStatesConstants.ACTIVE.equals(ObjectUtils.getState(driver))) {
processManager.scheduleStandardProcessAsync(StandardProcess.ACTIVATE, driver, null);
}
}
protected String getString(Map<String, Object> fields, String field) {
return DataAccessor.fromMap(fields).withKey(field).as(String.class);
}
private Object createDriver(String driverKey, Service service, Map<String, Object> fields) {
Class<?> driverClass = objectManager.getSchemaFactory().getSchemaClass(driverKey);
String name = getString(fields, ObjectMetaDataManager.NAME_FIELD);
if (name == null) {
name = service.getName();
}
Map<String, Object> data = CollectionUtils.asMap("fields", fields);
return objectManager.create(driverClass,
ObjectMetaDataManager.NAME_FIELD, name,
ObjectMetaDataManager.ACCOUNT_FIELD, service.getAccountId(),
"serviceId", service.getId(),
ObjectMetaDataManager.DATA_FIELD, data);
}
}