blob: 15230ecb42294fabf8b8c63f5816f7627355412c [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;
5import java.util.List;
6import java.util.Map;
7import java.util.Set;
8import java.util.concurrent.BlockingQueue;
9import java.util.concurrent.LinkedBlockingQueue;
10
11import net.floodlightcontroller.core.IFloodlightProviderService;
12import net.floodlightcontroller.core.module.FloodlightModuleContext;
13import net.floodlightcontroller.core.module.FloodlightModuleException;
14import net.floodlightcontroller.core.module.IFloodlightModule;
15import net.floodlightcontroller.core.module.IFloodlightService;
Jonathan Hart6df90172014-04-03 10:13:11 -070016import net.onrc.onos.core.datagrid.IDatagridService;
17import net.onrc.onos.core.datagrid.IEventChannel;
18import net.onrc.onos.core.datagrid.IEventChannelListener;
Jonathan Hart23701d12014-04-03 10:45:48 -070019import net.onrc.onos.core.flowprogrammer.IFlowPusherService;
Jonathan Hartaa380972014-04-03 10:24:46 -070020import net.onrc.onos.core.intent.FlowEntry;
Jonathan Harta99ec672014-04-03 11:30:34 -070021import net.onrc.onos.core.intent.Intent.IntentState;
Jonathan Hartaa380972014-04-03 10:24:46 -070022import net.onrc.onos.core.intent.IntentOperation;
23import net.onrc.onos.core.intent.IntentOperationList;
Jonathan Harte37e4e22014-05-13 19:12:02 -070024import net.onrc.onos.core.topology.ITopologyService;
25//import net.onrc.onos.core.topology.Topology;
Jonathan Hart472062d2014-04-03 10:56:48 -070026
Brian O'Connor5e73c012014-02-20 14:54:34 -080027import org.slf4j.Logger;
28import org.slf4j.LoggerFactory;
29
Brian O'Connor12861f72014-02-19 20:40:32 -080030public class PlanInstallModule implements IFloodlightModule {
31 protected volatile IFloodlightProviderService floodlightProvider;
Jonathan Harte37e4e22014-05-13 19:12:02 -070032 protected volatile ITopologyService topologyService;
Brian O'Connor12861f72014-02-19 20:40:32 -080033 protected volatile IDatagridService datagridService;
34 protected volatile IFlowPusherService flowPusher;
35 private PlanCalcRuntime planCalc;
36 private PlanInstallRuntime planInstall;
37 private EventListener eventListener;
Brian O'Connor488e5ed2014-02-20 19:50:01 -080038 private IEventChannel<Long, IntentStateList> intentStateChannel;
Ray Milkeyec838942014-04-09 11:28:43 -070039 private static final Logger log = LoggerFactory.getLogger(PlanInstallModule.class);
Brian O'Connor9b712f62014-02-20 14:22:20 -080040
Brian O'Connor12861f72014-02-19 20:40:32 -080041
42 private static final String PATH_INTENT_CHANNEL_NAME = "onos.pathintent";
Brian O'Connor488e5ed2014-02-20 19:50:01 -080043 private static final String INTENT_STATE_EVENT_CHANNEL_NAME = "onos.pathintent_state";
44
Toshio Koide3a52ef32014-02-28 12:10:26 -080045
Brian O'Connor12861f72014-02-19 20:40:32 -080046 @Override
47 public void init(FloodlightModuleContext context)
Ray Milkey269ffb92014-04-03 14:43:30 -070048 throws FloodlightModuleException {
49 floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
Jonathan Harte37e4e22014-05-13 19:12:02 -070050 topologyService = context.getServiceImpl(ITopologyService.class);
Ray Milkey269ffb92014-04-03 14:43:30 -070051 datagridService = context.getServiceImpl(IDatagridService.class);
52 flowPusher = context.getServiceImpl(IFlowPusherService.class);
Ray Milkey269ffb92014-04-03 14:43:30 -070053 planCalc = new PlanCalcRuntime();
54 planInstall = new PlanInstallRuntime(floodlightProvider, flowPusher);
55 eventListener = new EventListener();
Brian O'Connor12861f72014-02-19 20:40:32 -080056 }
57
58 class EventListener extends Thread
Ray Milkey269ffb92014-04-03 14:43:30 -070059 implements IEventChannelListener<Long, IntentOperationList> {
Toshio Koide3a52ef32014-02-28 12:10:26 -080060
Ray Milkey269ffb92014-04-03 14:43:30 -070061 private BlockingQueue<IntentOperationList> intentQueue = new LinkedBlockingQueue<>();
62 private Long key = Long.valueOf(0);
Toshio Koide3a52ef32014-02-28 12:10:26 -080063
Ray Milkey269ffb92014-04-03 14:43:30 -070064 @Override
65 public void run() {
66 while (true) {
67 try {
68 IntentOperationList intents = intentQueue.take();
69 //TODO: consider draining the remaining intent lists
70 // and processing in one big batch
71// List<IntentOperationList> remaining = new LinkedList<>();
72// intentQueue.drainTo(remaining);
Toshio Koide3a52ef32014-02-28 12:10:26 -080073
Ray Milkey269ffb92014-04-03 14:43:30 -070074 processIntents(intents);
75 } catch (InterruptedException e) {
76 log.warn("Error taking from intent queue: {}", e.getMessage());
77 }
78 }
79 }
Toshio Koide3a52ef32014-02-28 12:10:26 -080080
Ray Milkey269ffb92014-04-03 14:43:30 -070081 private void processIntents(IntentOperationList intents) {
82 log("start_processIntents");
83 log.debug("Processing OperationList {}", intents);
84 log("begin_computePlan");
85 List<Set<FlowEntry>> plan = planCalc.computePlan(intents);
86 log("end_computePlan");
87 log.debug("Plan: {}", plan);
88 log("begin_installPlan");
89 boolean success = planInstall.installPlan(plan);
90 log("end_installPlan");
Toshio Koide3a52ef32014-02-28 12:10:26 -080091
Ray Milkey269ffb92014-04-03 14:43:30 -070092 log("begin_sendInstallNotif");
93 sendNotifications(intents, true, success);
94 log("end_sendInstallNotif");
95 log("finish");
96 }
Toshio Koide3a52ef32014-02-28 12:10:26 -080097
Ray Milkey269ffb92014-04-03 14:43:30 -070098 private void sendNotifications(IntentOperationList intents, boolean installed, boolean success) {
99 IntentStateList states = new IntentStateList();
100 for (IntentOperation i : intents) {
101 IntentState newState;
102 switch (i.operator) {
103 case REMOVE:
104 if (installed) {
105 newState = success ? IntentState.DEL_ACK : IntentState.DEL_PENDING;
106 } else {
107 newState = IntentState.DEL_REQ;
108 }
109 break;
110 case ADD:
111 default:
112 if (installed) {
113 newState = success ? IntentState.INST_ACK : IntentState.INST_NACK;
114 } else {
115 newState = IntentState.INST_REQ;
116 }
117 break;
118 }
119 states.put(i.intent.getId(), newState);
120 }
121 intentStateChannel.addEntry(key, states);
122 // XXX: Send notifications using the same key every time
123 // and receive them by entryAdded() and entryUpdated()
124 // key += 1;
125 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800126
Ray Milkey269ffb92014-04-03 14:43:30 -0700127 @Override
128 public void entryAdded(IntentOperationList value) {
129 entryUpdated(value);
130 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800131
Ray Milkey269ffb92014-04-03 14:43:30 -0700132 @Override
133 public void entryRemoved(IntentOperationList value) {
134 // This channel is a queue, so this method is not needed
135 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800136
Ray Milkey269ffb92014-04-03 14:43:30 -0700137 @Override
138 public void entryUpdated(IntentOperationList value) {
139 log("start_intentNotifRecv");
140 log("begin_sendReceivedNotif");
141 sendNotifications(value, false, false);
142 log("end_sendReceivedNotif");
143 log("finish");
Brian O'Connor85dd8f22014-02-25 11:43:07 -0800144
Ray Milkey269ffb92014-04-03 14:43:30 -0700145 log.debug("Added OperationList {}", value);
146 try {
147 intentQueue.put(value);
148 } catch (InterruptedException e) {
149 log.warn("Error putting to intent queue: {}", e.getMessage());
150 }
151 }
Brian O'Connor12861f72014-02-19 20:40:32 -0800152 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800153
Brian O'Connor85dd8f22014-02-25 11:43:07 -0800154 public static void log(String step) {
Pavlin Radoslavov964f8ae2014-04-18 16:44:14 -0700155 log.debug("Time:{}, Step:{}", System.nanoTime(), step);
Brian O'Connor85dd8f22014-02-25 11:43:07 -0800156 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800157
Brian O'Connor12861f72014-02-19 20:40:32 -0800158 @Override
159 public void startUp(FloodlightModuleContext context) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700160 // start subscriber
161 datagridService.addListener(PATH_INTENT_CHANNEL_NAME,
162 eventListener,
163 Long.class,
164 IntentOperationList.class);
165 eventListener.start();
166 // start publisher
167 intentStateChannel = datagridService.createChannel(INTENT_STATE_EVENT_CHANNEL_NAME,
168 Long.class,
169 IntentStateList.class);
Brian O'Connor12861f72014-02-19 20:40:32 -0800170 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800171
Brian O'Connor12861f72014-02-19 20:40:32 -0800172 @Override
173 public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
Ray Milkey269ffb92014-04-03 14:43:30 -0700174 Collection<Class<? extends IFloodlightService>> l =
175 new ArrayList<Class<? extends IFloodlightService>>();
176 l.add(IFloodlightProviderService.class);
Jonathan Harte37e4e22014-05-13 19:12:02 -0700177 l.add(ITopologyService.class);
Ray Milkey269ffb92014-04-03 14:43:30 -0700178 l.add(IDatagridService.class);
179 l.add(IFlowPusherService.class);
180 return l;
Brian O'Connor12861f72014-02-19 20:40:32 -0800181 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800182
Brian O'Connor12861f72014-02-19 20:40:32 -0800183 @Override
184 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
Ray Milkey269ffb92014-04-03 14:43:30 -0700185 // no services, for now
186 return null;
Brian O'Connor12861f72014-02-19 20:40:32 -0800187 }
188
189 @Override
190 public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
Ray Milkey269ffb92014-04-03 14:43:30 -0700191 // no services, for now
192 return null;
Brian O'Connor12861f72014-02-19 20:40:32 -0800193 }
194
195}