package org.opennaas.extensions.sdnnetwork.driver.internal.actionsets.actions;
import java.util.List;
import org.opennaas.core.resources.ActivatorException;
import org.opennaas.core.resources.IResource;
import org.opennaas.core.resources.IResourceIdentifier;
import org.opennaas.core.resources.IResourceManager;
import org.opennaas.core.resources.ModelElementNotFoundException;
import org.opennaas.core.resources.ResourceException;
import org.opennaas.core.resources.action.Action;
import org.opennaas.core.resources.action.ActionException;
import org.opennaas.core.resources.action.ActionResponse;
import org.opennaas.core.resources.protocol.IProtocolSessionManager;
import org.opennaas.extensions.openflowswitch.capability.IOpenflowForwardingCapability;
import org.opennaas.extensions.sdnnetwork.Activator;
import org.opennaas.extensions.sdnnetwork.capability.ofprovision.OFProvisioningNetworkActionSet;
import org.opennaas.extensions.sdnnetwork.model.NetworkConnection;
import org.opennaas.extensions.sdnnetwork.model.SDNNetworkModel;
import org.opennaas.extensions.sdnnetwork.model.SDNNetworkModelHelper;
import org.opennaas.extensions.sdnnetwork.model.SDNNetworkOFFlow;
/**
*
* @author Isart Canyameres Gimenez (i2cat)
*
*/
public class DeallocateFlowAction extends Action {
@Override
public boolean checkParams(Object params) throws ActionException {
if (params == null || !(params instanceof String))
throw new ActionException("Invalid params for action " + OFProvisioningNetworkActionSet.DEALLOCATEFLOW);
return true;
}
@Override
public ActionResponse execute(IProtocolSessionManager protocolSessionManager) throws ActionException {
String flowName = (String) params;
SDNNetworkOFFlow flow;
try {
flow = SDNNetworkModelHelper.getFlowFromModelByName(flowName, (SDNNetworkModel) getModelToUpdate());
} catch (ModelElementNotFoundException e) {
throw new ActionException(e);
}
deallocateNetworkConnections(flow.getRoute().getNetworkConnections());
return ActionResponse.okResponse(OFProvisioningNetworkActionSet.DEALLOCATEFLOW);
}
private void deallocateNetworkConnections(List<NetworkConnection> networkConnections) throws ActionException {
// FIXME what to do if deallocation fails partially?
// - should we reallocate already deallocated networkConnections?
// - should we leave the flow allocated only partially?
// The second option is applied by now: A fail in deallocateNetworkConnection(networkConnection) will cause this action to interrupt,
// leaving the flow partially allocated and partially deallocated.
// This is not consistent with the vision the capability has: the user will see the flow as completely allocated, but may be only partially
// allocated.
for (NetworkConnection networkConnection : networkConnections) {
deallocateNetworkConnection(networkConnection);
}
}
private void deallocateNetworkConnection(NetworkConnection networkConnection) throws ActionException {
if (networkConnection.getSource().getDeviceId().equals(networkConnection.getDestination().getDeviceId())) {
/* link inside same device, use device internal capability to deallocate it */
deallocateConnectionInsideDevice(networkConnection.getSource().getDeviceId(), networkConnection);
} else {
/* link between different devices, assume it is statically allocated/deallocated */
}
}
private void deallocateConnectionInsideDevice(String DPID, NetworkConnection networkConnection) throws ActionException {
// use device IOpenflowForwardingCapability capability to deallocate networkConnection
try {
IOpenflowForwardingCapability forwardingCapability = getForwardingCapabilityOfDevice(networkConnection.getSource().getDeviceId());
//DPID and flowId???
forwardingCapability.removeOpenflowForwardingRule(DPID, networkConnection.getId());
} catch (ResourceException e) {
throw new ActionException("Failed to deallocate networkConnection " + networkConnection.getId(), e);
}
}
private IOpenflowForwardingCapability getForwardingCapabilityOfDevice(String deviceId) throws ResourceException {
String resourceName = deviceId;
IResource resource = getResourceByName(resourceName);
return (IOpenflowForwardingCapability) resource.getCapabilityByInterface(IOpenflowForwardingCapability.class);
}
private IResource getResourceByName(String resourceName) throws ResourceException {
try {
IResourceManager resourceManager = Activator.getResourceManagerService();
IResourceIdentifier resourceId = resourceManager.getIdentifierFromResourceName("openflowswitch", resourceName);
return resourceManager.getResource(resourceId);
} catch (ActivatorException e) {
throw new ResourceException("Couldn't get resource. Failed to get ResourceManagerService", e);
}
}
}