preparing QueueKeeper and message translation
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / core / session / SessionManagerOFImpl.java
1 /**
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.openflowplugin.openflow.md.core.session;
10
11 import java.util.Arrays;
12 import java.util.Collection;
13 import java.util.Map;
14 import java.util.Map.Entry;
15 import java.util.concurrent.ConcurrentHashMap;
16
17 import org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductor;
18 import org.opendaylight.openflowplugin.openflow.md.core.IMDMessageTranslator;
19 import org.opendaylight.openflowplugin.openflow.md.core.SwitchConnectionDistinguisher;
20 import org.opendaylight.openflowplugin.openflow.md.core.TranslatorKey;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
22 import org.opendaylight.yangtools.concepts.ListenerRegistration;
23 import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
24 import org.opendaylight.yangtools.yang.binding.DataObject;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28 /**
29  * @author mirehak
30  */
31 public class SessionManagerOFImpl implements SessionManager {
32
33     protected static final Logger LOG = LoggerFactory.getLogger(SessionManagerOFImpl.class);
34     private static SessionManagerOFImpl instance;
35     private ConcurrentHashMap<SwitchConnectionDistinguisher, SessionContext> sessionLot;
36     private Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, DataObject>>> translatorMapping;
37
38     protected final ListenerRegistry<SessionListener> sessionListeners = new ListenerRegistry<>();
39
40     /**
41      * @return singleton instance
42      */
43     public static synchronized SessionManager getInstance() {
44         if (instance == null) {
45             instance = new SessionManagerOFImpl();
46         }
47         return instance;
48     }
49
50     private SessionManagerOFImpl() {
51         sessionLot = new ConcurrentHashMap<>();
52     }
53
54     @Override
55     public SessionContext getSessionContext(SwitchConnectionDistinguisher sessionKey) {
56         return sessionLot.get(sessionKey);
57     }
58
59     @Override
60     public void invalidateSessionContext(SwitchConnectionDistinguisher sessionKey) {
61         SessionContext context = getSessionContext(sessionKey);
62         if (context == null) {
63             LOG.warn("context for invalidation not found");
64         } else {
65             for (Entry<SwitchConnectionDistinguisher, ConnectionConductor> auxEntry : context.getAuxiliaryConductors()) {
66                 invalidateAuxiliary(sessionKey, auxEntry.getKey());
67             }
68             context.getPrimaryConductor().disconnect();
69             context.setValid(false);
70             removeSessionContext(context);
71             // TODO:: notify listeners
72         }
73     }
74
75     private void invalidateDeadSessionContext(SessionContext sessionContext) {
76         if (sessionContext == null) {
77             LOG.warn("context for invalidation not found");
78         } else {
79             for (Entry<SwitchConnectionDistinguisher, ConnectionConductor> auxEntry : sessionContext
80                     .getAuxiliaryConductors()) {
81                 invalidateAuxiliary(sessionContext, auxEntry.getKey(), true);
82             }
83             sessionContext.setValid(false);
84             removeSessionContext(sessionContext);
85             // TODO:: notify listeners
86         }
87     }
88
89     private void removeSessionContext(SessionContext sessionContext) {
90         if (LOG.isDebugEnabled()) {
91             LOG.debug("removing session: {}", Arrays.toString(sessionContext.getSessionKey().getId()));
92         }
93         sessionLot.remove(sessionContext.getSessionKey(), sessionContext);
94         sessionNotifier.onSessionRemoved(sessionContext);
95     }
96
97     @Override
98     public void addSessionContext(SwitchConnectionDistinguisher sessionKey, SessionContext context) {
99         sessionLot.put(sessionKey, context);
100
101         sessionNotifier.onSessionAdded(sessionKey, context);
102
103     }
104
105     @Override
106     public void invalidateAuxiliary(SwitchConnectionDistinguisher sessionKey,
107             SwitchConnectionDistinguisher connectionCookie) {
108         SessionContext context = getSessionContext(sessionKey);
109         invalidateAuxiliary(context, connectionCookie, true);
110     }
111
112     /**
113      * @param context
114      * @param connectionCookie
115      * @param disconnect
116      *            true if auxiliary connection is to be disconnected
117      */
118     private static void invalidateAuxiliary(SessionContext context, SwitchConnectionDistinguisher connectionCookie,
119             boolean disconnect) {
120         if (context == null) {
121             LOG.warn("context for invalidation not found");
122         } else {
123             ConnectionConductor auxiliaryConductor = context.removeAuxiliaryConductor(connectionCookie);
124             if (auxiliaryConductor == null) {
125                 LOG.warn("auxiliary conductor not found");
126             } else {
127                 if (disconnect) {
128                     auxiliaryConductor.disconnect();
129                 }
130             }
131         }
132     }
133
134     @Override
135     public void invalidateOnDisconnect(ConnectionConductor conductor) {
136         if (conductor.getAuxiliaryKey() == null) {
137             invalidateDeadSessionContext(conductor.getSessionContext());
138             // TODO:: notify listeners
139         } else {
140             invalidateAuxiliary(conductor.getSessionContext(), conductor.getAuxiliaryKey(), false);
141         }
142     }
143
144     @Override
145     public void setTranslatorMapping(Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, DataObject>>> translatorMapping) {
146         this.translatorMapping = translatorMapping;
147     }
148
149     @Override
150     public ListenerRegistration<SessionListener> registerSessionListener(SessionListener listener) {
151         return sessionListeners.register(listener);
152     }
153
154     private final SessionListener sessionNotifier = new SessionListener() {
155
156         @Override
157         public void onSessionAdded(SwitchConnectionDistinguisher sessionKey, SessionContext context) {
158             for (ListenerRegistration<SessionListener> listener : sessionListeners) {
159                 try {
160                     listener.getInstance().onSessionAdded(sessionKey, context);
161                 } catch (Exception e) {
162                     LOG.error("Unhandled exeption occured while invoking onSessionAdded on listener", e);
163                 }
164             }
165         }
166
167         public void onSessionRemoved(SessionContext context) {
168             for (ListenerRegistration<SessionListener> listener : sessionListeners) {
169                 try {
170                     listener.getInstance().onSessionRemoved(context);
171                 } catch (Exception e) {
172                     LOG.error("Unhandled exeption occured while invoking onSessionRemoved on listener", e);
173                 }
174             }
175         }
176     };
177
178     @Override
179     public Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, DataObject>>> getTranslatorMapping() {
180         return this.translatorMapping;
181     }
182
183 }