Merge "BUG-5192: FRM skips reconciliation"
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / core / session / OFSessionUtil.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.math.BigInteger;
12 import java.util.Arrays;
13 import java.util.Collection;
14 import java.util.List;
15 import java.util.Map;
16
17 import org.opendaylight.openflowplugin.api.openflow.md.core.session.SessionContext;
18 import org.opendaylight.openflowplugin.api.openflow.md.core.session.SwitchSessionKeyOF;
19 import org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl;
20 import org.opendaylight.openflowplugin.api.openflow.md.core.IMDMessageTranslator;
21 import org.opendaylight.openflowplugin.api.openflow.md.core.SwitchConnectionDistinguisher;
22 import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey;
23 import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider;
24 import org.opendaylight.openflowplugin.api.openflow.md.queue.PopListener;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
27 import org.opendaylight.yangtools.yang.binding.DataObject;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 /**
32  * @author mirehak
33  */
34 public abstract class OFSessionUtil {
35
36     private static final Logger LOG = LoggerFactory
37             .getLogger(OFSessionUtil.class);
38
39     /**
40      * @param connectionConductor switch connection conductor
41      * @param features switch feature output
42      * @param version openflow version
43      */
44     // public static void registerSession(ConnectionConductorImpl connectionConductor,
45     public static SessionContext registerSession(ConnectionConductorImpl connectionConductor,
46             GetFeaturesOutput features, short version) {
47         SwitchSessionKeyOF sessionKey = createSwitchSessionKey(features
48                 .getDatapathId());
49         SessionContext sessionContext = getSessionManager().getSessionContext(sessionKey);
50         if (LOG.isDebugEnabled()) {
51             LOG.debug("registering sessionKey: {}", Arrays.toString(sessionKey.getId()));
52         }
53
54         if (features.getAuxiliaryId() == null || features.getAuxiliaryId() == 0) {
55             // handle primary
56             if (sessionContext != null) {
57                 LOG.warn("duplicate datapathId occured while registering new switch session: "
58                         + dumpDataPathId(features.getDatapathId()));
59                 getSessionManager().invalidateSessionContext(sessionKey);
60             }
61             // register new session context (based primary conductor)
62             SessionContextOFImpl context = new SessionContextOFImpl();
63             context.setPrimaryConductor(connectionConductor);
64             context.setNotificationEnqueuer(connectionConductor);
65             context.setFeatures(features);
66             context.setSessionKey(sessionKey);
67             context.setSeed((int) System.currentTimeMillis());
68             connectionConductor.setSessionContext(context);
69             getSessionManager().addSessionContext(sessionKey, context);
70         } else {
71             // handle auxiliary
72             if (sessionContext == null) {
73                 throw new IllegalStateException("unexpected auxiliary connection - primary connection missing: "
74                         + dumpDataPathId(features.getDatapathId()));
75             } else {
76                 // register auxiliary conductor into existing sessionContext
77                 SwitchConnectionDistinguisher auxiliaryKey = createConnectionCookie(features, sessionContext.getSeed());
78                 if (sessionContext.getAuxiliaryConductor(auxiliaryKey) != null) {
79                     LOG.warn("duplicate datapathId+auxiliary occured while registering switch session: "
80                             + dumpDataPathId(features.getDatapathId())
81                             + " | "
82                             + features.getAuxiliaryId());
83                     getSessionManager().invalidateAuxiliary(sessionKey,
84                             auxiliaryKey);
85                 }
86
87                 sessionContext.addAuxiliaryConductor(auxiliaryKey,
88                         connectionConductor);
89                 connectionConductor.setSessionContext(sessionContext);
90                 connectionConductor.setConnectionCookie(auxiliaryKey);
91             }
92         }
93
94         // check registration result
95         SessionContext resulContext = getSessionManager().getSessionContext(sessionKey);
96         if (resulContext == null) {
97             throw new IllegalStateException("session context registration failed");
98         } else {
99             if (!resulContext.isValid()) {
100                 throw new IllegalStateException("registered session context is invalid");
101             }
102         }
103         return(resulContext);
104     }
105
106     public static void setRole(SessionContext sessionContext)
107     {
108             getSessionManager().setRole(sessionContext);
109     }
110
111     /**
112      * @param datapathId switch datapath id
113      * @return readable version of datapathId (hex)
114      */
115     public static String dumpDataPathId(BigInteger datapathId) {
116         return datapathId.toString(16);
117     }
118
119     /**
120      * @param datapathId switch datapath id
121      * @return new session key
122      */
123     public static SwitchSessionKeyOF createSwitchSessionKey(
124             BigInteger datapathId) {
125         SwitchSessionKeyOF key = new SwitchSessionKeyOF();
126         key.setDatapathId(datapathId);
127         return key;
128     }
129
130     /**
131      * @param features switch feature output
132      * @param seed  seed value
133      * @return connection cookie key
134      * @see #createConnectionCookie(BigInteger,short, int)
135      */
136     public static SwitchConnectionDistinguisher createConnectionCookie(
137             GetFeaturesOutput features, int seed) {
138         return createConnectionCookie(features.getDatapathId(),
139                 features.getAuxiliaryId(), seed);
140     }
141
142     /**
143      * @param datapathId switch datapath id
144      * @param auxiliaryId connection aux id
145      * @param seed  seed value
146      * @return connection cookie key
147      */
148     public static SwitchConnectionDistinguisher createConnectionCookie(
149             BigInteger datapathId, short auxiliaryId, int seed) {
150         SwitchConnectionCookieOFImpl cookie = null;
151         cookie = new SwitchConnectionCookieOFImpl();
152         cookie.setAuxiliaryId(auxiliaryId);
153         cookie.init(datapathId.intValue() + seed);
154         return cookie;
155     }
156
157     /**
158      * @return session manager singleton instance
159      */
160     public static ConjunctSessionManager getSessionManager() {
161         return SessionManagerOFImpl.getInstance();
162     }
163     
164     /**
165      * release session manager singleton instance
166      */
167     public static void releaseSessionManager() {
168         SessionManagerOFImpl.releaseInstance();
169     }
170     
171     /**
172     * @return session manager listener Map
173     */
174     public static Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> getTranslatorMap() {
175         return getSessionManager().getTranslatorMapping();
176     }
177
178     /**
179      * @return pop listener Map
180      */
181     public static Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> getPopListenerMapping() {
182         return getSessionManager().getPopListenerMapping();
183     }
184
185     /**
186      * @return extension converters provider
187      */
188     public static ExtensionConverterProvider getExtensionConvertorProvider() {
189         return getSessionManager().getExtensionConverterProvider();
190     }
191
192     /**
193      * @return collection of all sessions
194      */
195     public static Collection<SessionContext> getAllSessions() {
196         return getSessionManager().getAllSessions();
197     }
198
199 }