package io.cattle.platform.servicediscovery.api.filter; import static io.cattle.platform.core.model.tables.ServiceTable.*; import io.cattle.platform.core.constants.InstanceConstants; import io.cattle.platform.core.constants.ServiceConstants; import io.cattle.platform.core.dao.NetworkDao; import io.cattle.platform.core.model.Service; import io.cattle.platform.core.model.Stack; import io.cattle.platform.iaas.api.filter.common.AbstractDefaultResourceManagerFilter; import io.cattle.platform.object.ObjectManager; import io.cattle.platform.object.process.StandardProcess; import io.github.ibuildthecloud.gdapi.context.ApiContext; import io.github.ibuildthecloud.gdapi.exception.ClientVisibleException; import io.github.ibuildthecloud.gdapi.id.IdFormatter; import io.github.ibuildthecloud.gdapi.model.ListOptions; import io.github.ibuildthecloud.gdapi.request.ApiRequest; import io.github.ibuildthecloud.gdapi.request.resource.ResourceManager; import io.github.ibuildthecloud.gdapi.util.ResponseCodes; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.inject.Inject; import org.apache.commons.lang3.StringUtils; public class ServiceStackNetworkDriverFilter extends AbstractDefaultResourceManagerFilter { private static final Set<String> ACTIONS = new HashSet<>(Arrays.asList( StandardProcess.REMOVE.toString().toLowerCase(), StandardProcess.DEACTIVATE.toString().toLowerCase(), ServiceConstants.ACTION_STACK_DEACTIVATE_SERVICES )); @Inject NetworkDao networkDao; @Inject ObjectManager objectManager; @Override public Object delete(String type, String id, ApiRequest request, ResourceManager next) { validateInUse(type, id, request, next); return super.delete(type, id, request, next); } protected void validateInUse(String type, String id, ApiRequest request, ResourceManager next) { Object resource = getById(type, id, new ListOptions(), next); List<Service> services = new ArrayList<>(); if (resource instanceof Service) { services.add((Service)resource); } else if (resource instanceof Stack) { services = objectManager.find(Service.class, SERVICE.STACK_ID, ((Stack) resource).getId(), SERVICE.REMOVED, null); } for (Service service : services) { List<Long> ids = networkDao.findInstancesInUseByServiceDriver(service.getId()); if (ids.size() > 0) { throwException(ids); } } } protected void throwException(List<Long> ids) { IdFormatter idF = ApiContext.getContext().getIdFormatter(); List<Object> stringIds = new ArrayList<>(ids.size()); for (Long instanceId : ids) { stringIds.add(idF.formatId(InstanceConstants.TYPE, instanceId)); } throw new ClientVisibleException(ResponseCodes.CONFLICT, "DRIVER_IN_USE", "Driver from service is in use by instances", StringUtils.join(stringIds, ",")); } @Override public Object resourceAction(String type, ApiRequest request, ResourceManager next) { if (ACTIONS.contains(request.getAction())) { validateInUse(type, request.getId(), request, next); } return super.resourceAction(type, request, next); } @Override public Class<?>[] getTypeClasses() { return new Class<?>[]{Service.class, Stack.class}; } @Override public String[] getTypes() { return new String[] { ServiceConstants.KIND_NETWORK_DRIVER_SERVICE }; } }