Brian O'Connor | a8e4980 | 2013-10-30 20:49:59 -0700 | [diff] [blame^] | 1 | package net.onrc.onos.ofcontroller.flowmanager; |
| 2 | |
| 3 | import java.io.IOException; |
| 4 | import java.util.ArrayList; |
| 5 | import java.util.Collection; |
| 6 | import java.util.Collections; |
| 7 | import java.util.HashMap; |
| 8 | import java.util.HashSet; |
| 9 | import java.util.List; |
| 10 | import java.util.Map; |
| 11 | import java.util.Set; |
| 12 | import java.util.concurrent.ExecutionException; |
| 13 | import java.util.concurrent.Executors; |
| 14 | import java.util.concurrent.Future; |
| 15 | |
| 16 | import org.openflow.protocol.OFFeaturesReply; |
| 17 | import org.openflow.protocol.OFMatch; |
| 18 | import org.openflow.protocol.OFStatisticsRequest; |
| 19 | import org.openflow.protocol.statistics.OFFlowStatisticsReply; |
| 20 | import org.openflow.protocol.statistics.OFFlowStatisticsRequest; |
| 21 | import org.openflow.protocol.statistics.OFStatistics; |
| 22 | import org.openflow.protocol.statistics.OFStatisticsType; |
| 23 | import org.slf4j.Logger; |
| 24 | import org.slf4j.LoggerFactory; |
| 25 | |
| 26 | import net.floodlightcontroller.core.IFloodlightProviderService; |
| 27 | import net.floodlightcontroller.core.IOFSwitch; |
| 28 | import net.floodlightcontroller.core.IOFSwitchListener; |
| 29 | import net.floodlightcontroller.core.module.FloodlightModuleContext; |
| 30 | import net.floodlightcontroller.core.module.FloodlightModuleException; |
| 31 | import net.floodlightcontroller.core.module.IFloodlightModule; |
| 32 | import net.floodlightcontroller.core.module.IFloodlightService; |
| 33 | import net.onrc.onos.graph.GraphDBOperation; |
| 34 | import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry; |
| 35 | import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject; |
| 36 | import net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher; |
| 37 | import net.onrc.onos.ofcontroller.util.Dpid; |
| 38 | import net.onrc.onos.ofcontroller.util.FlowEntry; |
| 39 | import net.onrc.onos.ofcontroller.util.FlowEntryId; |
| 40 | |
| 41 | public class FlowSynchronizer implements IOFSwitchListener, |
| 42 | IFloodlightModule { |
| 43 | |
| 44 | protected GraphDBOperation dbHandler = new GraphDBOperation(""); //TODO: conf |
| 45 | private static Logger log = LoggerFactory.getLogger(FlowSynchronizer.class); |
| 46 | protected IFloodlightProviderService floodlightProvider; |
| 47 | protected Map<IOFSwitch, Thread> switchThread = new HashMap<IOFSwitch, Thread>(); |
| 48 | |
| 49 | protected class Synchroizer implements Runnable { |
| 50 | IOFSwitch sw; |
| 51 | ISwitchObject swObj; |
| 52 | |
| 53 | public Synchroizer(IOFSwitch sw) { |
| 54 | this.sw = sw; |
| 55 | Dpid dpid = new Dpid(sw.getId()); |
| 56 | this.swObj = dbHandler.searchSwitch(dpid.toString()); |
| 57 | } |
| 58 | |
| 59 | @Override |
| 60 | public void run() { |
| 61 | //TODO: use a FlowEntryId, FlowEntry HashMap |
| 62 | Set<FlowEntryId> graphEntries = getFlowEntriesFromGraph(); |
| 63 | Set<FlowEntryId> switchEntries = getFlowEntriesFromSwitch(); |
| 64 | compare(graphEntries, switchEntries); |
| 65 | } |
| 66 | |
| 67 | private void compare(Set<FlowEntryId> graphEntries, Set<FlowEntryId> switchEntries) { |
| 68 | System.out.println("graph entries: " + graphEntries); |
| 69 | System.out.println("switch entries: " + switchEntries); |
| 70 | Set<FlowEntryId> entriesToAdd = new HashSet<FlowEntryId>(graphEntries); |
| 71 | entriesToAdd.removeAll(switchEntries); |
| 72 | Set<FlowEntryId> entriesToRemove = switchEntries; |
| 73 | entriesToRemove.removeAll(graphEntries); |
| 74 | System.out.println("add: " + entriesToAdd); |
| 75 | System.out.println("remove: " + entriesToRemove); |
| 76 | //FlowDatabaseOperation for converting flowentries |
| 77 | |
| 78 | /* TODO: new implementation with graph |
| 79 | for(FlowEntryId fid : switchEntries,keys()) { |
| 80 | if(graphEntries.contains(fid)) { |
| 81 | graphEntries.remove(fid); |
| 82 | } |
| 83 | else { |
| 84 | // remove fid from the switch |
| 85 | } |
| 86 | } |
| 87 | for(FlowEntry fe : graphEntries.values()) { |
| 88 | // add fid to switch |
| 89 | } |
| 90 | */ |
| 91 | |
| 92 | } |
| 93 | |
| 94 | private Set<FlowEntryId> getFlowEntriesFromGraph() { |
| 95 | Set<FlowEntryId> entryIds = new HashSet<FlowEntryId>(); |
| 96 | for(IFlowEntry entry : swObj.getFlowEntries()) { |
| 97 | FlowEntryId flowEntryId = new FlowEntryId(entry.getFlowEntryId()); |
| 98 | entryIds.add(flowEntryId); |
| 99 | } |
| 100 | return entryIds; |
| 101 | } |
| 102 | |
| 103 | private Set<FlowEntryId> getFlowEntriesFromSwitch() { |
| 104 | |
| 105 | int lengthU = 0; |
| 106 | OFMatch match = new OFMatch(); |
| 107 | match.setWildcards(OFMatch.OFPFW_ALL); |
| 108 | |
| 109 | OFFlowStatisticsRequest stat = new OFFlowStatisticsRequest(); |
| 110 | stat.setOutPort((short) 0xffff); //TODO: OFPort.OFPP_NONE |
| 111 | stat.setTableId((byte) 0xff); // TODO: fix this with enum (ALL TABLES) |
| 112 | stat.setMatch(match); |
| 113 | List<OFStatistics> stats = new ArrayList<OFStatistics>(); |
| 114 | stats.add(stat); |
| 115 | lengthU += stat.getLength(); |
| 116 | |
| 117 | OFStatisticsRequest req = new OFStatisticsRequest(); |
| 118 | req.setStatisticType(OFStatisticsType.FLOW); |
| 119 | req.setStatistics(stats); |
| 120 | lengthU += req.getLengthU(); |
| 121 | req.setLengthU(lengthU); |
| 122 | |
| 123 | List<OFStatistics> entries = null; |
| 124 | try { |
| 125 | Future<List<OFStatistics>> dfuture = sw.getStatistics(req); |
| 126 | entries = dfuture.get(); |
| 127 | } catch (IOException e) { |
| 128 | // TODO Auto-generated catch block |
| 129 | e.printStackTrace(); |
| 130 | } catch (InterruptedException e) { |
| 131 | // TODO Auto-generated catch block |
| 132 | e.printStackTrace(); |
| 133 | } catch (ExecutionException e) { |
| 134 | // TODO Auto-generated catch block |
| 135 | e.printStackTrace(); |
| 136 | } |
| 137 | |
| 138 | Set<FlowEntryId> entryIds = new HashSet<FlowEntryId>(); |
| 139 | for(OFStatistics result : entries){ |
| 140 | //System.out.println(result.getClass()); |
| 141 | OFFlowStatisticsReply entry = (OFFlowStatisticsReply) result; |
| 142 | FlowEntryId flowEntryId = new FlowEntryId(entry.getCookie()); |
| 143 | entryIds.add(flowEntryId); |
| 144 | } |
| 145 | return entryIds; |
| 146 | } |
| 147 | |
| 148 | } |
| 149 | |
| 150 | @Override |
| 151 | public void addedSwitch(IOFSwitch sw) { |
| 152 | // TODO Auto-generated method stub |
| 153 | System.out.println("added switch in flow sync: " + sw); |
| 154 | |
| 155 | // TODO: look at how this is spawned |
| 156 | Synchroizer sync = new Synchroizer(sw); |
| 157 | Thread t = new Thread(sync); |
| 158 | t.start(); |
| 159 | switchThread.put(sw, t); |
| 160 | } |
| 161 | |
| 162 | @Override |
| 163 | public void removedSwitch(IOFSwitch sw) { |
| 164 | // TODO Auto-generated method stub |
| 165 | System.out.println("removed switch in flow sync: " + sw); |
| 166 | Thread t = switchThread.remove(sw); |
| 167 | if(t != null) { |
| 168 | t.interrupt(); |
| 169 | } |
| 170 | |
| 171 | } |
| 172 | |
| 173 | @Override |
| 174 | public void switchPortChanged(Long switchId) { |
| 175 | // TODO Auto-generated method stub |
| 176 | |
| 177 | } |
| 178 | |
| 179 | @Override |
| 180 | public String getName() { |
| 181 | // TODO Auto-generated method stub |
| 182 | return "FlowSynchronizer"; |
| 183 | } |
| 184 | |
| 185 | @Override |
| 186 | public Collection<Class<? extends IFloodlightService>> getModuleServices() { |
| 187 | // TODO Auto-generated method stub |
| 188 | return null; |
| 189 | } |
| 190 | |
| 191 | @Override |
| 192 | public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() { |
| 193 | // TODO Auto-generated method stub |
| 194 | return null; |
| 195 | } |
| 196 | |
| 197 | @Override |
| 198 | public Collection<Class<? extends IFloodlightService>> getModuleDependencies() { |
| 199 | // TODO Auto-generated method stub |
| 200 | return null; |
| 201 | } |
| 202 | |
| 203 | @Override |
| 204 | public void init(FloodlightModuleContext context) |
| 205 | throws FloodlightModuleException { |
| 206 | // TODO Auto-generated method stub |
| 207 | System.out.println("********* Starting flow sync...."); |
| 208 | floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class); |
| 209 | System.out.println(context.getAllServices()); |
| 210 | } |
| 211 | |
| 212 | @Override |
| 213 | public void startUp(FloodlightModuleContext context) { |
| 214 | // TODO Auto-generated method stub |
| 215 | floodlightProvider.addOFSwitchListener(this); |
| 216 | |
| 217 | } |
| 218 | |
| 219 | } |