package org.opendaylight.openflowplugin.openflow.md.core.session;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import java.util.Arrays;
import java.util.Collection;
+import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
-
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
-import org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductor;
-import org.opendaylight.openflowplugin.openflow.md.core.IMDMessageListener;
-import org.opendaylight.openflowplugin.openflow.md.core.SwitchConnectionDistinguisher;
+import org.opendaylight.openflowplugin.api.openflow.md.core.ConnectionConductor;
+import org.opendaylight.openflowplugin.api.openflow.md.core.IMDMessageTranslator;
+import org.opendaylight.openflowplugin.api.openflow.md.core.SwitchConnectionDistinguisher;
+import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey;
+import org.opendaylight.openflowplugin.api.openflow.md.core.session.SessionContext;
+import org.opendaylight.openflowplugin.api.openflow.md.core.session.SessionListener;
+import org.opendaylight.openflowplugin.api.openflow.md.core.session.SwitchSessionKeyOF;
+import org.opendaylight.openflowplugin.api.openflow.md.queue.PopListener;
+import org.opendaylight.openflowplugin.api.statistics.MessageSpy;
+import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
+import org.opendaylight.yangtools.util.ListenerRegistry;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author mirehak
*/
-public class SessionManagerOFImpl implements SessionManager {
+public class SessionManagerOFImpl implements ConjunctSessionManager {
- private static final Logger LOG = LoggerFactory.getLogger(SessionManagerOFImpl.class);
+ protected static final Logger LOG = LoggerFactory.getLogger(SessionManagerOFImpl.class);
private static SessionManagerOFImpl instance;
- private ConcurrentHashMap<SwitchConnectionDistinguisher, SessionContext> sessionLot;
- private Map<Class<? extends DataObject>, Collection<IMDMessageListener>> listenerMapping;
+ private ConcurrentHashMap<SwitchSessionKeyOF, SessionContext> sessionLot;
+ private Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> translatorMapping;
+ private Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> popListenerMapping;
+
+ protected ListenerRegistry<SessionListener> sessionListeners;
+ private NotificationProviderService notificationProviderService;
+
+ private DataBroker dataBroker;
+ private ListeningExecutorService rpcPool;
- private final ListenerRegistry<SessionListener> sessionListeners = new ListenerRegistry<>();
/**
* @return singleton instance
*/
- public static synchronized SessionManager getInstance() {
+ public static ConjunctSessionManager getInstance() {
if (instance == null) {
- instance = new SessionManagerOFImpl();
+ synchronized (SessionContextOFImpl.class) {
+ if (instance == null) {
+ instance = new SessionManagerOFImpl();
+ }
+ }
}
return instance;
}
+ /**
+ * close and release singleton instance
+ */
+ public static void releaseInstance() {
+ if (instance != null) {
+ synchronized (SessionManagerOFImpl.class) {
+ if (instance != null) {
+ instance.close();
+ instance = null;
+ }
+ }
+ }
+ }
+
private SessionManagerOFImpl() {
+ LOG.debug("singleton creating");
sessionLot = new ConcurrentHashMap<>();
+ sessionListeners = new ListenerRegistry<>();
}
@Override
- public SessionContext getSessionContext(SwitchConnectionDistinguisher sessionKey) {
+ public SessionContext getSessionContext(SwitchSessionKeyOF sessionKey) {
return sessionLot.get(sessionKey);
}
@Override
- public void invalidateSessionContext(SwitchConnectionDistinguisher sessionKey) {
+ public void invalidateSessionContext(SwitchSessionKeyOF sessionKey) {
SessionContext context = getSessionContext(sessionKey);
if (context == null) {
LOG.warn("context for invalidation not found");
} else {
- for (Entry<SwitchConnectionDistinguisher, ConnectionConductor> auxEntry : context.getAuxiliaryConductors()) {
- invalidateAuxiliary(sessionKey, auxEntry.getKey());
+ synchronized (context) {
+ for (Entry<SwitchConnectionDistinguisher, ConnectionConductor> auxEntry : context.getAuxiliaryConductors()) {
+ invalidateAuxiliary(sessionKey, auxEntry.getKey());
+ }
+ context.getPrimaryConductor().disconnect();
+ context.setValid(false);
+ removeSessionContext(context);
+ // TODO:: notify listeners
}
- context.getPrimaryConductor().disconnect();
- context.setValid(false);
- sessionLot.remove(sessionKey);
- // TODO:: notify listeners
}
}
if (sessionContext == null) {
LOG.warn("context for invalidation not found");
} else {
- for (Entry<SwitchConnectionDistinguisher, ConnectionConductor> auxEntry : sessionContext
- .getAuxiliaryConductors()) {
- invalidateAuxiliary(sessionContext, auxEntry.getKey(), true);
+ synchronized (sessionContext) {
+ for (Entry<SwitchConnectionDistinguisher, ConnectionConductor> auxEntry : sessionContext
+ .getAuxiliaryConductors()) {
+ invalidateAuxiliary(sessionContext, auxEntry.getKey(), true);
+ }
+ sessionContext.setValid(false);
+ removeSessionContext(sessionContext);
+ // TODO:: notify listeners
}
- sessionContext.setValid(false);
- sessionLot.remove(sessionContext.getSessionKey(), sessionContext);
- // TODO:: notify listeners
}
}
- @Override
- public void addSessionContext(SwitchConnectionDistinguisher sessionKey, SessionContext context) {
- sessionLot.put(sessionKey, context);
-
- sessionNotifier.onSessionAdded(sessionKey, context);
+ private void removeSessionContext(SessionContext sessionContext) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("removing session: {}", Arrays.toString(sessionContext.getSessionKey().getId()));
+ }
+ sessionLot.remove(sessionContext.getSessionKey(), sessionContext);
+ sessionNotifier.onSessionRemoved(sessionContext);
+ }
+ @Override
+ public void addSessionContext(SwitchSessionKeyOF sessionKey, SessionContext context) {
+ synchronized (context) {
+ sessionLot.put(sessionKey, context);
+ sessionNotifier.onSessionAdded(sessionKey, context);
+ context.setValid(true);
+ }
}
@Override
- public void invalidateAuxiliary(SwitchConnectionDistinguisher sessionKey,
- SwitchConnectionDistinguisher connectionCookie) {
+ public void invalidateAuxiliary(SwitchSessionKeyOF sessionKey,
+ SwitchConnectionDistinguisher connectionCookie) {
SessionContext context = getSessionContext(sessionKey);
invalidateAuxiliary(context, connectionCookie, true);
}
/**
* @param context
* @param connectionCookie
- * @param disconnect
- * true if auxiliary connection is to be disconnected
+ * @param disconnect true if auxiliary connection is to be disconnected
*/
private static void invalidateAuxiliary(SessionContext context, SwitchConnectionDistinguisher connectionCookie,
- boolean disconnect) {
+ boolean disconnect) {
if (context == null) {
LOG.warn("context for invalidation not found");
} else {
}
}
- /**
- * @param listenerMapping
- * the listenerMapping to set
- */
- public void setListenerMapping(Map<Class<? extends DataObject>, Collection<IMDMessageListener>> listenerMapping) {
- this.listenerMapping = listenerMapping;
+ @Override
+ public void setTranslatorMapping(Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> translatorMapping) {
+ this.translatorMapping = translatorMapping;
}
@Override
public ListenerRegistration<SessionListener> registerSessionListener(SessionListener listener) {
+ LOG.debug("registerSessionListener");
return sessionListeners.register(listener);
}
private final SessionListener sessionNotifier = new SessionListener() {
@Override
- public void onSessionAdded(SwitchConnectionDistinguisher sessionKey, SessionContext context) {
+ public void onSessionAdded(SwitchSessionKeyOF sessionKey, SessionContext context) {
for (ListenerRegistration<SessionListener> listener : sessionListeners) {
try {
listener.getInstance().onSessionAdded(sessionKey, context);
}
}
}
+
+ @Override
+ public void onSessionRemoved(SessionContext context) {
+ for (ListenerRegistration<SessionListener> listener : sessionListeners) {
+ try {
+ listener.getInstance().onSessionRemoved(context);
+ } catch (Exception e) {
+ LOG.error("Unhandled exeption occured while invoking onSessionRemoved on listener", e);
+ }
+ }
+ }
};
+ private MessageSpy<DataContainer> messageSpy;
+ private ExtensionConverterProvider extensionConverterProvider;
+
+
+ @Override
+ public Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> getTranslatorMapping() {
+ return this.translatorMapping;
+ }
+
+ @Override
+ public void setNotificationProviderService(
+ NotificationProviderService notificationProviderService) {
+ this.notificationProviderService = notificationProviderService;
+
+ }
+
+ @Override
+ public DataBroker getDataBroker() {
+ return dataBroker;
+ }
+
+ @Override
+ public void setDataBroker(DataBroker dataBroker) {
+ this.dataBroker = dataBroker;
+
+ }
+
+ @Override
+ public NotificationProviderService getNotificationProviderService() {
+ return notificationProviderService;
+ }
+
+ @Override
+ public Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> getPopListenerMapping() {
+ return popListenerMapping;
+ }
+
+ @Override
+ public void setPopListenerMapping(
+ Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> popListenerMapping) {
+ this.popListenerMapping = popListenerMapping;
+ }
+
+ @Override
+ public void close() {
+ LOG.debug("close");
+ synchronized (sessionLot) {
+ for (SessionContext sessionContext : sessionLot.values()) {
+ sessionContext.getPrimaryConductor().disconnect();
+ }
+ // TODO: handle timeouted shutdown
+ rpcPool.shutdown();
+ }
+
+ for (ListenerRegistration<SessionListener> listenerRegistration : sessionListeners) {
+ SessionListener listener = listenerRegistration.getInstance();
+ if (listener instanceof AutoCloseable) {
+ try {
+ ((AutoCloseable) listener).close();
+ } catch (Exception e) {
+ LOG.warn("closing of sessionListenerRegistration failed", e);
+ }
+ }
+ }
+ }
+ @Override
+ public void setRpcPool(ListeningExecutorService rpcPool) {
+ this.rpcPool = rpcPool;
+ }
+
+ @Override
+ public ListeningExecutorService getRpcPool() {
+ return rpcPool;
+ }
+
+ @Override
+ public void setMessageSpy(MessageSpy<DataContainer> messageSpy) {
+ this.messageSpy = messageSpy;
+ }
+
+ @Override
+ public MessageSpy<DataContainer> getMessageSpy() {
+ return messageSpy;
+ }
+
+ @Override
+ public void setExtensionConverterProvider(
+ ExtensionConverterProvider extensionConverterProvider) {
+ this.extensionConverterProvider = extensionConverterProvider;
+ }
+
+ /**
+ * @return the extensionConverterProvider
+ */
+ @Override
+ public ExtensionConverterProvider getExtensionConverterProvider() {
+ return extensionConverterProvider;
+ }
+
+ @Override
+ public Collection<SessionContext> getAllSessions() {
+ return sessionLot.values();
+ }
}