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.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.openflowswitch.model.FloodlightOFAction; import org.opennaas.extensions.openflowswitch.model.FloodlightOFFlow; import org.opennaas.extensions.sdnnetwork.Activator; import org.opennaas.extensions.sdnnetwork.model.NetworkConnection; import org.opennaas.extensions.sdnnetwork.model.Port; import org.opennaas.extensions.sdnnetwork.model.Route; import org.opennaas.extensions.sdnnetwork.model.SDNNetworkOFFlow; /** * * @author Isart Canyameres Gimenez (i2cat) * @author Julio Carlos Barrera * */ public class AllocateFlowAction extends Action { @Override public ActionResponse execute(IProtocolSessionManager protocolSessionManager) throws ActionException { SDNNetworkOFFlow flow = (SDNNetworkOFFlow) params; // provision each link and mark the last one List<NetworkConnection> connections = flow.getRoute().getNetworkConnections(); for (int i = 0; i < connections.size(); i++) { NetworkConnection networkConnection = connections.get(i); try { provisionLink(networkConnection, new SDNNetworkOFFlow(flow), i == connections.size() - 1); } catch (Exception e) { throw new ActionException("Error provisioning link : ", e); } } return ActionResponse.okResponse(getActionID()); } /** * private void provisionLink(Port source, Port destination, SDNNetworkOFFlow sdnNetworkOFFlow, boolean lastLink) throws ActionException { if * (source.getDeviceId() != destination.getDeviceId()) { // link between different devices, assume it exists or it is provisioned } else { // link * inside same device, use device internal capability to provision it // get OpenNaaS resource Id from the map in the model String deviceId = * source.getDeviceId(); String resourceId = ((SDNNetworkModel) getModelToUpdate()).getDeviceResourceMap().get(deviceId); if (resourceId == null) * { throw new ActionException("No resource Id found from device Id: " + deviceId); } * * // get switch resource from Resource Manager using resource Id IResource resource = null; try { resource = * Activator.getResourceManagerService().getResourceById(resourceId); } catch (Exception e) { throw new * ActionException("Error getting switch resource from Resource Manager", e); } * * // get IOpenflowForwardingCapability from the obtained resource IOpenflowForwardingCapability capability = null; try { capability = * (IOpenflowForwardingCapability) resource.getCapabilityByInterface(IOpenflowForwardingCapability.class); } catch (ResourceException e) { throw * new ActionException("Error getting IOpenflowForwardingCapability from resource with Id: " + resourceId, e); } * * // construct FloodlightOFFlow based on SDNNetworkOFFlow, source Port, destination Port and lastLink FloodlightOFFlow flow = new * FloodlightOFFlow(sdnNetworkOFFlow, deviceId); * * flow.getMatch().setIngressPort(source.getPortNumber()); * * // Only last link in the flow should apply actions other than forwarding. // The rest of the links should have only forwarding actions. * List<FloodlightOFAction> actions = flow.getActions(); if (!lastLink) { FloodlightOFAction outputAction = null; for (FloodlightOFAction * floodlightOFAction : actions) { if (floodlightOFAction.getType() == FloodlightOFAction.TYPE_OUTPUT) { outputAction = floodlightOFAction; } } if * (outputAction == null) { throw new ActionException("No output action found in FloodlightOFFlow."); } // clear list and add output action * actions.clear(); actions.add(outputAction); } * * // invoke IOpenflowForwardingCapability try { capability.createOpenflowForwardingRule(flow); } catch (CapabilityException e) { throw new * ActionException("Error executing IOpenflowForwardingCapability from resource with Id: " + resourceId, e); } } } **/ /** * The commented code is the right way to do it, but since there's no way to set the mapping between the switchID and the deviceID and we have a * demo tomorrow, we will take the switch resource from the ResourceManager. Every switch contains in its model its floodlight switchId, so we can * use it as a work around. * * @param source * @param destination * @param sdnNetworkOFFlow * @param lastLink * @throws ResourceException * @throws ActivatorException */ private void provisionLink(NetworkConnection connection, SDNNetworkOFFlow sdnNetworkOFFlow, boolean isLastLinkInRoute) throws ResourceException, ActivatorException { if (connection.getSource().getDeviceId().equals(connection.getDestination().getDeviceId())) { /* link inside same device, use device internal capability to provision it */ // Last link should include all actions of the original flow and the forwarding one. // The rest only the forwarding rule. // This way we can re-use original match in all links of the same flow. FloodlightOFFlow flow = generateOFFlow(connection, sdnNetworkOFFlow, isLastLinkInRoute); String resourceName = connection.getSource().getDeviceId(); IResource resource = getResourceByName(resourceName); IOpenflowForwardingCapability forwardingCapability = (IOpenflowForwardingCapability) resource .getCapabilityByInterface(IOpenflowForwardingCapability.class); forwardingCapability.createOpenflowForwardingRule(flow); } else { /* link between different devices, assume it exists or it is provisioned */ } } /** * * @param connection * @param sdnNetworkOFFlow * @param keepActions * whether returned flow must have actions in sdnNetworkOFFlow or not. * @return a FloodlightOFFlow representing given connection in sdnNetworkOFFlow. * @throws ActionException */ private FloodlightOFFlow generateOFFlow(NetworkConnection connection, SDNNetworkOFFlow sdnNetworkOFFlow, boolean keepActions) throws ActionException { Port source = connection.getSource(); Port destination = connection.getDestination(); FloodlightOFFlow flow = new FloodlightOFFlow(sdnNetworkOFFlow, null); flow.setName(connection.getId()); flow.getMatch().setIngressPort(source.getPortNumber()); FloodlightOFAction outputAction = new FloodlightOFAction(); outputAction.setType(FloodlightOFAction.TYPE_OUTPUT); outputAction.setValue(destination.getPortNumber()); // All links should include a forwarding action (outputAction) List<FloodlightOFAction> actions = flow.getActions(); if (!keepActions) { actions.clear(); } else { for (FloodlightOFAction floodlightOFAction : actions) { if (floodlightOFAction.getType() == FloodlightOFAction.TYPE_OUTPUT) { actions.remove(floodlightOFAction); } } } actions.add(outputAction); return flow; } private IResource getResourceByName(String resourceName) throws ActivatorException, ResourceException { IResourceManager resourceManager = Activator.getResourceManagerService(); IResourceIdentifier resourceId = resourceManager.getIdentifierFromResourceName("openflowswitch", resourceName); return resourceManager.getResource(resourceId); } @Override public boolean checkParams(Object params) throws ActionException { if (params instanceof SDNNetworkOFFlow) { SDNNetworkOFFlow flow = (SDNNetworkOFFlow) params; Route route = flow.getRoute(); if (route == null) { throw new ActionException("Route must be set"); } List<NetworkConnection> connections = route.getNetworkConnections(); if (connections == null || connections.size() == 0) { throw new ActionException("NetworkConnection list must have at least 1 item"); } return true; } throw new ActionException("Action parameters must be set and SDNNetworkOFFlow type"); } }