Open Kilda Java Documentation
SwitchEventCollector.java
Go to the documentation of this file.
1 /* Copyright 2017 Telstra Open Source
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 package org.openkilda.floodlight.switchmanager;
17 
32 
33 import net.floodlightcontroller.core.IOFSwitch;
34 import net.floodlightcontroller.core.IOFSwitchListener;
35 import net.floodlightcontroller.core.PortChangeType;
36 import net.floodlightcontroller.core.internal.IOFSwitchService;
37 import net.floodlightcontroller.core.module.FloodlightModuleContext;
38 import net.floodlightcontroller.core.module.FloodlightModuleException;
39 import net.floodlightcontroller.core.module.IFloodlightModule;
40 import net.floodlightcontroller.core.module.IFloodlightService;
41 import org.projectfloodlight.openflow.protocol.OFFlowStatsReply;
42 import org.projectfloodlight.openflow.protocol.OFPortDesc;
43 import org.projectfloodlight.openflow.types.DatapathId;
44 import org.projectfloodlight.openflow.types.OFPort;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47 
48 import java.util.ArrayList;
49 import java.util.Collection;
50 import java.util.HashMap;
51 import java.util.Map;
52 
53 public class SwitchEventCollector implements IFloodlightModule, IOFSwitchListener, IFloodlightService {
54  private static final Logger logger = LoggerFactory.getLogger(SwitchEventCollector.class);
55 
56  private IOFSwitchService switchService;
57  private KafkaMessageProducer kafkaProducer;
58  private ISwitchManager switchManager;
59 
60  private String topoDiscoTopic;
61 
62  /*
63  * IOFSwitchListener methods
64  */
65 
66  private static org.openkilda.messaging.info.event.PortChangeType toJsonType(PortChangeType type) {
67  switch (type) {
68  case ADD:
70  case OTHER_UPDATE:
72  case DELETE:
74  case UP:
76  default:
78  }
79  }
80 
84  @Override
86  public void switchAdded(final DatapathId switchId) {
87  Message message = buildSwitchMessage(switchService.getSwitch(switchId), SwitchState.ADDED);
88  kafkaProducer.postMessage(topoDiscoTopic, message);
89  }
90 
94  @Override
96  public void switchRemoved(final DatapathId switchId) {
97  switchManager.stopSafeMode(switchId);
98  Message message = buildSwitchMessage(switchId, SwitchState.REMOVED);
99  kafkaProducer.postMessage(topoDiscoTopic, message);
100  }
101 
105  @Override
107  public void switchActivated(final DatapathId switchId) {
108  final IOFSwitch sw = switchService.getSwitch(switchId);
109  logger.info("ACTIVATING SWITCH: {}", switchId);
110 
111  // Message message = buildExtendedSwitchMessage(sw, SwitchState.ACTIVATED,
112  // switchManager.dumpFlowTable(switchId));
113  // kafkaProducer.postMessage(topoDiscoTopic, message);
114  ConnectModeRequest.Mode mode = switchManager.connectMode(null);
115 
116  try {
117  if (mode == ConnectModeRequest.Mode.SAFE) {
118  // the bulk of work below is done as part of the safe protocol
119  switchManager.startSafeMode(switchId);
120  return;
121  }
122 
123  switchManager.sendSwitchActivate(sw);
124  if (mode == ConnectModeRequest.Mode.AUTO) {
125  switchManager.installDefaultRules(switchId);
126  }
127 
128  // else MANUAL MODE - Don't install default rules. NB: without the default rules,
129  // ISL discovery will fail.
130  switchManager.sendPortUpEvents(sw);
131  } catch (SwitchOperationException e) {
132  logger.error("Could not activate switch={}", switchId, e);
133  }
134 
135  }
136 
143  public static boolean isPhysicalPort(OFPort p) {
144  return !(p.equals(OFPort.LOCAL)
145  || p.equals(OFPort.ALL)
146  || p.equals(OFPort.CONTROLLER)
147  || p.equals(OFPort.ANY)
148  || p.equals(OFPort.FLOOD)
149  || p.equals(OFPort.ZERO)
150  || p.equals(OFPort.NO_MASK)
151  || p.equals(OFPort.IN_PORT)
152  || p.equals(OFPort.NORMAL)
153  || p.equals(OFPort.TABLE));
154  }
155 
159  @Override
161  public void switchPortChanged(final DatapathId switchId, final OFPortDesc port, final PortChangeType type) {
162  if (isPhysicalPort(port.getPortNo())) {
163  Message message = buildPortMessage(switchId, port, type);
164  kafkaProducer.postMessage(topoDiscoTopic, message);
165  }
166  }
167 
171  @Override
173  public void switchChanged(final DatapathId switchId) {
174  Message message = buildSwitchMessage(switchService.getSwitch(switchId), SwitchState.CHANGED);
175  kafkaProducer.postMessage(topoDiscoTopic, message);
176  }
177 
178  /*
179  * IFloodlightModule methods.
180  */
181 
185  @Override
187  public void switchDeactivated(final DatapathId switchId) {
188  switchManager.stopSafeMode(switchId);
189  Message message = buildSwitchMessage(switchId, SwitchState.DEACTIVATED);
190  kafkaProducer.postMessage(topoDiscoTopic, message);
191  }
192 
196  @Override
197  public Collection<Class<? extends IFloodlightService>> getModuleServices() {
198  Collection<Class<? extends IFloodlightService>> services = new ArrayList<>(1);
199  services.add(SwitchEventCollector.class);
200  return services;
201  }
202 
206  @Override
207  public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
208  Map<Class<? extends IFloodlightService>, IFloodlightService> map = new HashMap<>();
209  map.put(SwitchEventCollector.class, this);
210  return map;
211  }
212 
216  @Override
217  public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
218  Collection<Class<? extends IFloodlightService>> services = new ArrayList<>(3);
219  services.add(IOFSwitchService.class);
220  services.add(KafkaMessageProducer.class);
221  services.add(ISwitchManager.class);
222  return services;
223  }
224 
228  @Override
229  public void init(FloodlightModuleContext context) throws FloodlightModuleException {
230  switchService = context.getServiceImpl(IOFSwitchService.class);
231  kafkaProducer = context.getServiceImpl(KafkaMessageProducer.class);
232  switchManager = context.getServiceImpl(ISwitchManager.class);
233 
234  ConfigurationProvider provider = ConfigurationProvider.of(context, this);
235  KafkaTopicsConfig topicsConfig = provider.getConfiguration(KafkaTopicsConfig.class);
236  topoDiscoTopic = topicsConfig.getTopoDiscoTopic();
237  }
238 
239  /*
240  * Utility functions
241  */
242 
246  @Override
247  public void startUp(FloodlightModuleContext context) throws FloodlightModuleException {
248  logger.info("Starting " + SwitchEventCollector.class.getCanonicalName());
249  switchService.addOFSwitchListener(this);
250  }
251 
260  private Message buildExtendedSwitchMessage(final IOFSwitch sw, final SwitchState eventType,
261  OFFlowStatsReply flowStats) {
262  return buildMessage(IofSwitchConverter.buildSwitchInfoDataExtended(sw, eventType, flowStats));
263  }
264 
272  public static Message buildSwitchMessage(final IOFSwitch sw, final SwitchState eventType) {
273  return buildMessage(IofSwitchConverter.buildSwitchInfoData(sw, eventType));
274  }
275 
283  public static Message buildSwitchMessage(final DatapathId switchId, final SwitchState eventType) {
284  final String unknown = "unknown";
285 
286  InfoData data = new SwitchInfoData(new SwitchId(switchId.getLong()), eventType,
287  unknown, unknown, unknown, unknown);
288  return buildMessage(data);
289  }
290 
297  public static Message buildMessage(final InfoData data) {
298  return new InfoMessage(data, System.currentTimeMillis(), CorrelationContext.getId(), null);
299  }
300 
309  public static Message buildPortMessage(final DatapathId switchId, final OFPort port, final PortChangeType type) {
310  InfoData data = new PortInfoData(new SwitchId(switchId.getLong()), port.getPortNumber(),
311  null, toJsonType(type));
312  return buildMessage(data);
313  }
314 
323  private Message buildPortMessage(final DatapathId switchId, final OFPortDesc port, final PortChangeType type) {
324  InfoData data = new PortInfoData(new SwitchId(switchId.getLong()), port.getPortNo().getPortNumber(),
325  null, toJsonType(type));
326  return buildMessage(data);
327  }
328 }
static Message buildSwitchMessage(final DatapathId switchId, final SwitchState eventType)
static Message buildSwitchMessage(final IOFSwitch sw, final SwitchState eventType)
static SwitchInfoExtendedData buildSwitchInfoDataExtended(IOFSwitch sw, SwitchState eventType, OFFlowStatsReply flowStats)
Collection< Class<? extends IFloodlightService > > getModuleDependencies()
void switchPortChanged(final DatapathId switchId, final OFPortDesc port, final PortChangeType type)
static SwitchInfoData buildSwitchInfoData(IOFSwitch sw, SwitchState eventType)
static Message buildPortMessage(final DatapathId switchId, final OFPort port, final PortChangeType type)
Collection< Class<? extends IFloodlightService > > getModuleServices()
static ConfigurationProvider of(FloodlightModuleContext moduleContext, IFloodlightModule module)
void postMessage(final String topic, final Message message)
ConnectModeRequest.Mode connectMode(final ConnectModeRequest.Mode mode)
Map< Class<? extends IFloodlightService >, IFloodlightService > getServiceImpls()
net
Definition: plan-b.py:46