import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Interner;
import com.google.common.collect.Interners;
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
// Non-final for mocking
class NetconfClientSessionNegotiator
- extends AbstractNetconfSessionNegotiator<NetconfClientSessionPreferences, NetconfClientSession,
- NetconfClientSessionListener> {
+ extends AbstractNetconfSessionNegotiator<NetconfClientSession, NetconfClientSessionListener> {
private static final Logger LOG = LoggerFactory.getLogger(NetconfClientSessionNegotiator.class);
private static final XPathExpression SESSION_ID_X_PATH = XMLNetconfUtil
private static final Interner<Set<String>> INTERNER = Interners.newWeakInterner();
+ private final NetconfMessage startExi;
+
NetconfClientSessionNegotiator(final NetconfClientSessionPreferences sessionPreferences,
final Promise<NetconfClientSession> promise, final Channel channel, final Timer timer,
final NetconfClientSessionListener sessionListener, final long connectionTimeoutMillis) {
- super(sessionPreferences, promise, channel, timer, sessionListener, connectionTimeoutMillis);
+ super(sessionPreferences.getHelloMessage(), promise, channel, timer, sessionListener, connectionTimeoutMillis);
+ startExi = sessionPreferences.getStartExiMessage();
}
@SuppressWarnings("checkstyle:IllegalCatch")
- @SuppressFBWarnings(value = "BC_UNCONFIRMED_CAST",
- justification = "SpotBugs does not understand generic cast of sessionPreferences")
@Override
protected void handleMessage(final NetconfHelloMessage netconfMessage) throws NetconfDocumentedException {
if (!ifNegotiatedAlready()) {
// If exi should be used, try to initiate exi communication
// Call negotiationSuccessFul after exi negotiation is finished successfully or not
- final NetconfMessage startExiMessage = sessionPreferences.getStartExiMessage();
- if (shouldUseExi(netconfMessage) && startExiMessage instanceof NetconfStartExiMessage) {
+ if (startExi instanceof NetconfStartExiMessage && shouldUseExi(netconfMessage)) {
LOG.debug("Netconf session {} should use exi.", session);
- tryToInitiateExi(session, (NetconfStartExiMessage) startExiMessage);
+ tryToInitiateExi(session, (NetconfStartExiMessage) startExi);
} else {
// Exi is not supported, release session immediately
LOG.debug("Netconf session {} isn't capable of using exi.", session);
});
}
- @SuppressFBWarnings(value = "BC_UNCONFIRMED_CAST",
- justification = "SpotBugs does not understand generic cast of sessionPreferences")
private boolean shouldUseExi(final NetconfHelloMessage helloMsg) {
- return containsExi10Capability(helloMsg.getDocument())
- && containsExi10Capability(sessionPreferences.getHelloMessage().getDocument());
+ return containsExi10Capability(helloMsg.getDocument()) && containsExi10Capability(localHello().getDocument());
}
private static boolean containsExi10Capability(final Document doc) {
*/
package org.opendaylight.netconf.impl;
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.netty.channel.Channel;
import io.netty.channel.local.LocalAddress;
import io.netty.util.Timer;
import org.slf4j.LoggerFactory;
public final class NetconfServerSessionNegotiator
- extends AbstractNetconfSessionNegotiator<NetconfServerSessionPreferences, NetconfServerSession,
- NetconfServerSessionListener> {
+ extends AbstractNetconfSessionNegotiator<NetconfServerSession, NetconfServerSessionListener> {
private static final Logger LOG = LoggerFactory.getLogger(NetconfServerSessionNegotiator.class);
private static final String UNKNOWN = "unknown";
+ private final long sessionId;
+
protected NetconfServerSessionNegotiator(final NetconfServerSessionPreferences sessionPreferences,
final Promise<NetconfServerSession> promise, final Channel channel, final Timer timer,
final NetconfServerSessionListener sessionListener, final long connectionTimeoutMillis) {
- super(sessionPreferences, promise, channel, timer, sessionListener, connectionTimeoutMillis);
+ super(sessionPreferences.getHelloMessage(), promise, channel, timer, sessionListener, connectionTimeoutMillis);
+ sessionId = sessionPreferences.getSessionId();
}
@Override
}
@Override
- @SuppressFBWarnings(value = "BC_UNCONFIRMED_CAST_OF_RETURN_VALUE",
- justification = "SpotBugs does not grok generic return of getSessionPreferences()")
protected NetconfServerSession getSession(final NetconfServerSessionListener sessionListener, final Channel channel,
final NetconfHelloMessage message) {
final var additionalHeader = message.getAdditionalHeader();
});
LOG.debug("Additional header from hello parsed as {} from {}", parsedHeader, additionalHeader);
- return new NetconfServerSession(sessionListener, channel, getSessionPreferences().getSessionId(), parsedHeader);
+ return new NetconfServerSession(sessionListener, channel, sessionId, parsedHeader);
}
/**
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import org.checkerframework.checker.lock.qual.GuardedBy;
+import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.netconf.api.NetconfDocumentedException;
import org.opendaylight.netconf.api.NetconfMessage;
import org.opendaylight.netconf.api.NetconfSessionListener;
-import org.opendaylight.netconf.api.NetconfSessionPreferences;
import org.opendaylight.netconf.api.messages.NetconfHelloMessage;
import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
import org.opendaylight.netconf.nettyutil.handler.FramingMechanismHandlerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
-public abstract class AbstractNetconfSessionNegotiator<P extends NetconfSessionPreferences,
- S extends AbstractNetconfSession<S, L>, L extends NetconfSessionListener<S>>
+public abstract class AbstractNetconfSessionNegotiator<S extends AbstractNetconfSession<S, L>,
+ L extends NetconfSessionListener<S>>
extends ChannelInboundHandlerAdapter implements NetconfSessionNegotiator<S> {
/**
* Possible states for Finite State Machine.
private static final Logger LOG = LoggerFactory.getLogger(AbstractNetconfSessionNegotiator.class);
private static final String NAME_OF_EXCEPTION_HANDLER = "lastExceptionHandler";
- protected final P sessionPreferences;
+ private final @NonNull NetconfHelloMessage localHello;
protected final Channel channel;
private final long connectionTimeoutMillis;
@GuardedBy("this")
private State state = State.IDLE;
- protected AbstractNetconfSessionNegotiator(final P sessionPreferences, final Promise<S> promise,
+ protected AbstractNetconfSessionNegotiator(final NetconfHelloMessage hello, final Promise<S> promise,
final Channel channel, final Timer timer,
final L sessionListener, final long connectionTimeoutMillis) {
- this.channel = requireNonNull(channel);
+ this.localHello = requireNonNull(hello);
this.promise = requireNonNull(promise);
- this.sessionPreferences = sessionPreferences;
+ this.channel = requireNonNull(channel);
this.timer = timer;
this.sessionListener = sessionListener;
this.connectionTimeoutMillis = connectionTimeoutMillis;
}
+ protected final @NonNull NetconfHelloMessage localHello() {
+ return localHello;
+ }
+
protected final void startNegotiation() {
if (ifNegotiatedAlready()) {
LOG.debug("Negotiation on channel {} already started", channel);
return Optional.ofNullable(channel.pipeline().get(SslHandler.class));
}
- public final P getSessionPreferences() {
- return sessionPreferences;
- }
-
private void start() {
- final NetconfHelloMessage helloMessage = this.sessionPreferences.getHelloMessage();
- LOG.debug("Session negotiation started with hello message {} on channel {}", helloMessage, channel);
+ LOG.debug("Session negotiation started with hello message {} on channel {}", localHello, channel);
channel.pipeline().addLast(NAME_OF_EXCEPTION_HANDLER, new ExceptionHandlingInboundChannelHandler());
- sendMessage(helloMessage);
+ sendMessage(localHello);
replaceHelloMessageOutboundHandler();
changeState(State.OPEN_WAIT);
}
private boolean shouldUseChunkFraming(final Document doc) {
- return containsBase11Capability(doc)
- && containsBase11Capability(sessionPreferences.getHelloMessage().getDocument());
+ return containsBase11Capability(doc) && containsBase11Capability(localHello.getDocument());
}
/**
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.opendaylight.netconf.api.NetconfSessionListener;
-import org.opendaylight.netconf.api.NetconfSessionPreferences;
import org.opendaylight.netconf.api.messages.NetconfHelloMessage;
import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
import org.opendaylight.netconf.api.xml.XmlUtil;
private NetconfHelloMessage hello;
private NetconfHelloMessage helloBase11;
private NetconfXMLToHelloMessageDecoder xmlToHello;
- private NetconfSessionPreferences prefs;
@Before
public void setUp() {
hello = NetconfHelloMessage.createClientHello(Set.of(), Optional.empty());
helloBase11 = NetconfHelloMessage.createClientHello(
Set.of(XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_1), Optional.empty());
- prefs = new NetconfSessionPreferences(helloBase11);
doReturn(promise).when(promise).setFailure(any());
- negotiator = new TestSessionNegotiator(prefs, promise, channel, timer, listener, 100L);
+ negotiator = new TestSessionNegotiator(helloBase11, promise, channel, timer, listener, 100L);
}
@Test
verify(closedDetector).close(any(), any());
}
- @Test
- public void testGetSessionPreferences() {
- assertEquals(prefs, negotiator.getSessionPreferences());
- }
-
@Test
public void testGetSessionForHelloMessage() throws Exception {
enableTimerTask();
*/
package org.opendaylight.netconf.nettyutil;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
import static org.opendaylight.netconf.nettyutil.AbstractChannelInitializer.NETCONF_MESSAGE_AGGREGATOR;
import static org.opendaylight.netconf.nettyutil.AbstractChannelInitializer.NETCONF_MESSAGE_FRAME_ENCODER;
import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.util.HashedWheelTimer;
import io.netty.util.concurrent.Promise;
-import java.util.Collections;
import java.util.Optional;
-import org.junit.Assert;
+import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.opendaylight.netconf.api.NetconfSessionListener;
-import org.opendaylight.netconf.api.NetconfSessionPreferences;
import org.opendaylight.netconf.api.messages.NetconfHelloMessage;
import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
import org.opendaylight.netconf.nettyutil.handler.ChunkedFramingMechanismEncoder;
private Promise<TestingNetconfSession> promise;
private EmbeddedChannel channel;
- private AbstractNetconfSessionNegotiator negotiator;
+ private TestSessionNegotiator negotiator;
@Before
public void setUp() throws Exception {
channel.pipeline().addLast(NETCONF_MESSAGE_FRAME_ENCODER,
FramingMechanismHandlerFactory.createHandler(FramingMechanism.EOM));
channel.pipeline().addLast(NETCONF_MESSAGE_AGGREGATOR, new NetconfEOMAggregator());
- final NetconfHelloMessage serverHello = NetconfHelloMessage.createClientHello(Collections
- .singleton(XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_1), Optional.empty());
- negotiator = new TestSessionNegotiator(new NetconfSessionPreferences(serverHello), promise, channel,
- new HashedWheelTimer(), listener, 100L);
+ final NetconfHelloMessage serverHello = NetconfHelloMessage.createClientHello(
+ Set.of(XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_1), Optional.empty());
+ negotiator = new TestSessionNegotiator(serverHello, promise, channel, new HashedWheelTimer(), listener, 100L);
}
@Test
final Document helloDocument = XmlFileLoader.xmlFileToDocument(fileName);
negotiator.startNegotiation();
final NetconfHelloMessage helloMessage = new NetconfHelloMessage(helloDocument);
- final AbstractNetconfSession session = negotiator.getSessionForHelloMessage(helloMessage);
- Assert.assertNotNull(session);
- Assert.assertTrue("NetconfChunkAggregator was not installed in the Netconf pipeline",
+ final TestingNetconfSession session = negotiator.getSessionForHelloMessage(helloMessage);
+ assertNotNull(session);
+ assertTrue("NetconfChunkAggregator was not installed in the Netconf pipeline",
channel.pipeline().get(NETCONF_MESSAGE_AGGREGATOR) instanceof NetconfChunkAggregator);
- Assert.assertTrue("ChunkedFramingMechanismEncoder was not installed in the Netconf pipeline",
+ assertTrue("ChunkedFramingMechanismEncoder was not installed in the Netconf pipeline",
channel.pipeline().get(NETCONF_MESSAGE_FRAME_ENCODER) instanceof ChunkedFramingMechanismEncoder);
}
}
\ No newline at end of file
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-
package org.opendaylight.netconf.nettyutil;
import io.netty.channel.Channel;
import io.netty.util.Timer;
import io.netty.util.concurrent.Promise;
-import org.opendaylight.netconf.api.NetconfDocumentedException;
import org.opendaylight.netconf.api.NetconfSessionListener;
-import org.opendaylight.netconf.api.NetconfSessionPreferences;
import org.opendaylight.netconf.api.messages.NetconfHelloMessage;
-final class TestSessionNegotiator extends
- AbstractNetconfSessionNegotiator<NetconfSessionPreferences,
- TestingNetconfSession, NetconfSessionListener<TestingNetconfSession>> {
-
-
- TestSessionNegotiator(final NetconfSessionPreferences sessionPreferences,
- final Promise<TestingNetconfSession> promise, final Channel channel,
- final Timer timer,
- final NetconfSessionListener<TestingNetconfSession> sessionListener,
- final long connectionTimeoutMillis) {
- super(sessionPreferences, promise, channel, timer, sessionListener, connectionTimeoutMillis);
+final class TestSessionNegotiator
+ extends AbstractNetconfSessionNegotiator<TestingNetconfSession, NetconfSessionListener<TestingNetconfSession>> {
+ TestSessionNegotiator(final NetconfHelloMessage hello, final Promise<TestingNetconfSession> promise,
+ final Channel channel, final Timer timer,
+ final NetconfSessionListener<TestingNetconfSession> sessionListener, final long connectionTimeoutMillis) {
+ super(hello, promise, channel, timer, sessionListener, connectionTimeoutMillis);
}
@Override
- protected TestingNetconfSession getSession(final NetconfSessionListener sessionListener, final Channel channel,
- final NetconfHelloMessage message)
- throws NetconfDocumentedException {
+ protected TestingNetconfSession getSession(final NetconfSessionListener<TestingNetconfSession> sessionListener,
+ final Channel channel, final NetconfHelloMessage message) {
return new TestingNetconfSession(sessionListener, channel, 0L);
}
@Override
- protected void handleMessage(final NetconfHelloMessage netconfHelloMessage) throws Exception {
-
+ protected void handleMessage(final NetconfHelloMessage netconfHelloMessage) {
+ // No-op
}
}
\ No newline at end of file