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 java.util.Arrays;
12 import java.util.Collection;
13 import java.util.List;
15 import java.util.Map.Entry;
16 import java.util.concurrent.ConcurrentHashMap;
18 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
19 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
20 import org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductor;
21 import org.opendaylight.openflowplugin.openflow.md.core.IMDMessageTranslator;
22 import org.opendaylight.openflowplugin.openflow.md.core.SwitchConnectionDistinguisher;
23 import org.opendaylight.openflowplugin.openflow.md.core.TranslatorKey;
24 import org.opendaylight.openflowplugin.openflow.md.queue.PopListener;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
26 import org.opendaylight.yangtools.concepts.ListenerRegistration;
27 import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
28 import org.opendaylight.yangtools.yang.binding.DataObject;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
35 public class SessionManagerOFImpl implements SessionManager {
37 protected static final Logger LOG = LoggerFactory.getLogger(SessionManagerOFImpl.class);
38 private static SessionManagerOFImpl instance;
39 private ConcurrentHashMap<SwitchConnectionDistinguisher, SessionContext> sessionLot;
40 private Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> translatorMapping;
41 private Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> popListenerMapping;
44 protected ListenerRegistry<SessionListener> sessionListeners;
45 private NotificationProviderService notificationProviderService;
47 private DataProviderService dataProviderService;
50 * @return singleton instance
52 public static synchronized SessionManager getInstance() {
53 if (instance == null) {
54 instance = new SessionManagerOFImpl();
60 * close and release singleton instace
62 public static synchronized void releaseInstance() {
67 private SessionManagerOFImpl() {
68 LOG.debug("singleton creating");
69 sessionLot = new ConcurrentHashMap<>();
70 sessionListeners = new ListenerRegistry<>();
74 public SessionContext getSessionContext(SwitchConnectionDistinguisher sessionKey) {
75 return sessionLot.get(sessionKey);
79 public void invalidateSessionContext(SwitchConnectionDistinguisher sessionKey) {
80 SessionContext context = getSessionContext(sessionKey);
81 if (context == null) {
82 LOG.warn("context for invalidation not found");
84 for (Entry<SwitchConnectionDistinguisher, ConnectionConductor> auxEntry : context.getAuxiliaryConductors()) {
85 invalidateAuxiliary(sessionKey, auxEntry.getKey());
87 context.getPrimaryConductor().disconnect();
88 context.setValid(false);
89 removeSessionContext(context);
90 // TODO:: notify listeners
94 private void invalidateDeadSessionContext(SessionContext sessionContext) {
95 if (sessionContext == null) {
96 LOG.warn("context for invalidation not found");
98 for (Entry<SwitchConnectionDistinguisher, ConnectionConductor> auxEntry : sessionContext
99 .getAuxiliaryConductors()) {
100 invalidateAuxiliary(sessionContext, auxEntry.getKey(), true);
102 sessionContext.setValid(false);
103 removeSessionContext(sessionContext);
104 // TODO:: notify listeners
108 private void removeSessionContext(SessionContext sessionContext) {
109 if (LOG.isDebugEnabled()) {
110 LOG.debug("removing session: {}", Arrays.toString(sessionContext.getSessionKey().getId()));
112 sessionLot.remove(sessionContext.getSessionKey(), sessionContext);
113 sessionNotifier.onSessionRemoved(sessionContext);
117 public void addSessionContext(SwitchConnectionDistinguisher sessionKey, SessionContext context) {
118 sessionLot.put(sessionKey, context);
120 sessionNotifier.onSessionAdded(sessionKey, context);
125 public void invalidateAuxiliary(SwitchConnectionDistinguisher sessionKey,
126 SwitchConnectionDistinguisher connectionCookie) {
127 SessionContext context = getSessionContext(sessionKey);
128 invalidateAuxiliary(context, connectionCookie, true);
133 * @param connectionCookie
135 * true if auxiliary connection is to be disconnected
137 private static void invalidateAuxiliary(SessionContext context, SwitchConnectionDistinguisher connectionCookie,
138 boolean disconnect) {
139 if (context == null) {
140 LOG.warn("context for invalidation not found");
142 ConnectionConductor auxiliaryConductor = context.removeAuxiliaryConductor(connectionCookie);
143 if (auxiliaryConductor == null) {
144 LOG.warn("auxiliary conductor not found");
147 auxiliaryConductor.disconnect();
154 public void invalidateOnDisconnect(ConnectionConductor conductor) {
155 if (conductor.getAuxiliaryKey() == null) {
156 invalidateDeadSessionContext(conductor.getSessionContext());
157 // TODO:: notify listeners
159 invalidateAuxiliary(conductor.getSessionContext(), conductor.getAuxiliaryKey(), false);
164 public void setTranslatorMapping(Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> translatorMapping) {
165 this.translatorMapping = translatorMapping;
169 public ListenerRegistration<SessionListener> registerSessionListener(SessionListener listener) {
170 LOG.debug("registerSessionListener");
171 return sessionListeners.register(listener);
174 private final SessionListener sessionNotifier = new SessionListener() {
177 public void onSessionAdded(SwitchConnectionDistinguisher sessionKey, SessionContext context) {
178 for (ListenerRegistration<SessionListener> listener : sessionListeners) {
180 listener.getInstance().onSessionAdded(sessionKey, context);
181 } catch (Exception e) {
182 LOG.error("Unhandled exeption occured while invoking onSessionAdded on listener", e);
188 public void onSessionRemoved(SessionContext context) {
189 for (ListenerRegistration<SessionListener> listener : sessionListeners) {
191 listener.getInstance().onSessionRemoved(context);
192 } catch (Exception e) {
193 LOG.error("Unhandled exeption occured while invoking onSessionRemoved on listener", e);
201 public Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> getTranslatorMapping() {
202 return this.translatorMapping;
206 public void setNotificationProviderService(
207 NotificationProviderService notificationProviderService) {
208 this.notificationProviderService = notificationProviderService;
213 public DataProviderService getDataProviderService() {
214 return dataProviderService;
218 public void setDataProviderService(DataProviderService dataServiceProvider) {
219 this.dataProviderService = dataServiceProvider;
224 public NotificationProviderService getNotificationProviderService() {
225 return notificationProviderService;
229 public Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> getPopListenerMapping() {
230 return popListenerMapping;
234 public void setPopListenerMapping(
235 Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> popListenerMapping) {
236 this.popListenerMapping = popListenerMapping;
240 public void close() {
242 sessionListeners = null;
243 synchronized (sessionLot) {
244 for (SessionContext sessionContext : sessionLot.values()) {
245 sessionContext.getPrimaryConductor().disconnect();