blob: 94e5d8f6b36778d9f99d2e664aa8817bdc7d81f6 [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;
Jonathan Hart472062d2014-04-03 10:56:48 -070025
Brian O'Connor5e73c012014-02-20 14:54:34 -080026import org.slf4j.Logger;
27import org.slf4j.LoggerFactory;
28
Brian O'Connor12861f72014-02-19 20:40:32 -080029public class PlanInstallModule implements IFloodlightModule {
30 protected volatile IFloodlightProviderService floodlightProvider;
Jonathan Harte37e4e22014-05-13 19:12:02 -070031 protected volatile ITopologyService topologyService;
Brian O'Connor12861f72014-02-19 20:40:32 -080032 protected volatile IDatagridService datagridService;
33 protected volatile IFlowPusherService flowPusher;
34 private PlanCalcRuntime planCalc;
35 private PlanInstallRuntime planInstall;
36 private EventListener eventListener;
Brian O'Connor488e5ed2014-02-20 19:50:01 -080037 private IEventChannel<Long, IntentStateList> intentStateChannel;
Ray Milkeyec838942014-04-09 11:28:43 -070038 private static final Logger log = LoggerFactory.getLogger(PlanInstallModule.class);
Brian O'Connor9b712f62014-02-20 14:22:20 -080039
Brian O'Connor12861f72014-02-19 20:40:32 -080040 private static final String PATH_INTENT_CHANNEL_NAME = "onos.pathintent";
Brian O'Connor488e5ed2014-02-20 19:50:01 -080041 private static final String INTENT_STATE_EVENT_CHANNEL_NAME = "onos.pathintent_state";
42
Toshio Koide3a52ef32014-02-28 12:10:26 -080043
Brian O'Connor12861f72014-02-19 20:40:32 -080044 @Override
45 public void init(FloodlightModuleContext context)
Ray Milkey269ffb92014-04-03 14:43:30 -070046 throws FloodlightModuleException {
47 floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
Jonathan Harte37e4e22014-05-13 19:12:02 -070048 topologyService = context.getServiceImpl(ITopologyService.class);
Ray Milkey269ffb92014-04-03 14:43:30 -070049 datagridService = context.getServiceImpl(IDatagridService.class);
50 flowPusher = context.getServiceImpl(IFlowPusherService.class);
Ray Milkey269ffb92014-04-03 14:43:30 -070051 planCalc = new PlanCalcRuntime();
52 planInstall = new PlanInstallRuntime(floodlightProvider, flowPusher);
53 eventListener = new EventListener();
Brian O'Connor12861f72014-02-19 20:40:32 -080054 }
55
56 class EventListener extends Thread
Ray Milkey269ffb92014-04-03 14:43:30 -070057 implements IEventChannelListener<Long, IntentOperationList> {
Toshio Koide3a52ef32014-02-28 12:10:26 -080058
Ray Milkey269ffb92014-04-03 14:43:30 -070059 private BlockingQueue<IntentOperationList> intentQueue = new LinkedBlockingQueue<>();
60 private Long key = Long.valueOf(0);
Toshio Koide3a52ef32014-02-28 12:10:26 -080061
Ray Milkey269ffb92014-04-03 14:43:30 -070062 @Override
63 public void run() {
64 while (true) {
65 try {
66 IntentOperationList intents = intentQueue.take();
67 //TODO: consider draining the remaining intent lists
68 // and processing in one big batch
69// List<IntentOperationList> remaining = new LinkedList<>();
70// intentQueue.drainTo(remaining);
Toshio Koide3a52ef32014-02-28 12:10:26 -080071
Ray Milkey269ffb92014-04-03 14:43:30 -070072 processIntents(intents);
73 } catch (InterruptedException e) {
74 log.warn("Error taking from intent queue: {}", e.getMessage());
75 }
76 }
77 }
Toshio Koide3a52ef32014-02-28 12:10:26 -080078
Ray Milkey269ffb92014-04-03 14:43:30 -070079 private void processIntents(IntentOperationList intents) {
80 log("start_processIntents");
81 log.debug("Processing OperationList {}", intents);
82 log("begin_computePlan");
83 List<Set<FlowEntry>> plan = planCalc.computePlan(intents);
84 log("end_computePlan");
85 log.debug("Plan: {}", plan);
86 log("begin_installPlan");
87 boolean success = planInstall.installPlan(plan);
88 log("end_installPlan");
TeruUf9111652014-05-14 23:10:35 -070089 Set<Long> domainSwitchDpids = floodlightProvider.getSwitches().keySet();
Ray Milkey269ffb92014-04-03 14:43:30 -070090 log("begin_sendInstallNotif");
TeruUf9111652014-05-14 23:10:35 -070091 sendNotifications(intents, true, success, domainSwitchDpids);
Ray Milkey269ffb92014-04-03 14:43:30 -070092 log("end_sendInstallNotif");
93 log("finish");
94 }
Toshio Koide3a52ef32014-02-28 12:10:26 -080095
TeruUf9111652014-05-14 23:10:35 -070096 /***
97 * This function is for sending intent state notification to other ONOS instances.
98 * The argument of "domainSwitchDpids" is required for dispatching this ONOS's managed switches.
99 * @param intents
100 * @param installed
101 * @param success
102 * @param domainSwitchDpids
103 */
104 private void sendNotifications(IntentOperationList intents, boolean installed, boolean success, Set<Long> domainSwitchDpids) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700105 IntentStateList states = new IntentStateList();
106 for (IntentOperation i : intents) {
107 IntentState newState;
108 switch (i.operator) {
109 case REMOVE:
110 if (installed) {
111 newState = success ? IntentState.DEL_ACK : IntentState.DEL_PENDING;
112 } else {
113 newState = IntentState.DEL_REQ;
114 }
115 break;
116 case ADD:
117 default:
118 if (installed) {
TeruUf9111652014-05-14 23:10:35 -0700119 if (domainSwitchDpids != null) {
120 states.domainSwitchDpids.addAll(domainSwitchDpids);
121 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700122 newState = success ? IntentState.INST_ACK : IntentState.INST_NACK;
123 } else {
124 newState = IntentState.INST_REQ;
125 }
126 break;
127 }
128 states.put(i.intent.getId(), newState);
129 }
TeruUf9111652014-05-14 23:10:35 -0700130
131 if (log.isTraceEnabled()) {
132 log.trace("domainSwitchDpids {}", states.domainSwitchDpids);
133 }
134
135 intentStateChannel.addTransientEntry(key, states);
Ray Milkey269ffb92014-04-03 14:43:30 -0700136 // XXX: Send notifications using the same key every time
137 // and receive them by entryAdded() and entryUpdated()
138 // key += 1;
139 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800140
Ray Milkey269ffb92014-04-03 14:43:30 -0700141 @Override
142 public void entryAdded(IntentOperationList value) {
143 entryUpdated(value);
144 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800145
Ray Milkey269ffb92014-04-03 14:43:30 -0700146 @Override
147 public void entryRemoved(IntentOperationList value) {
148 // This channel is a queue, so this method is not needed
149 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800150
Ray Milkey269ffb92014-04-03 14:43:30 -0700151 @Override
152 public void entryUpdated(IntentOperationList value) {
153 log("start_intentNotifRecv");
154 log("begin_sendReceivedNotif");
TeruUf9111652014-05-14 23:10:35 -0700155 sendNotifications(value, false, false, null);
Ray Milkey269ffb92014-04-03 14:43:30 -0700156 log("end_sendReceivedNotif");
157 log("finish");
Brian O'Connor85dd8f22014-02-25 11:43:07 -0800158
Ray Milkey269ffb92014-04-03 14:43:30 -0700159 log.debug("Added OperationList {}", value);
160 try {
161 intentQueue.put(value);
162 } catch (InterruptedException e) {
163 log.warn("Error putting to intent queue: {}", e.getMessage());
164 }
165 }
Brian O'Connor12861f72014-02-19 20:40:32 -0800166 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800167
Brian O'Connor85dd8f22014-02-25 11:43:07 -0800168 public static void log(String step) {
Pavlin Radoslavov964f8ae2014-04-18 16:44:14 -0700169 log.debug("Time:{}, Step:{}", System.nanoTime(), step);
Brian O'Connor85dd8f22014-02-25 11:43:07 -0800170 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800171
Brian O'Connor12861f72014-02-19 20:40:32 -0800172 @Override
173 public void startUp(FloodlightModuleContext context) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700174 // start subscriber
175 datagridService.addListener(PATH_INTENT_CHANNEL_NAME,
176 eventListener,
177 Long.class,
178 IntentOperationList.class);
179 eventListener.start();
180 // start publisher
181 intentStateChannel = datagridService.createChannel(INTENT_STATE_EVENT_CHANNEL_NAME,
182 Long.class,
183 IntentStateList.class);
Brian O'Connor12861f72014-02-19 20:40:32 -0800184 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800185
Brian O'Connor12861f72014-02-19 20:40:32 -0800186 @Override
187 public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
Ray Milkey269ffb92014-04-03 14:43:30 -0700188 Collection<Class<? extends IFloodlightService>> l =
189 new ArrayList<Class<? extends IFloodlightService>>();
190 l.add(IFloodlightProviderService.class);
Jonathan Harte37e4e22014-05-13 19:12:02 -0700191 l.add(ITopologyService.class);
Ray Milkey269ffb92014-04-03 14:43:30 -0700192 l.add(IDatagridService.class);
193 l.add(IFlowPusherService.class);
194 return l;
Brian O'Connor12861f72014-02-19 20:40:32 -0800195 }
Toshio Koide3a52ef32014-02-28 12:10:26 -0800196
Brian O'Connor12861f72014-02-19 20:40:32 -0800197 @Override
198 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
Ray Milkey269ffb92014-04-03 14:43:30 -0700199 // no services, for now
200 return null;
Brian O'Connor12861f72014-02-19 20:40:32 -0800201 }
202
203 @Override
204 public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
Ray Milkey269ffb92014-04-03 14:43:30 -0700205 // no services, for now
206 return null;
Brian O'Connor12861f72014-02-19 20:40:32 -0800207 }
Brian O'Connor12861f72014-02-19 20:40:32 -0800208}