blob: 3ee164f92464ef86e915797f0189544ffccd8768 [file] [log] [blame]
Ray Milkey18b44ac2014-08-22 08:29:47 -07001package net.onrc.onos.core.matchaction;
2
Ray Milkey18b44ac2014-08-22 08:29:47 -07003import java.util.ArrayList;
Ray Milkey18b44ac2014-08-22 08:29:47 -07004import java.util.EventListener;
5import java.util.HashMap;
6import java.util.HashSet;
7import java.util.List;
8import java.util.Map;
9import java.util.Set;
10import java.util.concurrent.ArrayBlockingQueue;
11import java.util.concurrent.BlockingQueue;
12import java.util.concurrent.ConcurrentHashMap;
13import java.util.concurrent.ConcurrentMap;
14import java.util.concurrent.ExecutionException;
15
Brian O'Connoraa5a7b92014-08-29 14:45:18 -070016import net.floodlightcontroller.core.IFloodlightProviderService;
17import net.floodlightcontroller.core.internal.OFMessageFuture;
18import net.floodlightcontroller.core.module.IFloodlightService;
19import net.onrc.onos.api.flowmanager.ConflictDetectionPolicy;
20import net.onrc.onos.core.datagrid.IDatagridService;
21import net.onrc.onos.core.datagrid.IEventChannel;
22import net.onrc.onos.core.datagrid.IEventChannelListener;
23import net.onrc.onos.core.flowprogrammer.IFlowPusherService;
Ray Milkey626a2b12014-09-02 11:19:06 -070024import net.onrc.onos.core.registry.IControllerRegistryService;
Brian O'Connoraa5a7b92014-08-29 14:45:18 -070025import net.onrc.onos.core.util.Dpid;
Ray Milkey626a2b12014-09-02 11:19:06 -070026import net.onrc.onos.core.util.IdBlockAllocator;
Brian O'Connoraa5a7b92014-08-29 14:45:18 -070027import net.onrc.onos.core.util.IdGenerator;
28import net.onrc.onos.core.util.SwitchPort;
29
30import org.apache.commons.lang3.tuple.Pair;
31import org.projectfloodlight.openflow.protocol.OFBarrierReply;
32import org.slf4j.Logger;
33import org.slf4j.LoggerFactory;
Ray Milkey18b44ac2014-08-22 08:29:47 -070034
Ray Milkey18b44ac2014-08-22 08:29:47 -070035/**
36 * Manages Match-Action entries.
37 * <p>
38 * TODO: Make all methods thread-safe
39 */
40public class MatchActionComponent implements MatchActionService, IFloodlightService {
41
42 private static final Logger log = LoggerFactory.getLogger(MatchActionService.class);
Ray Milkeya313cde2014-09-05 09:02:52 -070043 private final IFlowPusherService pusher;
44 private final IFloodlightProviderService provider;
Ray Milkey18b44ac2014-08-22 08:29:47 -070045
Ray Milkeya313cde2014-09-05 09:02:52 -070046 private final ConcurrentMap<MatchActionId, MatchAction> matchActionMap = new ConcurrentHashMap<>();
47 private final ConcurrentMap<MatchActionOperationsId, MatchActionOperations> matchSetMap =
Ray Milkey18b44ac2014-08-22 08:29:47 -070048 new ConcurrentHashMap<>();
49 // TODO - want something better here for the resolved Queue
Ray Milkeya313cde2014-09-05 09:02:52 -070050 private final BlockingQueue<MatchActionOperationsId> resolvedQueue = new ArrayBlockingQueue<>(100);
51 private final BlockingQueue<MatchActionOperations> installationWorkQueue = new ArrayBlockingQueue<>(100);
Ray Milkey18b44ac2014-08-22 08:29:47 -070052
Brian O'Connorab3e9e62014-09-09 23:45:55 -070053 private IEventChannel<Long, MatchActionOperations> installSetChannel;
Ray Milkey18b44ac2014-08-22 08:29:47 -070054 private IEventChannel<String, SwitchResultList> installSetReplyChannel;
55
Ray Milkey18b44ac2014-08-22 08:29:47 -070056 private final IDatagridService datagrid;
Ray Milkeya313cde2014-09-05 09:02:52 -070057 private final IControllerRegistryService registryService;
Ray Milkey626a2b12014-09-02 11:19:06 -070058
59 private MatchActionIdGeneratorWithIdBlockAllocator matchActionIdGenerator;
60 private MatchActionOperationsIdGeneratorWithIdBlockAllocator matchActionOperationsIdGenerator;
Ray Milkey18b44ac2014-08-22 08:29:47 -070061
Ray Milkeya313cde2014-09-05 09:02:52 -070062 /**
63 * Constructs a MatchActionComponent given the services it depends on.
64 *
65 * @param newDatagrid datagrid dependency
66 * @param newPusher flow pusher dependency
67 * @param newProvider provider used for switch queries
68 * @param newRegistryService registry for ID block allocation
69 */
Ray Milkey18b44ac2014-08-22 08:29:47 -070070 public MatchActionComponent(final IDatagridService newDatagrid,
71 final IFlowPusherService newPusher,
Ray Milkey626a2b12014-09-02 11:19:06 -070072 final IFloodlightProviderService newProvider,
73 final IControllerRegistryService newRegistryService) {
Ray Milkey18b44ac2014-08-22 08:29:47 -070074 datagrid = newDatagrid;
75 pusher = newPusher;
76 provider = newProvider;
Ray Milkey626a2b12014-09-02 11:19:06 -070077 registryService = newRegistryService;
Ray Milkey18b44ac2014-08-22 08:29:47 -070078 }
79
Ray Milkeya313cde2014-09-05 09:02:52 -070080 /**
81 * Starts the component. Created channels used for communication and
82 * creates producer and consumer threads.
83 */
Ray Milkey18b44ac2014-08-22 08:29:47 -070084 public void start() {
Ray Milkey626a2b12014-09-02 11:19:06 -070085 IdBlockAllocator idBlockAllocator = registryService;
86 matchActionIdGenerator =
87 new MatchActionIdGeneratorWithIdBlockAllocator(idBlockAllocator);
88 matchActionOperationsIdGenerator =
89 new MatchActionOperationsIdGeneratorWithIdBlockAllocator(idBlockAllocator);
90
Brian O'Connorab3e9e62014-09-09 23:45:55 -070091 final Installer installerListener = new Installer();
92 installSetChannel = datagrid.addListener(
93 "onos.matchaction.installSetChannel",
94 installerListener,
95 Long.class,
Ray Milkey18b44ac2014-08-22 08:29:47 -070096 MatchActionOperations.class);
97
Brian O'Connorab3e9e62014-09-09 23:45:55 -070098
99 final Coordinator coordinator = new Coordinator();
100 coordinator.start();
101 installSetReplyChannel = datagrid.addListener(
102 "onos.matchaction.installSetReplyChannel",
103 coordinator,
Ray Milkey18b44ac2014-08-22 08:29:47 -0700104 String.class,
105 SwitchResultList.class);
106
Ray Milkeya313cde2014-09-05 09:02:52 -0700107 // TODO Single instance for now, should be a work queue of some sort eventually
Brian O'Connorab3e9e62014-09-09 23:45:55 -0700108 final InstallerWorker installer = new InstallerWorker();
Ray Milkey18b44ac2014-08-22 08:29:47 -0700109 installer.start();
Brian O'Connor7e2d9142014-09-02 17:24:27 -0700110
Ray Milkey18b44ac2014-08-22 08:29:47 -0700111 }
112
Ray Milkeya313cde2014-09-05 09:02:52 -0700113 /**
114 * Installs a set of MatchActionOperations.
115 *
116 * @param matchSet the set of MatchActions to install
117 * @return identifier of the installed operations
118 */
Ray Milkey18b44ac2014-08-22 08:29:47 -0700119 public MatchActionOperationsId installMatchActionOperations(MatchActionOperations matchSet) {
120 if (checkResolved(matchSet)) {
121 matchSet.setState(MatchActionOperationsState.RESOLVED);
122 } else {
123 matchSet.setState(MatchActionOperationsState.INIT);
124 }
Brian O'Connor7e2d9142014-09-02 17:24:27 -0700125 log.trace("MatchActionsOperations set added: {} {} {}",
126 matchSet.getOperationsId(),
127 matchSet.getState(),
128 matchSet.toString());
Ray Milkey18b44ac2014-08-22 08:29:47 -0700129 matchSetMap.put(matchSet.getOperationsId(), matchSet);
130 if (matchSet.getState() == MatchActionOperationsState.RESOLVED) {
131 resolvedQueue.add(matchSet.getOperationsId());
132 }
133 return matchSet.getOperationsId();
134 }
135
Ray Milkeya313cde2014-09-05 09:02:52 -0700136 /**
137 * Returns the state of a set of operations.
138 *
139 * @param matchSetId identifier of the MatchActionOperations being queried.
140 * @return state of the given operations
141 */
Ray Milkey18b44ac2014-08-22 08:29:47 -0700142 public MatchActionOperationsState getMatchActionOperationsState(MatchActionOperationsId matchSetId) {
143 MatchActionOperations set = matchSetMap.get(matchSetId);
144 return (set == null) ? null : set.getState();
145 }
146
Ray Milkeya313cde2014-09-05 09:02:52 -0700147 /**
148 * Checks if a given set of operations has all of its dependencies resolved.
149 *
150 * @param matchSet Operations set to check
151 * @return true if all dependencies are resolved, false otherwise
152 */
153 private boolean checkResolved(MatchActionOperations matchSet) {
Ray Milkey18b44ac2014-08-22 08:29:47 -0700154 boolean resolved = true;
155 for (MatchActionOperationsId setId : matchSet.getDependencies()) {
156 MatchActionOperations set = matchSetMap.get(setId);
157 if (set == null || set.getState() != MatchActionOperationsState.RESOLVED) {
158 resolved = false;
159 break;
160 }
161 }
162 return resolved;
163 }
164
Ray Milkeya313cde2014-09-05 09:02:52 -0700165 /**
166 * Producer class for MatchActionOperations. An instance of this runs on
167 * each ONOS node. Requests come in via the resolved queue, and are
168 * distributed to workers running on each ONOS instance via a channel.
169 */
170 private final class Coordinator extends Thread
Ray Milkey18b44ac2014-08-22 08:29:47 -0700171 implements IEventChannelListener<String, SwitchResultList> {
172
Ray Milkeya313cde2014-09-05 09:02:52 -0700173 private final Map<MatchActionOperationsId,
174 Map<Dpid, SwitchResult>>
175 pendingMatchActionOperations = new HashMap<>();
Ray Milkey18b44ac2014-08-22 08:29:47 -0700176
Ray Milkeya313cde2014-09-05 09:02:52 -0700177 /**
178 * Default constructor.
179 */
180 Coordinator() {
Brian O'Connorab3e9e62014-09-09 23:45:55 -0700181 // nothing to initialize
Ray Milkey18b44ac2014-08-22 08:29:47 -0700182 }
183
184 @Override
185 public void run() {
Ray Milkeya313cde2014-09-05 09:02:52 -0700186 //noinspection InfiniteLoopStatement - for IntelliJ
Ray Milkey18b44ac2014-08-22 08:29:47 -0700187 while (true) {
188 // 1. Remove MatchActionOperations(s) from the Global Resolved Queue
189 try {
190 MatchActionOperationsId setId = resolvedQueue.take();
191 processSet(setId);
192 } catch (InterruptedException e) {
193 log.warn("Error taking from resolved queue: {}", e.getMessage());
194 }
195 }
196 }
197
Ray Milkeya313cde2014-09-05 09:02:52 -0700198 /**
199 * Processes an inbound MatchActionOperations object.
200 *
201 * @param setId Identifier of the MatchActionOperations object
202 */
Ray Milkey18b44ac2014-08-22 08:29:47 -0700203 private void processSet(MatchActionOperationsId setId) {
204 MatchActionOperations matchSet = matchSetMap.get(setId);
205 matchSet.setState(MatchActionOperationsState.PENDING);
206 matchSetMap.put(setId, matchSet);
207
208 // TODO apply updates to in-memory flow table and resolve conflicts
209 // TODO generate apply and undo sets, using MatchActionOperations for now...
210
211 // build pending switches set for coordinator tracking
212 Map<Dpid, SwitchResult> switches = new HashMap<>();
Brian O'Connoraa5a7b92014-08-29 14:45:18 -0700213 for (MatchActionOperationEntry matchActionOp : matchSet.getOperations()) {
214 MatchAction matchAction = matchActionOp.getTarget();
215 SwitchPort sw = matchAction.getSwitchPort();
Ray Milkey18b44ac2014-08-22 08:29:47 -0700216 switches.put(sw.getDpid(), new SwitchResult(setId, sw.getDpid()));
Brian O'Connoraa5a7b92014-08-29 14:45:18 -0700217 switch(matchActionOp.getOperator()) {
218 case ADD:
219 matchActionMap.put(matchAction.getId(), matchAction);
220 break;
221 case REMOVE:
Brian O'Connor7e2d9142014-09-02 17:24:27 -0700222 // TODO we may want to be more careful when removing MatchActions
223 matchActionMap.remove(matchAction.getId());
224 break;
Brian O'Connoraa5a7b92014-08-29 14:45:18 -0700225 default:
226 throw new UnsupportedOperationException(
227 "Unsupported MatchAction operation" +
228 matchActionOp.getOperator().toString());
229 }
Ray Milkey18b44ac2014-08-22 08:29:47 -0700230 }
Brian O'Connor7e2d9142014-09-02 17:24:27 -0700231 pendingMatchActionOperations.put(setId, switches);
Ray Milkey18b44ac2014-08-22 08:29:47 -0700232
233 // distribute apply/undo sets to cluster
Brian O'Connorab3e9e62014-09-09 23:45:55 -0700234 log.trace("MatchAction Coordinator distributing set: {}", matchSet);
235 installSetChannel.addTransientEntry(setId.getId(), matchSet);
Ray Milkey18b44ac2014-08-22 08:29:47 -0700236 }
237
238 @Override
239 public void entryAdded(SwitchResultList value) {
240 updateSwitchResults(value);
241 }
242
243 @Override
244 public void entryRemoved(SwitchResultList value) {
245 // noop
246 }
247
248 @Override
249 public void entryUpdated(SwitchResultList value) {
250 updateSwitchResults(value);
251 }
252
Ray Milkeya313cde2014-09-05 09:02:52 -0700253 /**
254 * Processes the response from a consumer.
255 *
256 * @param results List of switches modified by the consumer
257 */
Ray Milkey18b44ac2014-08-22 08:29:47 -0700258 private void updateSwitchResults(SwitchResultList results) {
259 if (results == null || results.size() == 0) {
260 return;
261 }
262 MatchActionOperationsId matchSetId = results.get(0).getMatchActionOperationsId();
263
264 // apply updates from results list
Brian O'Connor7e2d9142014-09-02 17:24:27 -0700265 Map<Dpid, SwitchResult> resultMap = pendingMatchActionOperations.get(matchSetId);
Ray Milkey18b44ac2014-08-22 08:29:47 -0700266 for (SwitchResult result : results) {
267 SwitchResult resultToUpdate = resultMap.get(result.getSwitch());
268 if (resultToUpdate != null) {
269 resultToUpdate.setStatus(result.getStatus());
270 }
271 // else {
272 // TODO error!
273 // }
274 }
275
276 // check to see the overall outcome of the install operation
277 SwitchResult.Status setResult = SwitchResult.Status.SUCCESS;
278 for (SwitchResult result : resultMap.values()) {
279 if (result.getStatus().equals(SwitchResult.Status.FAILURE)) {
280 setResult = SwitchResult.Status.FAILURE;
281 // if any switch fails, we fail the installation
282 break;
283 } else if (!setResult.equals(SwitchResult.Status.FAILURE)
284 && result.getStatus().equals(SwitchResult.Status.UNKNOWN)) {
285 setResult = SwitchResult.Status.UNKNOWN;
286 }
287 }
288 switch (setResult) {
289 case SUCCESS:
290 // mark MatchActionOperations as INSTALLED
291 MatchActionOperations matchSet = matchSetMap.get(matchSetId);
292 matchSet.setState(MatchActionOperationsState.INSTALLED);
293 matchSetMap.replace(matchSetId, matchSet);
Brian O'Connor7e2d9142014-09-02 17:24:27 -0700294 pendingMatchActionOperations.remove(matchSetId);
Ray Milkey18b44ac2014-08-22 08:29:47 -0700295
296 // TODO update dependent sets as needed
297 break;
298 case FAILURE:
299 // mark MatchActionOperations as FAILED
300 matchSet = matchSetMap.get(matchSetId);
301 matchSet.setState(MatchActionOperationsState.FAILED);
302 matchSetMap.replace(matchSetId, matchSet);
303
304 // TODO instruct installers to install Undo set
Brian O'Connor7e2d9142014-09-02 17:24:27 -0700305 // TODO the pendingMatchActionOperations state needs to be cleaned-up
Ray Milkey18b44ac2014-08-22 08:29:47 -0700306 break;
307 case UNKNOWN:
Brian O'Connor7e2d9142014-09-02 17:24:27 -0700308 // FALLTHROUGH
Ray Milkey18b44ac2014-08-22 08:29:47 -0700309 default:
310 // noop, still waiting for results
311 // TODO: check to see if installers are dead after timeout
Brian O'Connor7e2d9142014-09-02 17:24:27 -0700312 break;
Ray Milkey18b44ac2014-08-22 08:29:47 -0700313 }
314 }
315 }
316
Ray Milkeya313cde2014-09-05 09:02:52 -0700317 /**
318 * Worker thread that pushes MatchActionOperations to the switches via
319 * the FlowPusher.
320 */
321 private class InstallerWorker extends Thread {
322
323 /**
324 * Default constructor.
325 */
326 InstallerWorker() {
327 // nothing to initialize
328 }
Ray Milkey18b44ac2014-08-22 08:29:47 -0700329
330 // Note: we should consider using an alternative representation for
331 // apply sets
Ray Milkeya313cde2014-09-05 09:02:52 -0700332
333 /**
334 * Installs a set of MatchActionOperations using the Flow Pusher.
335 *
336 * @param matchSet set of MatchActions to install
337 */
338 private void install(MatchActionOperations matchSet) {
Brian O'Connoraa5a7b92014-08-29 14:45:18 -0700339 Set<Long> masterDpids = provider.getAllMasterSwitchDpids();
Ray Milkey18b44ac2014-08-22 08:29:47 -0700340
Brian O'Connoraa5a7b92014-08-29 14:45:18 -0700341 Set<MatchActionOperationEntry> installSet = new HashSet<>();
342 Set<Dpid> modifiedSwitches = new HashSet<>();
Ray Milkey18b44ac2014-08-22 08:29:47 -0700343
Brian O'Connoraa5a7b92014-08-29 14:45:18 -0700344 for (MatchActionOperationEntry matchActionOp : matchSet.getOperations()) {
345 MatchAction matchAction = matchActionOp.getTarget();
346 Dpid dpid = matchAction.getSwitchPort().getDpid();
347 if (masterDpids.contains(dpid.value())) {
348 // only install if we are the master
349 // TODO this optimization will introduce some nice race
350 // conditions on failure requiring mastership change
351 installSet.add(matchActionOp);
352 modifiedSwitches.add(dpid);
Ray Milkey18b44ac2014-08-22 08:29:47 -0700353 }
Ray Milkey18b44ac2014-08-22 08:29:47 -0700354 }
355
356 // push flow entries to switches
Brian O'Connoraa5a7b92014-08-29 14:45:18 -0700357 pusher.pushMatchActions(installSet);
Ray Milkey18b44ac2014-08-22 08:29:47 -0700358
359 // insert a barrier after each phase on each modifiedSwitch
360 // wait for confirmation messages before proceeding
Brian O'Connoraa5a7b92014-08-29 14:45:18 -0700361 List<Pair<Dpid, OFMessageFuture<OFBarrierReply>>> barriers = new ArrayList<>();
362 for (Dpid dpid : modifiedSwitches) {
363 barriers.add(Pair.of(dpid, pusher.barrierAsync(dpid)));
Ray Milkey18b44ac2014-08-22 08:29:47 -0700364 }
365 List<SwitchResult> switchResults = new ArrayList<>();
Brian O'Connoraa5a7b92014-08-29 14:45:18 -0700366 for (Pair<Dpid, OFMessageFuture<OFBarrierReply>> pair : barriers) {
367 Dpid dpid = pair.getLeft();
Ray Milkey18b44ac2014-08-22 08:29:47 -0700368 OFMessageFuture<OFBarrierReply> future = pair.getRight();
Brian O'Connoraa5a7b92014-08-29 14:45:18 -0700369 SwitchResult switchResult = new SwitchResult(matchSet.getOperationsId(),
370 dpid);
Ray Milkey18b44ac2014-08-22 08:29:47 -0700371 try {
372 future.get();
373 switchResult.setStatus(SwitchResult.Status.SUCCESS);
374 } catch (InterruptedException | ExecutionException e) {
Brian O'Connoraa5a7b92014-08-29 14:45:18 -0700375 log.error("Barrier message not received for sw: {}", dpid);
Ray Milkey18b44ac2014-08-22 08:29:47 -0700376 switchResult.setStatus(SwitchResult.Status.FAILURE);
377 }
378 switchResults.add(switchResult);
379 }
380
381 // send update message to coordinator
382 // TODO: we might want to use another ID here, i.e. GUID, to avoid
383 // overlap
384 final SwitchResultList switchResultList = new SwitchResultList();
385 switchResultList.addAll(switchResults);
386 installSetReplyChannel.addTransientEntry(matchSet.getOperationsId().toString(),
387 switchResultList);
388 }
389
Ray Milkey18b44ac2014-08-22 08:29:47 -0700390 @Override
391 public void run() {
Ray Milkeya313cde2014-09-05 09:02:52 -0700392 //noinspection InfiniteLoopStatement - for IntelliJ
Ray Milkey18b44ac2014-08-22 08:29:47 -0700393 while (true) {
394 // 1. Remove MatchActionOperations(s) from the Global Resolved Queue
395 try {
396 MatchActionOperations operations = installationWorkQueue.take();
397 install(operations);
398 } catch (InterruptedException e) {
399 log.warn("Error taking from installation queue: {}", e.getMessage());
400 }
401 }
402 }
403 }
404
Ray Milkeya313cde2014-09-05 09:02:52 -0700405 /**
406 * Consumer class for MatchActionOperations. Listens on the MatchAction
407 * channel and places inbound requests on a queue to be handled by the
408 * InstallerWorker threads.
409 */
Ray Milkey18b44ac2014-08-22 08:29:47 -0700410 class Installer
Brian O'Connorab3e9e62014-09-09 23:45:55 -0700411 implements IEventChannelListener<Long, MatchActionOperations> {
Ray Milkey18b44ac2014-08-22 08:29:47 -0700412
413 @Override
414 public void entryAdded(MatchActionOperations value) {
Brian O'Connor7e2d9142014-09-02 17:24:27 -0700415 try {
Brian O'Connorab3e9e62014-09-09 23:45:55 -0700416 log.trace("MatchAction Installer receiving set: {}", value);
Brian O'Connor7e2d9142014-09-02 17:24:27 -0700417 installationWorkQueue.put(value);
418 } catch (InterruptedException e) {
419 log.warn("Error adding to installer work queue: {}",
420 e.getMessage());
421 }
Ray Milkey18b44ac2014-08-22 08:29:47 -0700422 }
423
424 @Override
425 public void entryRemoved(MatchActionOperations value) {
426 // noop
427 }
428
429 @Override
430 public void entryUpdated(MatchActionOperations value) {
Brian O'Connor7e2d9142014-09-02 17:24:27 -0700431 try {
Brian O'Connorab3e9e62014-09-09 23:45:55 -0700432 log.trace("MatchAction Installer receiving set: {}", value);
Brian O'Connor7e2d9142014-09-02 17:24:27 -0700433 installationWorkQueue.put(value);
434 } catch (InterruptedException e) {
435 log.warn("Error adding to installer work queue: {}",
436 e.getMessage());
437 }
Ray Milkey18b44ac2014-08-22 08:29:47 -0700438 }
439 }
440
Ray Milkey18b44ac2014-08-22 08:29:47 -0700441 @Override
442 public boolean addMatchAction(MatchAction matchAction) {
443 return false;
444 }
445
446 @Override
447 public Set<MatchAction> getMatchActions() {
Ray Milkey80dc8c92014-09-03 13:49:46 -0700448 return new HashSet<>(matchActionMap.values());
Ray Milkey18b44ac2014-08-22 08:29:47 -0700449 }
450
451 @Override
452 public boolean executeOperations(final MatchActionOperations operations) {
453 installMatchActionOperations(operations);
Ray Milkey80dc8c92014-09-03 13:49:46 -0700454 // TODO how to generate an actual error response here
455 return true;
Ray Milkey18b44ac2014-08-22 08:29:47 -0700456 }
457
458 @Override
459 public void setConflictDetectionPolicy(ConflictDetectionPolicy policy) {
460 // TODO Auto-generated method stub
461
462 }
463
464 @Override
465 public ConflictDetectionPolicy getConflictDetectionPolicy() {
466 // TODO Auto-generated method stub
467 return null;
468 }
469
470 @Override
471 public void addEventListener(EventListener listener) {
472 // TODO Auto-generated method stub
473
474 }
475
476 @Override
477 public void removeEventListener(EventListener listener) {
478 // TODO Auto-generated method stub
479
480 }
481
482 @Override
483 public IdGenerator<MatchActionId> getMatchActionIdGenerator() {
Ray Milkey626a2b12014-09-02 11:19:06 -0700484 return matchActionIdGenerator;
Ray Milkey18b44ac2014-08-22 08:29:47 -0700485 }
486
487 @Override
488 public IdGenerator<MatchActionOperationsId> getMatchActionOperationsIdGenerator() {
Ray Milkey626a2b12014-09-02 11:19:06 -0700489 return matchActionOperationsIdGenerator;
Ray Milkey18b44ac2014-08-22 08:29:47 -0700490 }
491
492}