Made Notification and Data service available from SessionManager
[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.controller.sal.binding.api.NotificationProviderService;
18 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
19 import org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductor;
20 import org.opendaylight.openflowplugin.openflow.md.core.IMDMessageTranslator;
21 import org.opendaylight.openflowplugin.openflow.md.core.SwitchConnectionDistinguisher;
22 import org.opendaylight.openflowplugin.openflow.md.core.TranslatorKey;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
24 import org.opendaylight.yangtools.concepts.ListenerRegistration;
25 import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
26 import org.opendaylight.yangtools.yang.binding.DataObject;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 /**
31  * @author mirehak
32  */
33 public class SessionManagerOFImpl implements SessionManager {
34
35     protected static final Logger LOG = LoggerFactory.getLogger(SessionManagerOFImpl.class);
36     private static SessionManagerOFImpl instance;
37     private ConcurrentHashMap<SwitchConnectionDistinguisher, SessionContext> sessionLot;
38     private Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, DataObject>>> translatorMapping;
39
40     protected final ListenerRegistry<SessionListener> sessionListeners = new ListenerRegistry<>();
41     private NotificationProviderService notificationProviderService;
42
43     private DataProviderService dataProviderService;
44
45     /**
46      * @return singleton instance
47      */
48     public static synchronized SessionManager getInstance() {
49         if (instance == null) {
50             instance = new SessionManagerOFImpl();
51         }
52         return instance;
53     }
54
55     private SessionManagerOFImpl() {
56         sessionLot = new ConcurrentHashMap<>();
57     }
58
59     @Override
60     public SessionContext getSessionContext(SwitchConnectionDistinguisher sessionKey) {
61         return sessionLot.get(sessionKey);
62     }
63
64     @Override
65     public void invalidateSessionContext(SwitchConnectionDistinguisher sessionKey) {
66         SessionContext context = getSessionContext(sessionKey);
67         if (context == null) {
68             LOG.warn("context for invalidation not found");
69         } else {
70             for (Entry<SwitchConnectionDistinguisher, ConnectionConductor> auxEntry : context.getAuxiliaryConductors()) {
71                 invalidateAuxiliary(sessionKey, auxEntry.getKey());
72             }
73             context.getPrimaryConductor().disconnect();
74             context.setValid(false);
75             removeSessionContext(context);
76             // TODO:: notify listeners
77         }
78     }
79
80     private void invalidateDeadSessionContext(SessionContext sessionContext) {
81         if (sessionContext == null) {
82             LOG.warn("context for invalidation not found");
83         } else {
84             for (Entry<SwitchConnectionDistinguisher, ConnectionConductor> auxEntry : sessionContext
85                     .getAuxiliaryConductors()) {
86                 invalidateAuxiliary(sessionContext, auxEntry.getKey(), true);
87             }
88             sessionContext.setValid(false);
89             removeSessionContext(sessionContext);
90             // TODO:: notify listeners
91         }
92     }
93
94     private void removeSessionContext(SessionContext sessionContext) {
95         if (LOG.isDebugEnabled()) {
96             LOG.debug("removing session: {}", Arrays.toString(sessionContext.getSessionKey().getId()));
97         }
98         sessionLot.remove(sessionContext.getSessionKey(), sessionContext);
99         sessionNotifier.onSessionRemoved(sessionContext);
100     }
101
102     @Override
103     public void addSessionContext(SwitchConnectionDistinguisher sessionKey, SessionContext context) {
104         sessionLot.put(sessionKey, context);
105
106         sessionNotifier.onSessionAdded(sessionKey, context);
107
108     }
109
110     @Override
111     public void invalidateAuxiliary(SwitchConnectionDistinguisher sessionKey,
112             SwitchConnectionDistinguisher connectionCookie) {
113         SessionContext context = getSessionContext(sessionKey);
114         invalidateAuxiliary(context, connectionCookie, true);
115     }
116
117     /**
118      * @param context
119      * @param connectionCookie
120      * @param disconnect
121      *            true if auxiliary connection is to be disconnected
122      */
123     private static void invalidateAuxiliary(SessionContext context, SwitchConnectionDistinguisher connectionCookie,
124             boolean disconnect) {
125         if (context == null) {
126             LOG.warn("context for invalidation not found");
127         } else {
128             ConnectionConductor auxiliaryConductor = context.removeAuxiliaryConductor(connectionCookie);
129             if (auxiliaryConductor == null) {
130                 LOG.warn("auxiliary conductor not found");
131             } else {
132                 if (disconnect) {
133                     auxiliaryConductor.disconnect();
134                 }
135             }
136         }
137     }
138
139     @Override
140     public void invalidateOnDisconnect(ConnectionConductor conductor) {
141         if (conductor.getAuxiliaryKey() == null) {
142             invalidateDeadSessionContext(conductor.getSessionContext());
143             // TODO:: notify listeners
144         } else {
145             invalidateAuxiliary(conductor.getSessionContext(), conductor.getAuxiliaryKey(), false);
146         }
147     }
148
149     @Override
150     public void setTranslatorMapping(Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, DataObject>>> translatorMapping) {
151         this.translatorMapping = translatorMapping;
152     }
153
154     @Override
155     public ListenerRegistration<SessionListener> registerSessionListener(SessionListener listener) {
156         return sessionListeners.register(listener);
157     }
158
159     private final SessionListener sessionNotifier = new SessionListener() {
160
161         @Override
162         public void onSessionAdded(SwitchConnectionDistinguisher sessionKey, SessionContext context) {
163             for (ListenerRegistration<SessionListener> listener : sessionListeners) {
164                 try {
165                     listener.getInstance().onSessionAdded(sessionKey, context);
166                 } catch (Exception e) {
167                     LOG.error("Unhandled exeption occured while invoking onSessionAdded on listener", e);
168                 }
169             }
170         }
171
172         public void onSessionRemoved(SessionContext context) {
173             for (ListenerRegistration<SessionListener> listener : sessionListeners) {
174                 try {
175                     listener.getInstance().onSessionRemoved(context);
176                 } catch (Exception e) {
177                     LOG.error("Unhandled exeption occured while invoking onSessionRemoved on listener", e);
178                 }
179             }
180         }
181     };
182
183     @Override
184     public Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, DataObject>>> getTranslatorMapping() {
185         return this.translatorMapping;
186     }
187
188     @Override
189     public void setNotificationProviderService(
190             NotificationProviderService notificationProviderService) {
191         this.notificationProviderService = notificationProviderService;
192
193     }
194
195     @Override
196     public DataProviderService getDataProviderService() {
197         return dataProviderService;
198     }
199
200     @Override
201     public void setDataProviderService(DataProviderService dataServiceProvider) {
202         this.dataProviderService = dataServiceProvider;
203
204     }
205
206     @Override
207     public NotificationProviderService getNotificationProviderService() {
208         return notificationProviderService;
209     }
210
211 }