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;
32 import com.google.common.util.concurrent.ListeningExecutorService;
37 public class SessionManagerOFImpl implements SessionManager {
39 protected static final Logger LOG = LoggerFactory.getLogger(SessionManagerOFImpl.class);
40 private static SessionManagerOFImpl instance;
41 private ConcurrentHashMap<SwitchSessionKeyOF, SessionContext> sessionLot;
42 private Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> translatorMapping;
43 private Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> popListenerMapping;
45 protected ListenerRegistry<SessionListener> sessionListeners;
46 private NotificationProviderService notificationProviderService;
48 private DataProviderService dataProviderService;
49 private ListeningExecutorService rpcPool;
53 * @return singleton instance
55 public static synchronized SessionManager getInstance() {
56 if (instance == null) {
57 instance = new SessionManagerOFImpl();
63 * close and release singleton instace
65 public static synchronized void releaseInstance() {
70 private SessionManagerOFImpl() {
71 LOG.debug("singleton creating");
72 sessionLot = new ConcurrentHashMap<>();
73 sessionListeners = new ListenerRegistry<>();
77 public SessionContext getSessionContext(SwitchSessionKeyOF sessionKey) {
78 return sessionLot.get(sessionKey);
82 public void invalidateSessionContext(SwitchSessionKeyOF sessionKey) {
83 SessionContext context = getSessionContext(sessionKey);
84 if (context == null) {
85 LOG.warn("context for invalidation not found");
87 for (Entry<SwitchConnectionDistinguisher, ConnectionConductor> auxEntry : context.getAuxiliaryConductors()) {
88 invalidateAuxiliary(sessionKey, auxEntry.getKey());
90 context.getPrimaryConductor().disconnect();
91 context.setValid(false);
92 removeSessionContext(context);
93 // TODO:: notify listeners
97 private void invalidateDeadSessionContext(SessionContext sessionContext) {
98 if (sessionContext == null) {
99 LOG.warn("context for invalidation not found");
101 for (Entry<SwitchConnectionDistinguisher, ConnectionConductor> auxEntry : sessionContext
102 .getAuxiliaryConductors()) {
103 invalidateAuxiliary(sessionContext, auxEntry.getKey(), true);
105 sessionContext.setValid(false);
106 removeSessionContext(sessionContext);
107 // TODO:: notify listeners
111 private void removeSessionContext(SessionContext sessionContext) {
112 if (LOG.isDebugEnabled()) {
113 LOG.debug("removing session: {}", Arrays.toString(sessionContext.getSessionKey().getId()));
115 sessionLot.remove(sessionContext.getSessionKey(), sessionContext);
116 sessionNotifier.onSessionRemoved(sessionContext);
120 public void addSessionContext(SwitchSessionKeyOF sessionKey, SessionContext context) {
121 sessionLot.put(sessionKey, context);
123 sessionNotifier.onSessionAdded(sessionKey, context);
128 public void invalidateAuxiliary(SwitchSessionKeyOF sessionKey,
129 SwitchConnectionDistinguisher connectionCookie) {
130 SessionContext context = getSessionContext(sessionKey);
131 invalidateAuxiliary(context, connectionCookie, true);
136 * @param connectionCookie
138 * true if auxiliary connection is to be disconnected
140 private static void invalidateAuxiliary(SessionContext context, SwitchConnectionDistinguisher connectionCookie,
141 boolean disconnect) {
142 if (context == null) {
143 LOG.warn("context for invalidation not found");
145 ConnectionConductor auxiliaryConductor = context.removeAuxiliaryConductor(connectionCookie);
146 if (auxiliaryConductor == null) {
147 LOG.warn("auxiliary conductor not found");
150 auxiliaryConductor.disconnect();
157 public void invalidateOnDisconnect(ConnectionConductor conductor) {
158 if (conductor.getAuxiliaryKey() == null) {
159 invalidateDeadSessionContext(conductor.getSessionContext());
160 // TODO:: notify listeners
162 invalidateAuxiliary(conductor.getSessionContext(), conductor.getAuxiliaryKey(), false);
167 public void setTranslatorMapping(Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> translatorMapping) {
168 this.translatorMapping = translatorMapping;
172 public ListenerRegistration<SessionListener> registerSessionListener(SessionListener listener) {
173 LOG.debug("registerSessionListener");
174 return sessionListeners.register(listener);
177 private final SessionListener sessionNotifier = new SessionListener() {
180 public void onSessionAdded(SwitchSessionKeyOF sessionKey, SessionContext context) {
181 for (ListenerRegistration<SessionListener> listener : sessionListeners) {
183 listener.getInstance().onSessionAdded(sessionKey, context);
184 } catch (Exception e) {
185 LOG.error("Unhandled exeption occured while invoking onSessionAdded on listener", e);
191 public void onSessionRemoved(SessionContext context) {
192 for (ListenerRegistration<SessionListener> listener : sessionListeners) {
194 listener.getInstance().onSessionRemoved(context);
195 } catch (Exception e) {
196 LOG.error("Unhandled exeption occured while invoking onSessionRemoved on listener", e);
204 public Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> getTranslatorMapping() {
205 return this.translatorMapping;
209 public void setNotificationProviderService(
210 NotificationProviderService notificationProviderService) {
211 this.notificationProviderService = notificationProviderService;
216 public DataProviderService getDataProviderService() {
217 return dataProviderService;
221 public void setDataProviderService(DataProviderService dataServiceProvider) {
222 this.dataProviderService = dataServiceProvider;
227 public NotificationProviderService getNotificationProviderService() {
228 return notificationProviderService;
232 public Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> getPopListenerMapping() {
233 return popListenerMapping;
237 public void setPopListenerMapping(
238 Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> popListenerMapping) {
239 this.popListenerMapping = popListenerMapping;
243 public void close() {
245 sessionListeners = null;
246 synchronized (sessionLot) {
247 for (SessionContext sessionContext : sessionLot.values()) {
248 sessionContext.getPrimaryConductor().disconnect();
250 // TODO: handle timeouted shutdown
256 public void setRpcPool(ListeningExecutorService rpcPool) {
257 this.rpcPool = rpcPool;
261 public ListeningExecutorService getRpcPool() {