2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.openflowplugin.openflow.md.core.session;
11 import com.google.common.util.concurrent.ListeningExecutorService;
12 import java.util.Arrays;
13 import java.util.Collection;
14 import java.util.List;
16 import java.util.Map.Entry;
17 import java.util.concurrent.ConcurrentHashMap;
18 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
19 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
20 import org.opendaylight.openflowplugin.api.openflow.md.core.SwitchConnectionDistinguisher;
21 import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey;
22 import org.opendaylight.openflowplugin.api.statistics.MessageSpy;
23 import org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductor;
24 import org.opendaylight.openflowplugin.openflow.md.core.IMDMessageTranslator;
25 import org.opendaylight.openflowplugin.openflow.md.core.extension.ExtensionConverterProvider;
26 import org.opendaylight.openflowplugin.openflow.md.queue.PopListener;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
28 import org.opendaylight.yangtools.concepts.ListenerRegistration;
29 import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
30 import org.opendaylight.yangtools.yang.binding.DataContainer;
31 import org.opendaylight.yangtools.yang.binding.DataObject;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
38 public class SessionManagerOFImpl implements SessionManager {
40 protected static final Logger LOG = LoggerFactory.getLogger(SessionManagerOFImpl.class);
41 private static SessionManagerOFImpl instance;
42 private ConcurrentHashMap<SwitchSessionKeyOF, SessionContext> sessionLot;
43 private Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> translatorMapping;
44 private Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> popListenerMapping;
46 protected ListenerRegistry<SessionListener> sessionListeners;
47 private NotificationProviderService notificationProviderService;
49 private DataBroker dataBroker;
50 private ListeningExecutorService rpcPool;
54 * @return singleton instance
56 public static SessionManager getInstance() {
57 if (instance == null) {
58 synchronized (SessionContextOFImpl.class) {
59 if (instance == null) {
60 instance = new SessionManagerOFImpl();
68 * close and release singleton instace
70 public static void releaseInstance() {
71 if (instance != null) {
72 synchronized (SessionManagerOFImpl.class) {
73 if (instance != null) {
81 private SessionManagerOFImpl() {
82 LOG.debug("singleton creating");
83 sessionLot = new ConcurrentHashMap<>();
84 sessionListeners = new ListenerRegistry<>();
88 public SessionContext getSessionContext(SwitchSessionKeyOF sessionKey) {
89 return sessionLot.get(sessionKey);
93 public void invalidateSessionContext(SwitchSessionKeyOF sessionKey) {
94 SessionContext context = getSessionContext(sessionKey);
95 if (context == null) {
96 LOG.warn("context for invalidation not found");
98 synchronized (context) {
99 for (Entry<SwitchConnectionDistinguisher, ConnectionConductor> auxEntry : context.getAuxiliaryConductors()) {
100 invalidateAuxiliary(sessionKey, auxEntry.getKey());
102 context.getPrimaryConductor().disconnect();
103 context.setValid(false);
104 removeSessionContext(context);
105 // TODO:: notify listeners
110 private void invalidateDeadSessionContext(SessionContext sessionContext) {
111 if (sessionContext == null) {
112 LOG.warn("context for invalidation not found");
114 synchronized (sessionContext) {
115 for (Entry<SwitchConnectionDistinguisher, ConnectionConductor> auxEntry : sessionContext
116 .getAuxiliaryConductors()) {
117 invalidateAuxiliary(sessionContext, auxEntry.getKey(), true);
119 sessionContext.setValid(false);
120 removeSessionContext(sessionContext);
121 // TODO:: notify listeners
126 private void removeSessionContext(SessionContext sessionContext) {
127 if (LOG.isDebugEnabled()) {
128 LOG.debug("removing session: {}", Arrays.toString(sessionContext.getSessionKey().getId()));
130 sessionLot.remove(sessionContext.getSessionKey(), sessionContext);
131 sessionNotifier.onSessionRemoved(sessionContext);
135 public void addSessionContext(SwitchSessionKeyOF sessionKey, SessionContext context) {
136 synchronized (context) {
137 sessionLot.put(sessionKey, context);
138 sessionNotifier.onSessionAdded(sessionKey, context);
140 context.setValid(true);
145 public void invalidateAuxiliary(SwitchSessionKeyOF sessionKey,
146 SwitchConnectionDistinguisher connectionCookie) {
147 SessionContext context = getSessionContext(sessionKey);
148 invalidateAuxiliary(context, connectionCookie, true);
153 * @param connectionCookie
154 * @param disconnect true if auxiliary connection is to be disconnected
156 private static void invalidateAuxiliary(SessionContext context, SwitchConnectionDistinguisher connectionCookie,
157 boolean disconnect) {
158 if (context == null) {
159 LOG.warn("context for invalidation not found");
161 ConnectionConductor auxiliaryConductor = context.removeAuxiliaryConductor(connectionCookie);
162 if (auxiliaryConductor == null) {
163 LOG.warn("auxiliary conductor not found");
166 auxiliaryConductor.disconnect();
173 public void invalidateOnDisconnect(ConnectionConductor conductor) {
174 if (conductor.getAuxiliaryKey() == null) {
175 invalidateDeadSessionContext(conductor.getSessionContext());
176 // TODO:: notify listeners
178 invalidateAuxiliary(conductor.getSessionContext(), conductor.getAuxiliaryKey(), false);
183 public void setTranslatorMapping(Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> translatorMapping) {
184 this.translatorMapping = translatorMapping;
188 public ListenerRegistration<SessionListener> registerSessionListener(SessionListener listener) {
189 LOG.debug("registerSessionListener");
190 return sessionListeners.register(listener);
193 private final SessionListener sessionNotifier = new SessionListener() {
196 public void onSessionAdded(SwitchSessionKeyOF sessionKey, SessionContext context) {
197 for (ListenerRegistration<SessionListener> listener : sessionListeners) {
199 listener.getInstance().onSessionAdded(sessionKey, context);
200 } catch (Exception e) {
201 LOG.error("Unhandled exeption occured while invoking onSessionAdded on listener", e);
207 public void onSessionRemoved(SessionContext context) {
208 for (ListenerRegistration<SessionListener> listener : sessionListeners) {
210 listener.getInstance().onSessionRemoved(context);
211 } catch (Exception e) {
212 LOG.error("Unhandled exeption occured while invoking onSessionRemoved on listener", e);
217 private MessageSpy<DataContainer> messageSpy;
218 private ExtensionConverterProvider extensionConverterProvider;
222 public Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> getTranslatorMapping() {
223 return this.translatorMapping;
227 public void setNotificationProviderService(
228 NotificationProviderService notificationProviderService) {
229 this.notificationProviderService = notificationProviderService;
234 public DataBroker getDataBroker() {
239 public void setDataBroker(DataBroker dataBroker) {
240 this.dataBroker = dataBroker;
245 public NotificationProviderService getNotificationProviderService() {
246 return notificationProviderService;
250 public Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> getPopListenerMapping() {
251 return popListenerMapping;
255 public void setPopListenerMapping(
256 Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> popListenerMapping) {
257 this.popListenerMapping = popListenerMapping;
261 public void close() {
263 sessionListeners = null;
264 synchronized (sessionLot) {
265 for (SessionContext sessionContext : sessionLot.values()) {
266 sessionContext.getPrimaryConductor().disconnect();
268 // TODO: handle timeouted shutdown
274 public void setRpcPool(ListeningExecutorService rpcPool) {
275 this.rpcPool = rpcPool;
279 public ListeningExecutorService getRpcPool() {
284 public void setMessageSpy(MessageSpy<DataContainer> messageSpy) {
285 this.messageSpy = messageSpy;
289 public MessageSpy<DataContainer> getMessageSpy() {
294 public void setExtensionConverterProvider(
295 ExtensionConverterProvider extensionConverterProvider) {
296 this.extensionConverterProvider = extensionConverterProvider;
300 * @return the extensionConverterProvider
303 public ExtensionConverterProvider getExtensionConverterProvider() {
304 return extensionConverterProvider;