blob: eded26a2387fd3ef4d6809b3df1c68fb49b0cab3 [file] [log] [blame]
Jonathan Hartaa380972014-04-03 10:24:46 -07001package net.onrc.onos.core.intent.runtime;
Brian O'Connor12861f72014-02-19 20:40:32 -08002
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;
Jonathan Hart23701d12014-04-03 10:45:48 -070020import net.onrc.onos.core.flowprogrammer.IFlowPusherService;
Jonathan Hartaa380972014-04-03 10:24:46 -070021import net.onrc.onos.core.intent.FlowEntry;
22import net.onrc.onos.core.intent.IntentOperation;
23import net.onrc.onos.core.intent.IntentOperationList;
24import net.onrc.onos.core.intent.Intent.IntentState;
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
Jonathan Hartaa380972014-04-03 10:24:46 -070029
Jonathan Hart23701d12014-04-03 10:45:48 -070030
Brian O'Connor5e73c012014-02-20 14:54:34 -080031import org.slf4j.Logger;
32import org.slf4j.LoggerFactory;
33
Brian O'Connor12861f72014-02-19 20:40:32 -080034public class PlanInstallModule implements IFloodlightModule {
35 protected volatile IFloodlightProviderService floodlightProvider;
Brian O'Connor135a95e2014-02-20 13:48:44 -080036 protected volatile INetworkGraphService networkGraph;
Brian O'Connor12861f72014-02-19 20:40:32 -080037 protected volatile IDatagridService datagridService;
38 protected volatile IFlowPusherService flowPusher;
39 private PlanCalcRuntime planCalc;
40 private PlanInstallRuntime planInstall;
41 private EventListener eventListener;
Brian O'Connor488e5ed2014-02-20 19:50:01 -080042 private IEventChannel<Long, IntentStateList> intentStateChannel;
Brian O'Connor9b712f62014-02-20 14:22:20 -080043 private final static Logger log = LoggerFactory.getLogger(PlanInstallModule.class);
44
Brian O'Connor12861f72014-02-19 20:40:32 -080045
46 private static final String PATH_INTENT_CHANNEL_NAME = "onos.pathintent";
Brian O'Connor488e5ed2014-02-20 19:50:01 -080047 private static final String INTENT_STATE_EVENT_CHANNEL_NAME = "onos.pathintent_state";
48
Toshio Koide3a52ef32014-02-28 12:10:26 -080049
Brian O'Connor12861f72014-02-19 20:40:32 -080050 @Override
51 public void init(FloodlightModuleContext context)
52 throws FloodlightModuleException {
53 floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
Brian O'Connor135a95e2014-02-20 13:48:44 -080054 networkGraph = context.getServiceImpl(INetworkGraphService.class);
Brian O'Connor12861f72014-02-19 20:40:32 -080055 datagridService = context.getServiceImpl(IDatagridService.class);
56 flowPusher = context.getServiceImpl(IFlowPusherService.class);
Brian O'Connor488e5ed2014-02-20 19:50:01 -080057// NetworkGraph graph = networkGraph.getNetworkGraph();
58 planCalc = new PlanCalcRuntime();
59 planInstall = new PlanInstallRuntime(floodlightProvider, flowPusher);
Brian O'Connor12861f72014-02-19 20:40:32 -080060 eventListener = new EventListener();
61 }
62
63 class EventListener extends Thread
64 implements IEventChannelListener<Long, IntentOperationList> {
Toshio Koide3a52ef32014-02-28 12:10:26 -080065
Brian O'Connor12861f72014-02-19 20:40:32 -080066 private BlockingQueue<IntentOperationList> intentQueue = new LinkedBlockingQueue<>();
Brian O'Connor488e5ed2014-02-20 19:50:01 -080067 private Long key = Long.valueOf(0);
Toshio Koide3a52ef32014-02-28 12:10:26 -080068
Brian O'Connor12861f72014-02-19 20:40:32 -080069 @Override
70 public void run() {
71 while(true) {
72 try {
73 IntentOperationList intents = intentQueue.take();
Toshio Koide3a52ef32014-02-28 12:10:26 -080074 //TODO: consider draining the remaining intent lists
Brian O'Connor067b95d2014-02-21 18:43:27 -080075 // and processing in one big batch
Brian O'Connor6dc44e92014-02-24 21:23:46 -080076// List<IntentOperationList> remaining = new LinkedList<>();
77// intentQueue.drainTo(remaining);
Toshio Koide3a52ef32014-02-28 12:10:26 -080078
Brian O'Connor12861f72014-02-19 20:40:32 -080079 processIntents(intents);
80 } catch (InterruptedException e) {
Brian O'Connor5e73c012014-02-20 14:54:34 -080081 log.warn("Error taking from intent queue: {}", e.getMessage());
Brian O'Connor12861f72014-02-19 20:40:32 -080082 }
83 }
84 }
Toshio Koide3a52ef32014-02-28 12:10:26 -080085
Brian O'Connor12861f72014-02-19 20:40:32 -080086 private void processIntents(IntentOperationList intents) {
Brian O'Connor85dd8f22014-02-25 11:43:07 -080087 log("start_processIntents");
Brian O'Connor9b712f62014-02-20 14:22:20 -080088 log.debug("Processing OperationList {}", intents);
Brian O'Connor85dd8f22014-02-25 11:43:07 -080089 log("begin_computePlan");
Brian O'Connor12861f72014-02-19 20:40:32 -080090 List<Set<FlowEntry>> plan = planCalc.computePlan(intents);
Brian O'Connor85dd8f22014-02-25 11:43:07 -080091 log("end_computePlan");
Brian O'Connor9b712f62014-02-20 14:22:20 -080092 log.debug("Plan: {}", plan);
Brian O'Connor85dd8f22014-02-25 11:43:07 -080093 log("begin_installPlan");
Brian O'Connor488e5ed2014-02-20 19:50:01 -080094 boolean success = planInstall.installPlan(plan);
Brian O'Connor85dd8f22014-02-25 11:43:07 -080095 log("end_installPlan");
Toshio Koide3a52ef32014-02-28 12:10:26 -080096
Brian O'Connor85dd8f22014-02-25 11:43:07 -080097 log("begin_sendInstallNotif");
Brian O'Connor488e5ed2014-02-20 19:50:01 -080098 sendNotifications(intents, true, success);
Brian O'Connor85dd8f22014-02-25 11:43:07 -080099 log("end_sendInstallNotif");
100 log("finish");
Brian O'Connor488e5ed2014-02-20 19:50:01 -0800101 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800102
Brian O'Connor488e5ed2014-02-20 19:50:01 -0800103 private void sendNotifications(IntentOperationList intents, boolean installed, boolean success) {
104 IntentStateList states = new IntentStateList();
105 for(IntentOperation i : intents) {
106 IntentState newState;
107 switch(i.operator) {
108 case REMOVE:
109 if(installed) {
110 newState = success ? IntentState.DEL_ACK : IntentState.DEL_PENDING;
111 }
112 else {
113 newState = IntentState.DEL_REQ;
114 }
115 break;
116 case ADD:
117 default:
118 if(installed) {
119 newState = success ? IntentState.INST_ACK : IntentState.INST_NACK;
120 }
121 else {
122 newState = IntentState.INST_REQ;
123 }
124 break;
125 }
126 states.put(i.intent.getId(), newState);
127 }
128 intentStateChannel.addEntry(key, states);
Toshio Koide3a52ef32014-02-28 12:10:26 -0800129 // XXX: Send notifications using the same key every time
130 // and receive them by entryAdded() and entryUpdated()
131 // key += 1;
Brian O'Connor12861f72014-02-19 20:40:32 -0800132 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800133
Brian O'Connor12861f72014-02-19 20:40:32 -0800134 @Override
135 public void entryAdded(IntentOperationList value) {
Toshio Koide3a52ef32014-02-28 12:10:26 -0800136 entryUpdated(value);
137 }
138
139 @Override
140 public void entryRemoved(IntentOperationList value) {
141 // This channel is a queue, so this method is not needed
142 }
143
144 @Override
145 public void entryUpdated(IntentOperationList value) {
Brian O'Connor85dd8f22014-02-25 11:43:07 -0800146 log("start_intentNotifRecv");
147 log("begin_sendReceivedNotif");
Brian O'Connor488e5ed2014-02-20 19:50:01 -0800148 sendNotifications(value, false, false);
Brian O'Connor85dd8f22014-02-25 11:43:07 -0800149 log("end_sendReceivedNotif");
150 log("finish");
151
Brian O'Connor9b712f62014-02-20 14:22:20 -0800152 log.debug("Added OperationList {}", value);
Brian O'Connor5e73c012014-02-20 14:54:34 -0800153 try {
154 intentQueue.put(value);
155 } catch (InterruptedException e) {
156 log.warn("Error putting to intent queue: {}", e.getMessage());
157 }
Brian O'Connor12861f72014-02-19 20:40:32 -0800158 }
Brian O'Connor12861f72014-02-19 20:40:32 -0800159 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800160
Brian O'Connor85dd8f22014-02-25 11:43:07 -0800161 public static void log(String step) {
162 log.error("Time:{}, Step:{}", System.nanoTime(), step);
163 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800164
Brian O'Connor12861f72014-02-19 20:40:32 -0800165 @Override
166 public void startUp(FloodlightModuleContext context) {
Brian O'Connor488e5ed2014-02-20 19:50:01 -0800167 // start subscriber
Toshio Koide3a52ef32014-02-28 12:10:26 -0800168 datagridService.addListener(PATH_INTENT_CHANNEL_NAME,
169 eventListener,
170 Long.class,
Brian O'Connor5e73c012014-02-20 14:54:34 -0800171 IntentOperationList.class);
Brian O'Connor12861f72014-02-19 20:40:32 -0800172 eventListener.start();
Brian O'Connor488e5ed2014-02-20 19:50:01 -0800173 // start publisher
Toshio Koide3a52ef32014-02-28 12:10:26 -0800174 intentStateChannel = datagridService.createChannel(INTENT_STATE_EVENT_CHANNEL_NAME,
175 Long.class,
Brian O'Connor488e5ed2014-02-20 19:50:01 -0800176 IntentStateList.class);
Brian O'Connor12861f72014-02-19 20:40:32 -0800177 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800178
Brian O'Connor12861f72014-02-19 20:40:32 -0800179 @Override
180 public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
181 Collection<Class<? extends IFloodlightService>> l =
182 new ArrayList<Class<? extends IFloodlightService>>();
183 l.add(IFloodlightProviderService.class);
Brian O'Connor135a95e2014-02-20 13:48:44 -0800184 l.add(INetworkGraphService.class);
Brian O'Connor12861f72014-02-19 20:40:32 -0800185 l.add(IDatagridService.class);
186 l.add(IFlowPusherService.class);
187 return l;
188 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800189
Brian O'Connor12861f72014-02-19 20:40:32 -0800190 @Override
191 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
Brian O'Connor067b95d2014-02-21 18:43:27 -0800192 // no services, for now
Brian O'Connor12861f72014-02-19 20:40:32 -0800193 return null;
194 }
195
196 @Override
197 public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
Brian O'Connor067b95d2014-02-21 18:43:27 -0800198 // no services, for now
Brian O'Connor12861f72014-02-19 20:40:32 -0800199 return null;
200 }
201
202}