blob: 4d4e437c4f4df536bde8df29fee6e6d0769471d3 [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;
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;
16import net.onrc.onos.datagrid.IDatagridService;
Brian O'Connor5e73c012014-02-20 14:54:34 -080017import net.onrc.onos.datagrid.IEventChannel;
Brian O'Connor12861f72014-02-19 20:40:32 -080018import net.onrc.onos.datagrid.IEventChannelListener;
19import net.onrc.onos.intent.FlowEntry;
Brian O'Connor488e5ed2014-02-20 19:50:01 -080020import net.onrc.onos.intent.Intent.IntentState;
21import net.onrc.onos.intent.IntentOperation;
Brian O'Connor12861f72014-02-19 20:40:32 -080022import net.onrc.onos.intent.IntentOperationList;
23import net.onrc.onos.ofcontroller.flowprogrammer.IFlowPusherService;
Brian O'Connor135a95e2014-02-20 13:48:44 -080024import net.onrc.onos.ofcontroller.networkgraph.INetworkGraphService;
Brian O'Connor488e5ed2014-02-20 19:50:01 -080025//import net.onrc.onos.ofcontroller.networkgraph.NetworkGraph;
Brian O'Connor12861f72014-02-19 20:40:32 -080026
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
Brian O'Connor12861f72014-02-19 20:40:32 -080045
46 @Override
47 public void init(FloodlightModuleContext context)
48 throws FloodlightModuleException {
49 floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
Brian O'Connor135a95e2014-02-20 13:48:44 -080050 networkGraph = context.getServiceImpl(INetworkGraphService.class);
Brian O'Connor12861f72014-02-19 20:40:32 -080051 datagridService = context.getServiceImpl(IDatagridService.class);
52 flowPusher = context.getServiceImpl(IFlowPusherService.class);
Brian O'Connor488e5ed2014-02-20 19:50:01 -080053// NetworkGraph graph = networkGraph.getNetworkGraph();
54 planCalc = new PlanCalcRuntime();
55 planInstall = new PlanInstallRuntime(floodlightProvider, flowPusher);
Brian O'Connor12861f72014-02-19 20:40:32 -080056 eventListener = new EventListener();
57 }
58
59 class EventListener extends Thread
60 implements IEventChannelListener<Long, IntentOperationList> {
61
62 private BlockingQueue<IntentOperationList> intentQueue = new LinkedBlockingQueue<>();
Brian O'Connor488e5ed2014-02-20 19:50:01 -080063 private Long key = Long.valueOf(0);
Brian O'Connor12861f72014-02-19 20:40:32 -080064
65 @Override
66 public void run() {
67 while(true) {
68 try {
69 IntentOperationList intents = intentQueue.take();
Brian O'Connor067b95d2014-02-21 18:43:27 -080070 //TODO: consider draining the remaining intent lists
71 // and processing in one big batch
Brian O'Connor12861f72014-02-19 20:40:32 -080072 processIntents(intents);
73 } catch (InterruptedException e) {
Brian O'Connor5e73c012014-02-20 14:54:34 -080074 log.warn("Error taking from intent queue: {}", e.getMessage());
Brian O'Connor12861f72014-02-19 20:40:32 -080075 }
76 }
77 }
78
79 private void processIntents(IntentOperationList intents) {
Brian O'Connor9b712f62014-02-20 14:22:20 -080080 log.debug("Processing OperationList {}", intents);
Brian O'Connor12861f72014-02-19 20:40:32 -080081 List<Set<FlowEntry>> plan = planCalc.computePlan(intents);
Brian O'Connor9b712f62014-02-20 14:22:20 -080082 log.debug("Plan: {}", plan);
Brian O'Connor488e5ed2014-02-20 19:50:01 -080083 boolean success = planInstall.installPlan(plan);
84
85 sendNotifications(intents, true, success);
86 }
87
88 private void sendNotifications(IntentOperationList intents, boolean installed, boolean success) {
89 IntentStateList states = new IntentStateList();
90 for(IntentOperation i : intents) {
91 IntentState newState;
92 switch(i.operator) {
93 case REMOVE:
94 if(installed) {
95 newState = success ? IntentState.DEL_ACK : IntentState.DEL_PENDING;
96 }
97 else {
98 newState = IntentState.DEL_REQ;
99 }
100 break;
101 case ADD:
102 default:
103 if(installed) {
104 newState = success ? IntentState.INST_ACK : IntentState.INST_NACK;
105 }
106 else {
107 newState = IntentState.INST_REQ;
108 }
109 break;
110 }
111 states.put(i.intent.getId(), newState);
112 }
113 intentStateChannel.addEntry(key, states);
114 key += 1;
Brian O'Connor12861f72014-02-19 20:40:32 -0800115 }
116
117 @Override
118 public void entryAdded(IntentOperationList value) {
Brian O'Connor488e5ed2014-02-20 19:50:01 -0800119 sendNotifications(value, false, false);
120
Brian O'Connor9b712f62014-02-20 14:22:20 -0800121 log.debug("Added OperationList {}", value);
Brian O'Connor5e73c012014-02-20 14:54:34 -0800122 try {
123 intentQueue.put(value);
124 } catch (InterruptedException e) {
125 log.warn("Error putting to intent queue: {}", e.getMessage());
126 }
Brian O'Connor12861f72014-02-19 20:40:32 -0800127 }
128
129 @Override
130 public void entryRemoved(IntentOperationList value) {
131 // This channel is a queue, so this method is not needed
132 }
133
134 @Override
135 public void entryUpdated(IntentOperationList value) {
136 // This channel is a queue, so this method is not needed
137 }
138 }
139 @Override
140 public void startUp(FloodlightModuleContext context) {
Brian O'Connor488e5ed2014-02-20 19:50:01 -0800141 // start subscriber
142 datagridService.addListener(PATH_INTENT_CHANNEL_NAME,
Brian O'Connor5e73c012014-02-20 14:54:34 -0800143 eventListener,
144 Long.class,
145 IntentOperationList.class);
Brian O'Connor12861f72014-02-19 20:40:32 -0800146 eventListener.start();
Brian O'Connor488e5ed2014-02-20 19:50:01 -0800147 // start publisher
148 intentStateChannel = datagridService.createChannel(INTENT_STATE_EVENT_CHANNEL_NAME,
149 Long.class,
150 IntentStateList.class);
Brian O'Connor12861f72014-02-19 20:40:32 -0800151 }
152
153 @Override
154 public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
155 Collection<Class<? extends IFloodlightService>> l =
156 new ArrayList<Class<? extends IFloodlightService>>();
157 l.add(IFloodlightProviderService.class);
Brian O'Connor135a95e2014-02-20 13:48:44 -0800158 l.add(INetworkGraphService.class);
Brian O'Connor12861f72014-02-19 20:40:32 -0800159 l.add(IDatagridService.class);
160 l.add(IFlowPusherService.class);
161 return l;
162 }
163
164 @Override
165 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
Brian O'Connor067b95d2014-02-21 18:43:27 -0800166 // no services, for now
Brian O'Connor12861f72014-02-19 20:40:32 -0800167 return null;
168 }
169
170 @Override
171 public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
Brian O'Connor067b95d2014-02-21 18:43:27 -0800172 // no services, for now
Brian O'Connor12861f72014-02-19 20:40:32 -0800173 return null;
174 }
175
176}