blob: b4904c15450985d4f0e70f7f08a3bd2ae53c665c [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 Hart472062d2014-04-03 10:56:48 -070024import net.onrc.onos.core.topology.INetworkGraphService;
25//import net.onrc.onos.core.topology.NetworkGraph;
26
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;
Brian O'Connor135a95e2014-02-20 13:48:44 -080032 protected volatile INetworkGraphService networkGraph;
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;
Brian O'Connor9b712f62014-02-20 14:22:20 -080039 private final static Logger log = LoggerFactory.getLogger(PlanInstallModule.class);
40
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);
50 networkGraph = context.getServiceImpl(INetworkGraphService.class);
51 datagridService = context.getServiceImpl(IDatagridService.class);
52 flowPusher = context.getServiceImpl(IFlowPusherService.class);
53// NetworkGraph graph = networkGraph.getNetworkGraph();
54 planCalc = new PlanCalcRuntime();
55 planInstall = new PlanInstallRuntime(floodlightProvider, flowPusher);
56 eventListener = new EventListener();
Brian O'Connor12861f72014-02-19 20:40:32 -080057 }
58
59 class EventListener extends Thread
Ray Milkey269ffb92014-04-03 14:43:30 -070060 implements IEventChannelListener<Long, IntentOperationList> {
Toshio Koide3a52ef32014-02-28 12:10:26 -080061
Ray Milkey269ffb92014-04-03 14:43:30 -070062 private BlockingQueue<IntentOperationList> intentQueue = new LinkedBlockingQueue<>();
63 private Long key = Long.valueOf(0);
Toshio Koide3a52ef32014-02-28 12:10:26 -080064
Ray Milkey269ffb92014-04-03 14:43:30 -070065 @Override
66 public void run() {
67 while (true) {
68 try {
69 IntentOperationList intents = intentQueue.take();
70 //TODO: consider draining the remaining intent lists
71 // and processing in one big batch
72// List<IntentOperationList> remaining = new LinkedList<>();
73// intentQueue.drainTo(remaining);
Toshio Koide3a52ef32014-02-28 12:10:26 -080074
Ray Milkey269ffb92014-04-03 14:43:30 -070075 processIntents(intents);
76 } catch (InterruptedException e) {
77 log.warn("Error taking from intent queue: {}", e.getMessage());
78 }
79 }
80 }
Toshio Koide3a52ef32014-02-28 12:10:26 -080081
Ray Milkey269ffb92014-04-03 14:43:30 -070082 private void processIntents(IntentOperationList intents) {
83 log("start_processIntents");
84 log.debug("Processing OperationList {}", intents);
85 log("begin_computePlan");
86 List<Set<FlowEntry>> plan = planCalc.computePlan(intents);
87 log("end_computePlan");
88 log.debug("Plan: {}", plan);
89 log("begin_installPlan");
90 boolean success = planInstall.installPlan(plan);
91 log("end_installPlan");
Toshio Koide3a52ef32014-02-28 12:10:26 -080092
Ray Milkey269ffb92014-04-03 14:43:30 -070093 log("begin_sendInstallNotif");
94 sendNotifications(intents, true, success);
95 log("end_sendInstallNotif");
96 log("finish");
97 }
Toshio Koide3a52ef32014-02-28 12:10:26 -080098
Ray Milkey269ffb92014-04-03 14:43:30 -070099 private void sendNotifications(IntentOperationList intents, boolean installed, boolean success) {
100 IntentStateList states = new IntentStateList();
101 for (IntentOperation i : intents) {
102 IntentState newState;
103 switch (i.operator) {
104 case REMOVE:
105 if (installed) {
106 newState = success ? IntentState.DEL_ACK : IntentState.DEL_PENDING;
107 } else {
108 newState = IntentState.DEL_REQ;
109 }
110 break;
111 case ADD:
112 default:
113 if (installed) {
114 newState = success ? IntentState.INST_ACK : IntentState.INST_NACK;
115 } else {
116 newState = IntentState.INST_REQ;
117 }
118 break;
119 }
120 states.put(i.intent.getId(), newState);
121 }
122 intentStateChannel.addEntry(key, states);
123 // XXX: Send notifications using the same key every time
124 // and receive them by entryAdded() and entryUpdated()
125 // key += 1;
126 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800127
Ray Milkey269ffb92014-04-03 14:43:30 -0700128 @Override
129 public void entryAdded(IntentOperationList value) {
130 entryUpdated(value);
131 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800132
Ray Milkey269ffb92014-04-03 14:43:30 -0700133 @Override
134 public void entryRemoved(IntentOperationList value) {
135 // This channel is a queue, so this method is not needed
136 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800137
Ray Milkey269ffb92014-04-03 14:43:30 -0700138 @Override
139 public void entryUpdated(IntentOperationList value) {
140 log("start_intentNotifRecv");
141 log("begin_sendReceivedNotif");
142 sendNotifications(value, false, false);
143 log("end_sendReceivedNotif");
144 log("finish");
Brian O'Connor85dd8f22014-02-25 11:43:07 -0800145
Ray Milkey269ffb92014-04-03 14:43:30 -0700146 log.debug("Added OperationList {}", value);
147 try {
148 intentQueue.put(value);
149 } catch (InterruptedException e) {
150 log.warn("Error putting to intent queue: {}", e.getMessage());
151 }
152 }
Brian O'Connor12861f72014-02-19 20:40:32 -0800153 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800154
Brian O'Connor85dd8f22014-02-25 11:43:07 -0800155 public static void log(String step) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700156 log.error("Time:{}, Step:{}", System.nanoTime(), step);
Brian O'Connor85dd8f22014-02-25 11:43:07 -0800157 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800158
Brian O'Connor12861f72014-02-19 20:40:32 -0800159 @Override
160 public void startUp(FloodlightModuleContext context) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700161 // start subscriber
162 datagridService.addListener(PATH_INTENT_CHANNEL_NAME,
163 eventListener,
164 Long.class,
165 IntentOperationList.class);
166 eventListener.start();
167 // start publisher
168 intentStateChannel = datagridService.createChannel(INTENT_STATE_EVENT_CHANNEL_NAME,
169 Long.class,
170 IntentStateList.class);
Brian O'Connor12861f72014-02-19 20:40:32 -0800171 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800172
Brian O'Connor12861f72014-02-19 20:40:32 -0800173 @Override
174 public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
Ray Milkey269ffb92014-04-03 14:43:30 -0700175 Collection<Class<? extends IFloodlightService>> l =
176 new ArrayList<Class<? extends IFloodlightService>>();
177 l.add(IFloodlightProviderService.class);
178 l.add(INetworkGraphService.class);
179 l.add(IDatagridService.class);
180 l.add(IFlowPusherService.class);
181 return l;
Brian O'Connor12861f72014-02-19 20:40:32 -0800182 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800183
Brian O'Connor12861f72014-02-19 20:40:32 -0800184 @Override
185 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
Ray Milkey269ffb92014-04-03 14:43:30 -0700186 // no services, for now
187 return null;
Brian O'Connor12861f72014-02-19 20:40:32 -0800188 }
189
190 @Override
191 public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
Ray Milkey269ffb92014-04-03 14:43:30 -0700192 // no services, for now
193 return null;
Brian O'Connor12861f72014-02-19 20:40:32 -0800194 }
195
196}