blob: f4e8226d2ac92d1b86c79f19ee72666e192ff4ec [file] [log] [blame]
Brian O'Connor12861f72014-02-19 20:40:32 -08001package net.onrc.onos.intent.runtime;
2
3import java.util.ArrayList;
4import java.util.Collection;
Brian O'Connor6dc44e92014-02-24 21:23:46 -08005import java.util.LinkedList;
Brian O'Connor12861f72014-02-19 20:40:32 -08006import java.util.List;
7import java.util.Map;
8import java.util.Set;
9import java.util.concurrent.BlockingQueue;
10import java.util.concurrent.LinkedBlockingQueue;
11
12import net.floodlightcontroller.core.IFloodlightProviderService;
13import net.floodlightcontroller.core.module.FloodlightModuleContext;
14import net.floodlightcontroller.core.module.FloodlightModuleException;
15import net.floodlightcontroller.core.module.IFloodlightModule;
16import net.floodlightcontroller.core.module.IFloodlightService;
Jonathan Hart6df90172014-04-03 10:13:11 -070017import net.onrc.onos.core.datagrid.IDatagridService;
18import net.onrc.onos.core.datagrid.IEventChannel;
19import net.onrc.onos.core.datagrid.IEventChannelListener;
Brian O'Connor12861f72014-02-19 20:40:32 -080020import net.onrc.onos.intent.FlowEntry;
Brian O'Connor488e5ed2014-02-20 19:50:01 -080021import net.onrc.onos.intent.Intent.IntentState;
22import net.onrc.onos.intent.IntentOperation;
Brian O'Connor12861f72014-02-19 20:40:32 -080023import net.onrc.onos.intent.IntentOperationList;
24import net.onrc.onos.ofcontroller.flowprogrammer.IFlowPusherService;
Brian O'Connor135a95e2014-02-20 13:48:44 -080025import net.onrc.onos.ofcontroller.networkgraph.INetworkGraphService;
Brian O'Connor488e5ed2014-02-20 19:50:01 -080026//import net.onrc.onos.ofcontroller.networkgraph.NetworkGraph;
Brian O'Connor12861f72014-02-19 20:40:32 -080027
Jonathan Hart6df90172014-04-03 10:13:11 -070028
Brian O'Connor5e73c012014-02-20 14:54:34 -080029import org.slf4j.Logger;
30import org.slf4j.LoggerFactory;
31
Brian O'Connor12861f72014-02-19 20:40:32 -080032public class PlanInstallModule implements IFloodlightModule {
33 protected volatile IFloodlightProviderService floodlightProvider;
Brian O'Connor135a95e2014-02-20 13:48:44 -080034 protected volatile INetworkGraphService networkGraph;
Brian O'Connor12861f72014-02-19 20:40:32 -080035 protected volatile IDatagridService datagridService;
36 protected volatile IFlowPusherService flowPusher;
37 private PlanCalcRuntime planCalc;
38 private PlanInstallRuntime planInstall;
39 private EventListener eventListener;
Brian O'Connor488e5ed2014-02-20 19:50:01 -080040 private IEventChannel<Long, IntentStateList> intentStateChannel;
Brian O'Connor9b712f62014-02-20 14:22:20 -080041 private final static Logger log = LoggerFactory.getLogger(PlanInstallModule.class);
42
Brian O'Connor12861f72014-02-19 20:40:32 -080043
44 private static final String PATH_INTENT_CHANNEL_NAME = "onos.pathintent";
Brian O'Connor488e5ed2014-02-20 19:50:01 -080045 private static final String INTENT_STATE_EVENT_CHANNEL_NAME = "onos.pathintent_state";
46
Toshio Koide3a52ef32014-02-28 12:10:26 -080047
Brian O'Connor12861f72014-02-19 20:40:32 -080048 @Override
49 public void init(FloodlightModuleContext context)
50 throws FloodlightModuleException {
51 floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
Brian O'Connor135a95e2014-02-20 13:48:44 -080052 networkGraph = context.getServiceImpl(INetworkGraphService.class);
Brian O'Connor12861f72014-02-19 20:40:32 -080053 datagridService = context.getServiceImpl(IDatagridService.class);
54 flowPusher = context.getServiceImpl(IFlowPusherService.class);
Brian O'Connor488e5ed2014-02-20 19:50:01 -080055// NetworkGraph graph = networkGraph.getNetworkGraph();
56 planCalc = new PlanCalcRuntime();
57 planInstall = new PlanInstallRuntime(floodlightProvider, flowPusher);
Brian O'Connor12861f72014-02-19 20:40:32 -080058 eventListener = new EventListener();
59 }
60
61 class EventListener extends Thread
62 implements IEventChannelListener<Long, IntentOperationList> {
Toshio Koide3a52ef32014-02-28 12:10:26 -080063
Brian O'Connor12861f72014-02-19 20:40:32 -080064 private BlockingQueue<IntentOperationList> intentQueue = new LinkedBlockingQueue<>();
Brian O'Connor488e5ed2014-02-20 19:50:01 -080065 private Long key = Long.valueOf(0);
Toshio Koide3a52ef32014-02-28 12:10:26 -080066
Brian O'Connor12861f72014-02-19 20:40:32 -080067 @Override
68 public void run() {
69 while(true) {
70 try {
71 IntentOperationList intents = intentQueue.take();
Toshio Koide3a52ef32014-02-28 12:10:26 -080072 //TODO: consider draining the remaining intent lists
Brian O'Connor067b95d2014-02-21 18:43:27 -080073 // and processing in one big batch
Brian O'Connor6dc44e92014-02-24 21:23:46 -080074// List<IntentOperationList> remaining = new LinkedList<>();
75// intentQueue.drainTo(remaining);
Toshio Koide3a52ef32014-02-28 12:10:26 -080076
Brian O'Connor12861f72014-02-19 20:40:32 -080077 processIntents(intents);
78 } catch (InterruptedException e) {
Brian O'Connor5e73c012014-02-20 14:54:34 -080079 log.warn("Error taking from intent queue: {}", e.getMessage());
Brian O'Connor12861f72014-02-19 20:40:32 -080080 }
81 }
82 }
Toshio Koide3a52ef32014-02-28 12:10:26 -080083
Brian O'Connor12861f72014-02-19 20:40:32 -080084 private void processIntents(IntentOperationList intents) {
Brian O'Connor85dd8f22014-02-25 11:43:07 -080085 log("start_processIntents");
Brian O'Connor9b712f62014-02-20 14:22:20 -080086 log.debug("Processing OperationList {}", intents);
Brian O'Connor85dd8f22014-02-25 11:43:07 -080087 log("begin_computePlan");
Brian O'Connor12861f72014-02-19 20:40:32 -080088 List<Set<FlowEntry>> plan = planCalc.computePlan(intents);
Brian O'Connor85dd8f22014-02-25 11:43:07 -080089 log("end_computePlan");
Brian O'Connor9b712f62014-02-20 14:22:20 -080090 log.debug("Plan: {}", plan);
Brian O'Connor85dd8f22014-02-25 11:43:07 -080091 log("begin_installPlan");
Brian O'Connor488e5ed2014-02-20 19:50:01 -080092 boolean success = planInstall.installPlan(plan);
Brian O'Connor85dd8f22014-02-25 11:43:07 -080093 log("end_installPlan");
Toshio Koide3a52ef32014-02-28 12:10:26 -080094
Brian O'Connor85dd8f22014-02-25 11:43:07 -080095 log("begin_sendInstallNotif");
Brian O'Connor488e5ed2014-02-20 19:50:01 -080096 sendNotifications(intents, true, success);
Brian O'Connor85dd8f22014-02-25 11:43:07 -080097 log("end_sendInstallNotif");
98 log("finish");
Brian O'Connor488e5ed2014-02-20 19:50:01 -080099 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800100
Brian O'Connor488e5ed2014-02-20 19:50:01 -0800101 private void sendNotifications(IntentOperationList intents, boolean installed, boolean success) {
102 IntentStateList states = new IntentStateList();
103 for(IntentOperation i : intents) {
104 IntentState newState;
105 switch(i.operator) {
106 case REMOVE:
107 if(installed) {
108 newState = success ? IntentState.DEL_ACK : IntentState.DEL_PENDING;
109 }
110 else {
111 newState = IntentState.DEL_REQ;
112 }
113 break;
114 case ADD:
115 default:
116 if(installed) {
117 newState = success ? IntentState.INST_ACK : IntentState.INST_NACK;
118 }
119 else {
120 newState = IntentState.INST_REQ;
121 }
122 break;
123 }
124 states.put(i.intent.getId(), newState);
125 }
126 intentStateChannel.addEntry(key, states);
Toshio Koide3a52ef32014-02-28 12:10:26 -0800127 // XXX: Send notifications using the same key every time
128 // and receive them by entryAdded() and entryUpdated()
129 // key += 1;
Brian O'Connor12861f72014-02-19 20:40:32 -0800130 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800131
Brian O'Connor12861f72014-02-19 20:40:32 -0800132 @Override
133 public void entryAdded(IntentOperationList value) {
Toshio Koide3a52ef32014-02-28 12:10:26 -0800134 entryUpdated(value);
135 }
136
137 @Override
138 public void entryRemoved(IntentOperationList value) {
139 // This channel is a queue, so this method is not needed
140 }
141
142 @Override
143 public void entryUpdated(IntentOperationList value) {
Brian O'Connor85dd8f22014-02-25 11:43:07 -0800144 log("start_intentNotifRecv");
145 log("begin_sendReceivedNotif");
Brian O'Connor488e5ed2014-02-20 19:50:01 -0800146 sendNotifications(value, false, false);
Brian O'Connor85dd8f22014-02-25 11:43:07 -0800147 log("end_sendReceivedNotif");
148 log("finish");
149
Brian O'Connor9b712f62014-02-20 14:22:20 -0800150 log.debug("Added OperationList {}", value);
Brian O'Connor5e73c012014-02-20 14:54:34 -0800151 try {
152 intentQueue.put(value);
153 } catch (InterruptedException e) {
154 log.warn("Error putting to intent queue: {}", e.getMessage());
155 }
Brian O'Connor12861f72014-02-19 20:40:32 -0800156 }
Brian O'Connor12861f72014-02-19 20:40:32 -0800157 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800158
Brian O'Connor85dd8f22014-02-25 11:43:07 -0800159 public static void log(String step) {
160 log.error("Time:{}, Step:{}", System.nanoTime(), step);
161 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800162
Brian O'Connor12861f72014-02-19 20:40:32 -0800163 @Override
164 public void startUp(FloodlightModuleContext context) {
Brian O'Connor488e5ed2014-02-20 19:50:01 -0800165 // start subscriber
Toshio Koide3a52ef32014-02-28 12:10:26 -0800166 datagridService.addListener(PATH_INTENT_CHANNEL_NAME,
167 eventListener,
168 Long.class,
Brian O'Connor5e73c012014-02-20 14:54:34 -0800169 IntentOperationList.class);
Brian O'Connor12861f72014-02-19 20:40:32 -0800170 eventListener.start();
Brian O'Connor488e5ed2014-02-20 19:50:01 -0800171 // start publisher
Toshio Koide3a52ef32014-02-28 12:10:26 -0800172 intentStateChannel = datagridService.createChannel(INTENT_STATE_EVENT_CHANNEL_NAME,
173 Long.class,
Brian O'Connor488e5ed2014-02-20 19:50:01 -0800174 IntentStateList.class);
Brian O'Connor12861f72014-02-19 20:40:32 -0800175 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800176
Brian O'Connor12861f72014-02-19 20:40:32 -0800177 @Override
178 public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
179 Collection<Class<? extends IFloodlightService>> l =
180 new ArrayList<Class<? extends IFloodlightService>>();
181 l.add(IFloodlightProviderService.class);
Brian O'Connor135a95e2014-02-20 13:48:44 -0800182 l.add(INetworkGraphService.class);
Brian O'Connor12861f72014-02-19 20:40:32 -0800183 l.add(IDatagridService.class);
184 l.add(IFlowPusherService.class);
185 return l;
186 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800187
Brian O'Connor12861f72014-02-19 20:40:32 -0800188 @Override
189 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
Brian O'Connor067b95d2014-02-21 18:43:27 -0800190 // no services, for now
Brian O'Connor12861f72014-02-19 20:40:32 -0800191 return null;
192 }
193
194 @Override
195 public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
Brian O'Connor067b95d2014-02-21 18:43:27 -0800196 // no services, for now
Brian O'Connor12861f72014-02-19 20:40:32 -0800197 return null;
198 }
199
200}