<type>xml</type>
<classifier>features</classifier>
</dependency>
- <dependency>
- <groupId>org.opendaylight.netconf</groupId>
- <artifactId>odl-protocol-framework</artifactId>
- <type>xml</type>
- <classifier>features</classifier>
- </dependency>
<dependency>
<groupId>org.opendaylight.mdsal.model</groupId>
<artifactId>odl-mdsal-model-rfc7895</artifactId>
<classifier>features</classifier>
</dependency>
-
<dependency>
<groupId>org.opendaylight.netconf</groupId>
<artifactId>netconf-api</artifactId>
<modules>
<module>netconf</module>
<module>netconf-connector</module>
- <module>protocol-framework</module>
<module>restconf</module>
<module>yanglib</module>
</modules>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright © 2016, 2017 Red Hat, Inc. and others.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.opendaylight.odlparent</groupId>
- <artifactId>feature-repo-parent</artifactId>
- <version>4.0.7</version>
- <relativePath/>
- </parent>
-
- <groupId>org.opendaylight.netconf</groupId>
- <artifactId>features-protocol-framework</artifactId>
- <version>1.3.0-SNAPSHOT</version>
- <packaging>feature</packaging>
-
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.netconf</groupId>
- <artifactId>odl-protocol-framework</artifactId>
- <version>1.3.0-SNAPSHOT</version>
- <type>xml</type>
- <classifier>features</classifier>
- </dependency>
- </dependencies>
-
-</project>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright © 2016, 2017 Red Hat, Inc. and others.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.opendaylight.odlparent</groupId>
- <artifactId>single-feature-parent</artifactId>
- <version>4.0.7</version>
- <relativePath/>
- </parent>
-
- <groupId>org.opendaylight.netconf</groupId>
- <artifactId>odl-protocol-framework</artifactId>
- <version>1.3.0-SNAPSHOT</version>
- <packaging>feature</packaging>
-
- <name>OpenDaylight :: Protocol Framework</name>
-
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.odlparent</groupId>
- <artifactId>odl-netty-4</artifactId>
- <type>xml</type>
- <classifier>features</classifier>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.odlparent</groupId>
- <artifactId>odl-guava</artifactId>
- <type>xml</type>
- <classifier>features</classifier>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.netconf</groupId>
- <artifactId>protocol-framework</artifactId>
- <version>${project.version}</version>
- </dependency>
- </dependencies>
-
-</project>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright © 2016, 2017 Red Hat, Inc. and others.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.odlparent</groupId>
- <artifactId>odlparent-lite</artifactId>
- <version>4.0.7</version>
- <relativePath/>
- </parent>
-
- <groupId>org.opendaylight.netconf</groupId>
- <artifactId>features-protocol-framework-aggregator</artifactId>
- <version>1.3.0-SNAPSHOT</version>
- <packaging>pom</packaging>
-
- <properties>
- <maven.deploy.skip>true</maven.deploy.skip>
- <maven.install.skip>true</maven.install.skip>
- </properties>
-
- <modules>
- <module>features-protocol-framework</module>
- <module>odl-protocol-framework</module>
- </modules>
-
- <scm>
- <connection>scm:git:ssh://git.opendaylight.org:29418/netconf.git</connection>
- <developerConnection>scm:git:ssh://git.opendaylight.org:29418/netconf.git</developerConnection>
- <tag>HEAD</tag>
- <url>https://git.opendaylight.org/gerrit/gitweb?p=netconf.git;a=summary</url>
- </scm>
-</project>
* 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.callhome.protocol;
import io.netty.channel.Channel;
import io.netty.util.concurrent.Promise;
+import org.opendaylight.netconf.api.NetconfSessionListenerFactory;
import org.opendaylight.netconf.client.NetconfClientSession;
import org.opendaylight.netconf.client.NetconfClientSessionListener;
import org.opendaylight.netconf.client.NetconfClientSessionNegotiatorFactory;
import org.opendaylight.netconf.nettyutil.AbstractChannelInitializer;
-import org.opendaylight.protocol.framework.SessionListenerFactory;
final class ReverseSshChannelInitializer extends AbstractChannelInitializer<NetconfClientSession>
- implements SessionListenerFactory<NetconfClientSessionListener> {
+ implements NetconfSessionListenerFactory<NetconfClientSessionListener> {
private final NetconfClientSessionNegotiatorFactory negotiatorFactory;
private final NetconfClientSessionListener sessionListener;
* 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.callhome.mount;
import static org.junit.Assert.assertFalse;
import org.opendaylight.netconf.client.NetconfClientSessionListener;
import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
import org.opendaylight.netconf.client.conf.NetconfClientConfigurationBuilder;
+import org.opendaylight.netconf.nettyutil.ReconnectStrategy;
import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
import org.opendaylight.netconf.topology.api.SchemaRepositoryProvider;
-import org.opendaylight.protocol.framework.ReconnectStrategy;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
<dependencies>
<dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>ietf-netconf-monitoring</artifactId>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-transport</artifactId>
</dependency>
+
<dependency>
<groupId>${project.groupId}</groupId>
- <artifactId>ietf-netconf-monitoring-extension</artifactId>
+ <artifactId>ietf-netconf-monitoring</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
- <artifactId>protocol-framework</artifactId>
+ <artifactId>ietf-netconf-monitoring-extension</artifactId>
</dependency>
<dependency>
<groupId>org.opendaylight.mdsal.binding.model.ietf</groupId>
package org.opendaylight.netconf.api;
import io.netty.channel.ChannelFuture;
-import org.opendaylight.protocol.framework.ProtocolSession;
+import java.io.Closeable;
-public interface NetconfSession extends ProtocolSession<NetconfMessage> {
+/**
+ * Protocol Session represents the finite state machine in underlying protocol, including timers and its purpose is to
+ * create a connection between server and client. Session is automatically started, when TCP connection is created, but
+ * can be stopped manually. If the session is up, it has to redirect messages to/from user. Handles also malformed
+ * messages and unknown requests.
+ *
+ * <p>
+ * This interface should be implemented by a final class representing a protocol specific session.
+ */
+public interface NetconfSession extends Closeable {
ChannelFuture sendMessage(NetconfMessage message);
+ @Override
+ void close();
}
* 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.api;
-import org.opendaylight.protocol.framework.SessionListener;
+// FIXME: NETCONF-554: rework this interface
+public interface NetconfSessionListener<S extends NetconfSession> {
+ /**
+ * Fired when the session was established successfully.
+ *
+ * @param session New session
+ */
+ void onSessionUp(S session);
+
+ /**
+ * Fired when the session went down because of an IO error. Implementation should take care of closing underlying
+ * session.
+ *
+ * @param session that went down
+ * @param cause Exception that was thrown as the cause of session being down
+ */
+ void onSessionDown(S session, Exception cause);
+
+ /**
+ * Fired when the session is terminated locally. The session has already been closed and transitioned to IDLE state.
+ * Any outstanding queued messages were not sent. The user should not attempt to make any use of the session.
+ *
+ * @param reason the cause why the session went down
+ */
+ void onSessionTerminated(S session, NetconfTerminationReason reason);
-public interface NetconfSessionListener
- <S extends NetconfSession> extends SessionListener<NetconfMessage, S, NetconfTerminationReason> {
+ /**
+ * Fired when a normal protocol message is received.
+ *
+ * @param message Protocol message
+ */
+ void onMessage(S session, NetconfMessage message);
}
* 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.protocol.framework;
-
+package org.opendaylight.netconf.api;
/**
* Factory for generating Session Listeners. Used by a server. This interface should be
* a final class that implements the methods.
*/
@Deprecated
-public interface SessionListenerFactory<T extends SessionListener<?, ?, ?>> {
+public interface NetconfSessionListenerFactory<T extends NetconfSessionListener<?>> {
/**
- * Returns one session listener
+ * Returns one session listener.
+ *
* @return specific session listener
*/
T getSessionListener();
* 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.api;
-import org.opendaylight.protocol.framework.TerminationReason;
-
-public class NetconfTerminationReason implements TerminationReason {
+public class NetconfTerminationReason {
private final String reason;
this.reason = reason;
}
- @Override
+ /**
+ * Get cause of session termination.
+ * @return human-readable cause.
+ */
public String getErrorMessage() {
return reason;
}
<artifactId>netconf-topology-singleton</artifactId>
<version>${project.version}</version>
</dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>protocol-framework</artifactId>
- <version>1.3.0-SNAPSHOT</version>
- </dependency>
<!-- netconf features -->
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>features-protocol-framework</artifactId>
- <version>1.3.0-SNAPSHOT</version>
- <type>xml</type>
- <classifier>features</classifier>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>odl-protocol-framework</artifactId>
- <version>1.3.0-SNAPSHOT</version>
- <type>xml</type>
- <classifier>features</classifier>
- </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>features-netconf</artifactId>
* 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.client;
import io.netty.channel.EventLoopGroup;
import java.util.Set;
import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfiguration;
-import org.opendaylight.protocol.framework.AbstractDispatcher;
+import org.opendaylight.netconf.nettyutil.AbstractNetconfDispatcher;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class NetconfClientDispatcherImpl extends AbstractDispatcher<NetconfClientSession, NetconfClientSessionListener>
+public class NetconfClientDispatcherImpl
+ extends AbstractNetconfDispatcher<NetconfClientSession, NetconfClientSessionListener>
implements NetconfClientDispatcher {
private static final Logger LOG = LoggerFactory.getLogger(NetconfClientDispatcherImpl.class);
import java.util.Set;
import org.opendaylight.netconf.api.NetconfClientSessionPreferences;
import org.opendaylight.netconf.api.NetconfMessage;
+import org.opendaylight.netconf.api.NetconfSessionListenerFactory;
import org.opendaylight.netconf.api.messages.NetconfHelloMessage;
import org.opendaylight.netconf.api.messages.NetconfHelloMessageAdditionalHeader;
import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
+import org.opendaylight.netconf.nettyutil.NetconfSessionNegotiatorFactory;
import org.opendaylight.netconf.nettyutil.handler.exi.EXIParameters;
import org.opendaylight.netconf.nettyutil.handler.exi.NetconfStartExiMessage;
-import org.opendaylight.protocol.framework.SessionListenerFactory;
-import org.opendaylight.protocol.framework.SessionNegotiator;
-import org.opendaylight.protocol.framework.SessionNegotiatorFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class NetconfClientSessionNegotiatorFactory implements SessionNegotiatorFactory<NetconfMessage,
- NetconfClientSession, NetconfClientSessionListener> {
+public class NetconfClientSessionNegotiatorFactory
+ implements NetconfSessionNegotiatorFactory<NetconfClientSession, NetconfClientSessionListener> {
public static final Set<String> EXI_CLIENT_CAPABILITIES = ImmutableSet.of(
XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0,
}
@Override
- public SessionNegotiator<NetconfClientSession> getSessionNegotiator(
- final SessionListenerFactory<NetconfClientSessionListener> sessionListenerFactory,
+ public NetconfClientSessionNegotiator getSessionNegotiator(
+ final NetconfSessionListenerFactory<NetconfClientSessionListener> sessionListenerFactory,
final Channel channel, final Promise<NetconfClientSession> promise) {
NetconfMessage startExiMessage = NetconfStartExiMessage.create(options, START_EXI_MESSAGE_ID);
import org.opendaylight.netconf.api.messages.NetconfHelloMessageAdditionalHeader;
import org.opendaylight.netconf.client.NetconfClientSessionListener;
import org.opendaylight.netconf.client.SslHandlerFactory;
+import org.opendaylight.netconf.nettyutil.ReconnectStrategy;
import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
-import org.opendaylight.protocol.framework.ReconnectStrategy;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.opendaylight.netconf.api.messages.NetconfHelloMessageAdditionalHeader;
import org.opendaylight.netconf.client.NetconfClientSessionListener;
import org.opendaylight.netconf.client.SslHandlerFactory;
+import org.opendaylight.netconf.nettyutil.ReconnectStrategy;
import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
-import org.opendaylight.protocol.framework.ReconnectStrategy;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
public class NetconfClientConfigurationBuilder {
import org.opendaylight.netconf.api.messages.NetconfHelloMessageAdditionalHeader;
import org.opendaylight.netconf.client.NetconfClientSessionListener;
import org.opendaylight.netconf.client.SslHandlerFactory;
+import org.opendaylight.netconf.nettyutil.ReconnectStrategy;
+import org.opendaylight.netconf.nettyutil.ReconnectStrategyFactory;
import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
-import org.opendaylight.protocol.framework.ReconnectStrategy;
-import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
public final class NetconfReconnectingClientConfiguration extends NetconfClientConfiguration {
import org.opendaylight.netconf.api.messages.NetconfHelloMessageAdditionalHeader;
import org.opendaylight.netconf.client.NetconfClientSessionListener;
import org.opendaylight.netconf.client.SslHandlerFactory;
+import org.opendaylight.netconf.nettyutil.ReconnectStrategy;
+import org.opendaylight.netconf.nettyutil.ReconnectStrategyFactory;
import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
-import org.opendaylight.protocol.framework.ReconnectStrategy;
-import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
public final class NetconfReconnectingClientConfigurationBuilder extends NetconfClientConfigurationBuilder {
import org.opendaylight.netconf.api.messages.NetconfHelloMessageAdditionalHeader;
import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
import org.opendaylight.netconf.client.conf.NetconfClientConfigurationBuilder;
+import org.opendaylight.netconf.nettyutil.ReconnectStrategy;
import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
-import org.opendaylight.protocol.framework.ReconnectStrategy;
public class NetconfClientConfigurationTest {
@Test
import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfiguration;
import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfigurationBuilder;
+import org.opendaylight.netconf.nettyutil.ReconnectStrategy;
+import org.opendaylight.netconf.nettyutil.ReconnectStrategyFactory;
import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
-import org.opendaylight.protocol.framework.ReconnectStrategy;
-import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
public class NetconfClientDispatcherImplTest {
@Test
import io.netty.util.Timer;
import io.netty.util.concurrent.Promise;
import org.junit.Test;
-import org.opendaylight.protocol.framework.SessionListenerFactory;
-import org.opendaylight.protocol.framework.SessionNegotiator;
+import org.opendaylight.netconf.api.NetconfSessionListenerFactory;
public class NetconfClientSessionNegotiatorFactoryTest {
@Test
public void testGetSessionNegotiator() throws Exception {
NetconfClientSessionListener sessionListener = mock(NetconfClientSessionListener.class);
Timer timer = new HashedWheelTimer();
- SessionListenerFactory<NetconfClientSessionListener> listenerFactory = mock(SessionListenerFactory.class);
+ NetconfSessionListenerFactory<NetconfClientSessionListener> listenerFactory =
+ mock(NetconfSessionListenerFactory.class);
doReturn(sessionListener).when(listenerFactory).getSessionListener();
Channel channel = mock(Channel.class);
NetconfClientSessionNegotiatorFactory negotiatorFactory = new NetconfClientSessionNegotiatorFactory(timer,
Optional.absent(), 200L);
- SessionNegotiator<?> sessionNegotiator = negotiatorFactory.getSessionNegotiator(listenerFactory, channel,
- promise);
+ NetconfClientSessionNegotiator sessionNegotiator = negotiatorFactory.getSessionNegotiator(listenerFactory,
+ channel, promise);
assertNotNull(sessionNegotiator);
}
}
import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfiguration;
import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfigurationBuilder;
+import org.opendaylight.netconf.nettyutil.ReconnectStrategy;
+import org.opendaylight.netconf.nettyutil.ReconnectStrategyFactory;
import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
-import org.opendaylight.protocol.framework.ReconnectStrategy;
-import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
public class NetconfReconnectingClientConfigurationTest {
@Test
* 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.client;
import static org.mockito.ArgumentMatchers.any;
import io.netty.channel.ChannelPipeline;
import io.netty.util.concurrent.Promise;
import org.junit.Test;
+import org.opendaylight.netconf.api.NetconfSessionListenerFactory;
import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
-import org.opendaylight.protocol.framework.SessionListenerFactory;
-import org.opendaylight.protocol.framework.SessionNegotiator;
public class SshClientChannelInitializerTest {
@Test
NetconfClientSessionNegotiatorFactory negotiatorFactory = mock(NetconfClientSessionNegotiatorFactory.class);
NetconfClientSessionListener sessionListener = mock(NetconfClientSessionListener.class);
- SessionNegotiator<?> sessionNegotiator = mock(SessionNegotiator.class);
+ NetconfClientSessionNegotiator sessionNegotiator = mock(NetconfClientSessionNegotiator.class);
doReturn("").when(sessionNegotiator).toString();
- doReturn(sessionNegotiator).when(negotiatorFactory).getSessionNegotiator(any(SessionListenerFactory.class),
- any(Channel.class), any(Promise.class));
+ doReturn(sessionNegotiator).when(negotiatorFactory).getSessionNegotiator(
+ any(NetconfSessionListenerFactory.class), any(Channel.class), any(Promise.class));
ChannelPipeline pipeline = mock(ChannelPipeline.class);
doReturn(pipeline).when(pipeline).addAfter(anyString(), anyString(), any(ChannelHandler.class));
Channel channel = mock(Channel.class);
* 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.client;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyString;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import io.netty.channel.ChannelPipeline;
import io.netty.util.concurrent.Promise;
import org.junit.Test;
-import org.opendaylight.protocol.framework.SessionListenerFactory;
-import org.opendaylight.protocol.framework.SessionNegotiator;
+import org.opendaylight.netconf.api.NetconfSessionListenerFactory;
public class TcpClientChannelInitializerTest {
@Test
public void testInitializeSessionNegotiator() throws Exception {
NetconfClientSessionNegotiatorFactory factory = mock(NetconfClientSessionNegotiatorFactory.class);
- SessionNegotiator<?> sessionNegotiator = mock(SessionNegotiator.class);
+ NetconfClientSessionNegotiator sessionNegotiator = mock(NetconfClientSessionNegotiator.class);
doReturn("").when(sessionNegotiator).toString();
- doReturn(sessionNegotiator).when(factory).getSessionNegotiator(any(SessionListenerFactory.class),
+ doReturn(sessionNegotiator).when(factory).getSessionNegotiator(any(NetconfSessionListenerFactory.class),
any(Channel.class), any(Promise.class));
NetconfClientSessionListener listener = mock(NetconfClientSessionListener.class);
final TcpClientChannelInitializer initializer = new TcpClientChannelInitializer(factory, listener);
import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
import org.opendaylight.netconf.client.conf.NetconfClientConfiguration.NetconfClientProtocol;
import org.opendaylight.netconf.client.conf.NetconfClientConfigurationBuilder;
+import org.opendaylight.netconf.nettyutil.NeverReconnectStrategy;
import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.LoginPasswordHandler;
-import org.opendaylight.protocol.framework.NeverReconnectStrategy;
/**
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelPipeline;
import io.netty.util.concurrent.Promise;
-import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.protocol.framework.SessionListenerFactory;
-import org.opendaylight.protocol.framework.SessionNegotiator;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.opendaylight.netconf.api.NetconfSessionListenerFactory;
+@RunWith(MockitoJUnitRunner.class)
public class TlsClientChannelInitializerTest {
@Mock
private SslHandlerFactory sslHandlerFactory;
@Mock
private NetconfClientSessionListener sessionListener;
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- }
-
@SuppressWarnings("unchecked")
@Test
public void testInitialize() throws Exception {
- SessionNegotiator<?> sessionNegotiator = mock(SessionNegotiator.class);
- doReturn(sessionNegotiator).when(negotiatorFactory).getSessionNegotiator(any(SessionListenerFactory.class),
- any(Channel.class), any(Promise.class));
+ NetconfClientSessionNegotiator sessionNegotiator = mock(NetconfClientSessionNegotiator.class);
+ doReturn(sessionNegotiator).when(negotiatorFactory).getSessionNegotiator(
+ any(NetconfSessionListenerFactory.class), any(Channel.class), any(Promise.class));
ChannelPipeline pipeline = mock(ChannelPipeline.class);
doReturn(pipeline).when(pipeline).addAfter(anyString(), anyString(), any(ChannelHandler.class));
Channel channel = mock(Channel.class);
* 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.impl;
import io.netty.channel.Channel;
import org.opendaylight.netconf.api.NetconfServerDispatcher;
import org.opendaylight.netconf.impl.util.DeserializerExceptionHandler;
import org.opendaylight.netconf.nettyutil.AbstractChannelInitializer;
-import org.opendaylight.protocol.framework.AbstractDispatcher;
+import org.opendaylight.netconf.nettyutil.AbstractNetconfDispatcher;
-public class NetconfServerDispatcherImpl extends AbstractDispatcher<NetconfServerSession,
+public class NetconfServerDispatcherImpl extends AbstractNetconfDispatcher<NetconfServerSession,
NetconfServerSessionListener> implements NetconfServerDispatcher {
private final ServerChannelInitializer initializer;
* 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.impl;
import com.google.common.base.Preconditions;
import java.net.SocketAddress;
import java.util.Set;
import org.opendaylight.netconf.api.NetconfServerSessionPreferences;
+import org.opendaylight.netconf.api.NetconfSessionListenerFactory;
import org.opendaylight.netconf.api.messages.NetconfHelloMessage;
import org.opendaylight.netconf.api.monitoring.NetconfMonitoringService;
import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
import org.opendaylight.netconf.impl.osgi.NetconfOperationRouterImpl;
import org.opendaylight.netconf.mapping.api.NetconfOperationService;
import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactory;
-import org.opendaylight.protocol.framework.SessionListenerFactory;
-import org.opendaylight.protocol.framework.SessionNegotiator;
-import org.opendaylight.protocol.framework.SessionNegotiatorFactory;
+import org.opendaylight.netconf.nettyutil.NetconfSessionNegotiatorFactory;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Capabilities;
-public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorFactory<NetconfHelloMessage,
- NetconfServerSession, NetconfServerSessionListener> {
+public class NetconfServerSessionNegotiatorFactory
+ implements NetconfSessionNegotiatorFactory<NetconfServerSession, NetconfServerSessionListener> {
public static final Set<String> DEFAULT_BASE_CAPABILITIES = ImmutableSet.of(
XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0,
* @return session negotiator
*/
@Override
- public SessionNegotiator<NetconfServerSession> getSessionNegotiator(
- final SessionListenerFactory<NetconfServerSessionListener> defunctSessionListenerFactory,
+ public NetconfServerSessionNegotiator getSessionNegotiator(
+ final NetconfSessionListenerFactory<NetconfServerSessionListener> defunctSessionListenerFactory,
final Channel channel, final Promise<NetconfServerSession> promise) {
final long sessionId = idProvider.getNextSessionId();
import org.opendaylight.netconf.mapping.api.NetconfOperationChainedExecution;
import org.opendaylight.netconf.mapping.api.NetconfOperationService;
import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactory;
+import org.opendaylight.netconf.nettyutil.NeverReconnectStrategy;
import org.opendaylight.netconf.nettyutil.handler.exi.NetconfStartExiMessage;
import org.opendaylight.netconf.util.messages.NetconfMessageUtil;
import org.opendaylight.netconf.util.test.XmlFileLoader;
-import org.opendaylight.protocol.framework.NeverReconnectStrategy;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.CapabilitiesBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
* 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.protocol.framework;
+package org.opendaylight.netconf.nettyutil;
import com.google.common.base.Preconditions;
import io.netty.bootstrap.Bootstrap;
import java.io.Closeable;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
+import org.opendaylight.netconf.api.NetconfSession;
+import org.opendaylight.netconf.api.NetconfSessionListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
* start method that will handle sockets in different thread.
*/
@Deprecated
-public abstract class AbstractDispatcher<S extends ProtocolSession<?>, L extends SessionListener<?, ?, ?>> implements Closeable {
+public abstract class AbstractNetconfDispatcher<S extends NetconfSession, L extends NetconfSessionListener<? super S>>
+ implements Closeable {
-
- protected interface ChannelPipelineInitializer<CH extends Channel, S extends ProtocolSession<?>> {
+ protected interface ChannelPipelineInitializer<C extends Channel, S extends NetconfSession> {
/**
- * Initializes channel by specifying the handlers in its pipeline. Handlers are protocol specific, therefore this
- * method needs to be implemented in protocol specific Dispatchers.
+ * Initializes channel by specifying the handlers in its pipeline. Handlers are protocol specific, therefore
+ * this method needs to be implemented in protocol specific Dispatchers.
*
- * @param channel whose pipeline should be defined, also to be passed to {@link SessionNegotiatorFactory}
- * @param promise to be passed to {@link SessionNegotiatorFactory}
+ * @param channel whose pipeline should be defined, also to be passed to {@link NetconfSessionNegotiatorFactory}
+ * @param promise to be passed to {@link NetconfSessionNegotiatorFactory}
*/
- void initializeChannel(CH channel, Promise<S> promise);
+ void initializeChannel(C channel, Promise<S> promise);
}
- protected interface PipelineInitializer<S extends ProtocolSession<?>> extends ChannelPipelineInitializer<SocketChannel, S> {
+ protected interface PipelineInitializer<S extends NetconfSession>
+ extends ChannelPipelineInitializer<SocketChannel, S> {
}
- private static final Logger LOG = LoggerFactory.getLogger(AbstractDispatcher.class);
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractNetconfDispatcher.class);
private final EventLoopGroup bossGroup;
private final EventExecutor executor;
- protected AbstractDispatcher(final EventLoopGroup bossGroup, final EventLoopGroup workerGroup) {
+ protected AbstractNetconfDispatcher(final EventLoopGroup bossGroup, final EventLoopGroup workerGroup) {
this(GlobalEventExecutor.INSTANCE, bossGroup, workerGroup);
}
- protected AbstractDispatcher(final EventExecutor executor, final EventLoopGroup bossGroup, final EventLoopGroup workerGroup) {
+ protected AbstractNetconfDispatcher(final EventExecutor executor, final EventLoopGroup bossGroup,
+ final EventLoopGroup workerGroup) {
this.bossGroup = Preconditions.checkNotNull(bossGroup);
this.workerGroup = Preconditions.checkNotNull(workerGroup);
this.executor = Preconditions.checkNotNull(executor);
*
* @return ChannelFuture representing the binding process
*/
- protected <CH extends Channel> ChannelFuture createServer(final SocketAddress address, final Class<? extends ServerChannel> channelClass,
- final ChannelPipelineInitializer<CH, S> initializer) {
+ protected <C extends Channel> ChannelFuture createServer(final SocketAddress address,
+ final Class<? extends ServerChannel> channelClass, final ChannelPipelineInitializer<C, S> initializer) {
final ServerBootstrap b = new ServerBootstrap();
- b.childHandler(new ChannelInitializer<CH>() {
+ b.childHandler(new ChannelInitializer<C>() {
@Override
- protected void initChannel(final CH ch) {
+ protected void initChannel(final C ch) {
initializer.initializeChannel(ch, new DefaultPromise<>(executor));
}
});
* subclasses to assign non-default server options before the server is
* created.
*
- * @param b Server bootstrap
+ * @param bootstrap Server bootstrap
+ */
+ protected void customizeBootstrap(final ServerBootstrap bootstrap) {
+ // The default is a no-op
+ }
+
+ /**
+ * Customize a client bootstrap before the connection is attempted. This
+ * allows subclasses to assign non-default options before the client is
+ * created.
+ *
+ * @param bootstrap Client bootstrap
*/
- protected void customizeBootstrap(final ServerBootstrap b) {
+ protected void customizeBootstrap(final Bootstrap bootstrap) {
// The default is a no-op
}
* @return Future representing the connection process. Its result represents the combined success of TCP connection
* as well as session negotiation.
*/
- protected Future<S> createClient(final InetSocketAddress address, final ReconnectStrategy strategy, final PipelineInitializer<S> initializer) {
+ protected Future<S> createClient(final InetSocketAddress address, final ReconnectStrategy strategy,
+ final PipelineInitializer<S> initializer) {
final Bootstrap b = new Bootstrap();
- final ProtocolSessionPromise<S> p = new ProtocolSessionPromise<>(executor, address, strategy, b);
+ final NetconfSessionPromise<S> p = new NetconfSessionPromise<>(executor, address, strategy, b);
b.option(ChannelOption.SO_KEEPALIVE, true).handler(
new ChannelInitializer<SocketChannel>() {
@Override
return p;
}
- private void setWorkerGroup(final Bootstrap b) {
- if (b.group() == null) {
- b.group(workerGroup);
- }
- }
-
/**
* Create a client but use a pre-configured bootstrap.
* This method however replaces the ChannelInitializer in the bootstrap. All other configuration is preserved.
*
* @param address remote address
*/
- protected Future<S> createClient(final InetSocketAddress address, final ReconnectStrategy strategy, final Bootstrap bootstrap, final PipelineInitializer<S> initializer) {
- final ProtocolSessionPromise<S> p = new ProtocolSessionPromise<>(executor, address, strategy, bootstrap);
+ protected Future<S> createClient(final InetSocketAddress address, final ReconnectStrategy strategy,
+ final Bootstrap bootstrap, final PipelineInitializer<S> initializer) {
+ final NetconfSessionPromise<S> p = new NetconfSessionPromise<>(executor, address, strategy, bootstrap);
bootstrap.handler(
new ChannelInitializer<SocketChannel>() {
}
/**
- * Customize a client bootstrap before the connection is attempted. This
- * allows subclasses to assign non-default options before the client is
- * created.
- *
- * @param b Client bootstrap
- */
- protected void customizeBootstrap(final Bootstrap b) {
- // The default is a no-op
- }
-
- /**
- *
- * @deprecated use {@link org.opendaylight.protocol.framework.AbstractDispatcher#createReconnectingClient(java.net.InetSocketAddress, ReconnectStrategyFactory, org.opendaylight.protocol.framework.AbstractDispatcher.PipelineInitializer)} with only one reconnectStrategyFactory instead.
- *
* Creates a client.
*
* @param address remote address
* @param connectStrategyFactory Factory for creating reconnection strategy to be used when initial connection fails
* @param reestablishStrategy Reconnection strategy to be used when the already-established session fails
- *
* @return Future representing the reconnection task. It will report completion based on reestablishStrategy, e.g.
* success if it indicates no further attempts should be made and failure if it reports an error
+ * @deprecated Use
+ * {@link #createReconnectingClient(InetSocketAddress, ReconnectStrategyFactory, PipelineInitializer)}
+ * instead.
*/
@Deprecated
- protected Future<Void> createReconnectingClient(final InetSocketAddress address, final ReconnectStrategyFactory connectStrategyFactory,
- final ReconnectStrategy reestablishStrategy, final PipelineInitializer<S> initializer) {
+ protected Future<Void> createReconnectingClient(final InetSocketAddress address,
+ final ReconnectStrategyFactory connectStrategyFactory, final ReconnectStrategy reestablishStrategy,
+ final PipelineInitializer<S> initializer) {
return createReconnectingClient(address, connectStrategyFactory, initializer);
}
*
* @param address remote address
* @param connectStrategyFactory Factory for creating reconnection strategy for every reconnect attempt
- *
* @return Future representing the reconnection task. It will report completion based on reestablishStrategy, e.g.
* success is never reported, only failure when it runs out of reconnection attempts.
*/
- protected Future<Void> createReconnectingClient(final InetSocketAddress address, final ReconnectStrategyFactory connectStrategyFactory,
- final PipelineInitializer<S> initializer) {
+ protected Future<Void> createReconnectingClient(final InetSocketAddress address,
+ final ReconnectStrategyFactory connectStrategyFactory, final PipelineInitializer<S> initializer) {
final Bootstrap b = new Bootstrap();
- final ReconnectPromise<S, L> p = new ReconnectPromise<>(GlobalEventExecutor.INSTANCE, this, address, connectStrategyFactory, b, initializer);
+ final ReconnectPromise<S, L> p = new ReconnectPromise<>(GlobalEventExecutor.INSTANCE, this, address,
+ connectStrategyFactory, b, initializer);
b.option(ChannelOption.SO_KEEPALIVE, true);
return p;
}
- private void setChannelFactory(final Bootstrap b) {
+ private static void setChannelFactory(final Bootstrap bootstrap) {
// There is no way to detect if this was already set by
// customizeBootstrap()
try {
- b.channel(NioSocketChannel.class);
+ bootstrap.channel(NioSocketChannel.class);
} catch (final IllegalStateException e) {
- LOG.trace("Not overriding channelFactory on bootstrap {}", b, e);
+ LOG.trace("Not overriding channelFactory on bootstrap {}", bootstrap, e);
+ }
+ }
+
+ private void setWorkerGroup(final Bootstrap bootstrap) {
+ if (bootstrap.group() == null) {
+ bootstrap.group(workerGroup);
}
}
- /**
- * @deprecated Should only be used with AbstractDispatcher#AbstractDispatcher()
- */
@Deprecated
@Override
public void close() {
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;
+import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.MessageToByteEncoder;
import java.io.IOException;
import org.opendaylight.netconf.nettyutil.handler.NetconfEXIToMessageDecoder;
import org.opendaylight.netconf.nettyutil.handler.NetconfMessageToEXIEncoder;
import org.opendaylight.netconf.nettyutil.handler.exi.EXIParameters;
-import org.opendaylight.protocol.framework.AbstractProtocolSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class AbstractNetconfSession<S extends NetconfSession,L extends NetconfSessionListener<S>>
- extends AbstractProtocolSession<NetconfMessage> implements NetconfSession, NetconfExiSession {
+ extends SimpleChannelInboundHandler<Object> implements NetconfSession, NetconfExiSession {
+
private static final Logger LOG = LoggerFactory.getLogger(AbstractNetconfSession.class);
private final L sessionListener;
private final long sessionId;
sessionListener.onSessionTerminated(thisInstance(), new NetconfTerminationReason("Session closed"));
}
- @Override
protected void handleMessage(final NetconfMessage netconfMessage) {
LOG.debug("handling incoming message");
sessionListener.onMessage(thisInstance(), netconfMessage);
return promise;
}
- @Override
protected void endOfInput() {
LOG.debug("Session {} end of input detected while session was in state {}", toString(), isUp() ? "up"
: "initialized");
}
}
- @Override
protected void sessionUp() {
LOG.debug("Session {} up", toString());
sessionListener.onSessionUp(thisInstance());
public final long getSessionId() {
return sessionId;
}
+
+ @Override
+ @SuppressWarnings("checkstyle:illegalCatch")
+ public final void channelInactive(final ChannelHandlerContext ctx) {
+ LOG.debug("Channel {} inactive.", ctx.channel());
+ endOfInput();
+ try {
+ // Forward channel inactive event, all handlers in pipeline might be interested in the event e.g. close
+ // channel handler of reconnect promise
+ super.channelInactive(ctx);
+ } catch (final Exception e) {
+ throw new RuntimeException("Failed to delegate channel inactive event on channel " + ctx.channel(), e);
+ }
+ }
+
+ @Override
+ protected final void channelRead0(final ChannelHandlerContext ctx, final Object msg) {
+ LOG.debug("Message was received: {}", msg);
+ handleMessage((NetconfMessage) msg);
+ }
+
+ @Override
+ public final void handlerAdded(final ChannelHandlerContext ctx) {
+ sessionUp();
+ }
}
* 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 static com.google.common.base.Preconditions.checkState;
+import static java.util.Objects.requireNonNull;
+
import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandler;
import org.opendaylight.netconf.nettyutil.handler.NetconfXMLToHelloMessageDecoder;
import org.opendaylight.netconf.nettyutil.handler.NetconfXMLToMessageDecoder;
import org.opendaylight.netconf.util.messages.FramingMechanism;
-import org.opendaylight.protocol.framework.AbstractSessionNegotiator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
public abstract class AbstractNetconfSessionNegotiator<P extends NetconfSessionPreferences,
S extends AbstractNetconfSession<S, L>, L extends NetconfSessionListener<S>>
- extends AbstractSessionNegotiator<NetconfHelloMessage, S> {
+ extends ChannelInboundHandlerAdapter implements NetconfSessionNegotiator<S> {
private static final Logger LOG = LoggerFactory.getLogger(AbstractNetconfSessionNegotiator.class);
public static final String NAME_OF_EXCEPTION_HANDLER = "lastExceptionHandler";
protected final P sessionPreferences;
+ protected final Channel channel;
+ private final Promise<S> promise;
private final L sessionListener;
private Timeout timeout;
}
private State state = State.IDLE;
- private final Promise<S> promise;
private final Timer timer;
private final long connectionTimeoutMillis;
protected AbstractNetconfSessionNegotiator(final P sessionPreferences, final Promise<S> promise,
final Channel channel, final Timer timer,
final L sessionListener, final long connectionTimeoutMillis) {
- super(promise, channel);
+ this.channel = requireNonNull(channel);
+ this.promise = requireNonNull(promise);
this.sessionPreferences = sessionPreferences;
- this.promise = promise;
this.timer = timer;
this.sessionListener = sessionListener;
this.connectionTimeoutMillis = connectionTimeoutMillis;
}
- @Override
protected final void startNegotiation() {
if (ifNegotiatedAlready()) {
LOG.debug("Negotiation on channel {} already started", channel);
final Optional<SslHandler> sslHandler = getSslHandler(channel);
if (sslHandler.isPresent()) {
sslHandler.get().handshakeFuture().addListener(future -> {
- Preconditions.checkState(future.isSuccess(), "Ssl handshake was not successful");
+ checkState(future.isSuccess(), "Ssl handshake was not successful");
LOG.debug("Ssl handshake complete");
start();
});
protected final S getSessionForHelloMessage(final NetconfHelloMessage netconfMessage)
throws NetconfDocumentedException {
- Preconditions.checkNotNull(netconfMessage, "netconfMessage");
-
final Document doc = netconfMessage.getDocument();
if (shouldUseChunkFraming(doc)) {
ChannelHandler helloMessageHandler = replaceChannelHandler(channel,
AbstractChannelInitializer.NETCONF_MESSAGE_DECODER, new NetconfXMLToMessageDecoder());
- Preconditions.checkState(helloMessageHandler instanceof NetconfXMLToHelloMessageDecoder,
+ checkState(helloMessageHandler instanceof NetconfXMLToHelloMessageDecoder,
"Pipeline handlers misplaced on session: %s, pipeline: %s", session, channel.pipeline());
Iterable<NetconfMessage> netconfMessagesFromNegotiation =
((NetconfXMLToHelloMessageDecoder) helloMessageHandler).getPostHelloNetconfMessages();
private synchronized void changeState(final State newState) {
LOG.debug("Changing state from : {} to : {} for channel: {}", state, newState, channel);
- Preconditions.checkState(isStateChangePermitted(state, newState),
+ checkState(isStateChangePermitted(state, newState),
"Cannot change state from %s to %s for chanel %s", state, newState, channel);
this.state = newState;
}
changeState(State.FAILED);
}
}
+
+ protected final void negotiationSuccessful(final S session) {
+ LOG.debug("Negotiation on channel {} successful with session {}", channel, session);
+ channel.pipeline().replace(this, "session", session);
+ promise.setSuccess(session);
+ }
+
+ protected void negotiationFailed(final Throwable cause) {
+ LOG.debug("Negotiation on channel {} failed", channel, cause);
+ channel.close();
+ promise.setFailure(cause);
+ }
+
+ /**
+ * Send a message to peer and fail negotiation if it does not reach
+ * the peer.
+ *
+ * @param msg Message which should be sent.
+ */
+ protected final void sendMessage(final NetconfMessage msg) {
+ this.channel.writeAndFlush(msg).addListener(f -> {
+ if (!f.isSuccess()) {
+ LOG.info("Failed to send message {}", msg, f.cause());
+ negotiationFailed(f.cause());
+ } else {
+ LOG.trace("Message {} sent to socket", msg);
+ }
+ });
+ }
+
+ @Override
+ @SuppressWarnings("checkstyle:illegalCatch")
+ public final void channelActive(final ChannelHandlerContext ctx) {
+ LOG.debug("Starting session negotiation on channel {}", channel);
+ try {
+ startNegotiation();
+ } catch (final Exception e) {
+ LOG.warn("Unexpected negotiation failure", e);
+ negotiationFailed(e);
+ }
+ }
+
+ @Override
+ @SuppressWarnings("checkstyle:illegalCatch")
+ public final void channelRead(final ChannelHandlerContext ctx, final Object msg) {
+ LOG.debug("Negotiation read invoked on channel {}", channel);
+ try {
+ handleMessage((NetconfHelloMessage) msg);
+ } catch (final Exception e) {
+ LOG.debug("Unexpected error while handling negotiation message {}", msg, e);
+ negotiationFailed(e);
+ }
+ }
+
+ @Override
+ public void exceptionCaught(final ChannelHandlerContext ctx, final Throwable cause) {
+ LOG.info("Unexpected error during negotiation", cause);
+ negotiationFailed(cause);
+ }
+
+ protected abstract void handleMessage(NetconfHelloMessage msg) throws Exception;
}
* 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.protocol.framework;
+package org.opendaylight.netconf.nettyutil;
import io.netty.channel.ChannelInboundHandler;
+import org.opendaylight.netconf.api.NetconfSession;
/**
* Session negotiator concepts. A negotiator is responsible for message
* @param <T> Protocol session type.
*/
@Deprecated
-public interface SessionNegotiator<T extends ProtocolSession<?>> extends ChannelInboundHandler {
+public interface NetconfSessionNegotiator<T extends NetconfSession> extends ChannelInboundHandler {
}
* 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.protocol.framework;
+package org.opendaylight.netconf.nettyutil;
import io.netty.channel.Channel;
import io.netty.util.concurrent.Promise;
+import org.opendaylight.netconf.api.NetconfSession;
+import org.opendaylight.netconf.api.NetconfSessionListener;
+import org.opendaylight.netconf.api.NetconfSessionListenerFactory;
/**
* A factory class creating SessionNegotiators.
* @param <S> session type
*/
@Deprecated
-public interface SessionNegotiatorFactory<M, S extends ProtocolSession<?>, L extends SessionListener<?, ?, ?>> {
+public interface NetconfSessionNegotiatorFactory<S extends NetconfSession,
+ L extends NetconfSessionListener<? super S>> {
/**
* Create a new negotiator attached to a channel, which will notify
* a promise once the negotiation completes.
* @param promise Promise to be notified
* @return new negotiator instance
*/
- SessionNegotiator<S> getSessionNegotiator(SessionListenerFactory<L> factory, Channel channel, Promise<S> promise);
+ NetconfSessionNegotiator<S> getSessionNegotiator(NetconfSessionListenerFactory<L> factory, Channel channel,
+ Promise<S> promise);
}
* 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.protocol.framework;
+package org.opendaylight.netconf.nettyutil;
import com.google.common.base.Preconditions;
import io.netty.bootstrap.Bootstrap;
import java.net.InetSocketAddress;
import javax.annotation.concurrent.GuardedBy;
import javax.annotation.concurrent.ThreadSafe;
+import org.opendaylight.netconf.api.NetconfSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Deprecated
@ThreadSafe
-final class ProtocolSessionPromise<S extends ProtocolSession<?>> extends DefaultPromise<S> {
- private static final Logger LOG = LoggerFactory.getLogger(ProtocolSessionPromise.class);
+final class NetconfSessionPromise<S extends NetconfSession> extends DefaultPromise<S> {
+ private static final Logger LOG = LoggerFactory.getLogger(NetconfSessionPromise.class);
private final ReconnectStrategy strategy;
private InetSocketAddress address;
- private final Bootstrap b;
+ private final Bootstrap bootstrap;
@GuardedBy("this")
private Future<?> pending;
- ProtocolSessionPromise(final EventExecutor executor, final InetSocketAddress address, final ReconnectStrategy strategy,
- final Bootstrap b) {
+ NetconfSessionPromise(final EventExecutor executor, final InetSocketAddress address,
+ final ReconnectStrategy strategy, final Bootstrap bootstrap) {
super(executor);
this.strategy = Preconditions.checkNotNull(strategy);
this.address = Preconditions.checkNotNull(address);
- this.b = Preconditions.checkNotNull(b);
+ this.bootstrap = Preconditions.checkNotNull(bootstrap);
}
+ @SuppressWarnings("checkstyle:illegalCatch")
synchronized void connect() {
- final Object lock = this;
-
try {
final int timeout = this.strategy.getConnectTimeout();
- LOG.debug("Promise {} attempting connect for {}ms", lock, timeout);
+ LOG.debug("Promise {} attempting connect for {}ms", this, timeout);
- if(this.address.isUnresolved()) {
+ if (this.address.isUnresolved()) {
this.address = new InetSocketAddress(this.address.getHostName(), this.address.getPort());
}
- this.b.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, timeout);
- final ChannelFuture connectFuture = this.b.connect(this.address);
+ this.bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, timeout);
+ final ChannelFuture connectFuture = this.bootstrap.connect(this.address);
// Add listener that attempts reconnect by invoking this method again.
- connectFuture.addListener(new BootstrapConnectListener(lock));
+ connectFuture.addListener(new BootstrapConnectListener());
this.pending = connectFuture;
} catch (final Exception e) {
LOG.info("Failed to connect to {}", address, e);
}
private class BootstrapConnectListener implements ChannelFutureListener {
- private final Object lock;
-
- public BootstrapConnectListener(final Object lock) {
- this.lock = lock;
- }
-
@Override
public void operationComplete(final ChannelFuture cf) {
- synchronized (lock) {
+ synchronized (NetconfSessionPromise.this) {
- LOG.debug("Promise {} connection resolved", lock);
+ LOG.debug("Promise {} connection resolved", NetconfSessionPromise.this);
// Triggered when a connection attempt is resolved.
- Preconditions.checkState(ProtocolSessionPromise.this.pending.equals(cf));
+ Preconditions.checkState(NetconfSessionPromise.this.pending.equals(cf));
/*
* The promise we gave out could have been cancelled,
*/
if (isCancelled()) {
if (cf.isSuccess()) {
- LOG.debug("Closing channel for cancelled promise {}", lock);
+ LOG.debug("Closing channel for cancelled promise {}", NetconfSessionPromise.this);
cf.channel().close();
}
return;
}
- if(cf.isSuccess()) {
- LOG.debug("Promise {} connection successful", lock);
+ if (cf.isSuccess()) {
+ LOG.debug("Promise {} connection successful", NetconfSessionPromise.this);
return;
}
- LOG.debug("Attempt to connect to {} failed", ProtocolSessionPromise.this.address, cf.cause());
+ LOG.debug("Attempt to connect to {} failed", NetconfSessionPromise.this.address, cf.cause());
- final Future<Void> rf = ProtocolSessionPromise.this.strategy.scheduleReconnect(cf.cause());
+ final Future<Void> rf = NetconfSessionPromise.this.strategy.scheduleReconnect(cf.cause());
rf.addListener(new ReconnectingStrategyListener());
- ProtocolSessionPromise.this.pending = rf;
+ NetconfSessionPromise.this.pending = rf;
}
}
private class ReconnectingStrategyListener implements FutureListener<Void> {
@Override
public void operationComplete(final Future<Void> sf) {
- synchronized (lock) {
+ synchronized (NetconfSessionPromise.this) {
// Triggered when a connection attempt is to be made.
- Preconditions.checkState(ProtocolSessionPromise.this.pending.equals(sf));
+ Preconditions.checkState(NetconfSessionPromise.this.pending.equals(sf));
/*
* The promise we gave out could have been cancelled,
}
}
}
-
}
-
}
* 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.protocol.framework;
+package org.opendaylight.netconf.nettyutil;
+import com.google.common.base.Preconditions;
import io.netty.util.concurrent.EventExecutor;
import io.netty.util.concurrent.Future;
-
import javax.annotation.concurrent.ThreadSafe;
-import com.google.common.base.Preconditions;
-
/**
* Utility ReconnectStrategy singleton, which will cause the reconnect process
* to always fail.
* 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.protocol.framework;
+package org.opendaylight.netconf.nettyutil;
+import com.google.common.base.Preconditions;
import io.netty.util.concurrent.EventExecutor;
import io.netty.util.concurrent.Future;
-
import javax.annotation.concurrent.ThreadSafe;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Preconditions;
-
/**
* Utility ReconnectStrategy singleton, which will cause the reconnect process
* to immediately schedule a reconnection attempt.
* 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.protocol.framework;
+package org.opendaylight.netconf.nettyutil;
import com.google.common.base.Preconditions;
import io.netty.bootstrap.Bootstrap;
import io.netty.util.concurrent.EventExecutor;
import io.netty.util.concurrent.Future;
import java.net.InetSocketAddress;
+import org.opendaylight.netconf.api.NetconfSession;
+import org.opendaylight.netconf.api.NetconfSessionListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Deprecated
-final class ReconnectPromise<S extends ProtocolSession<?>, L extends SessionListener<?, ?, ?>> extends DefaultPromise<Void> {
+final class ReconnectPromise<S extends NetconfSession, L extends NetconfSessionListener<? super S>>
+ extends DefaultPromise<Void> {
private static final Logger LOG = LoggerFactory.getLogger(ReconnectPromise.class);
- private final AbstractDispatcher<S, L> dispatcher;
+ private final AbstractNetconfDispatcher<S, L> dispatcher;
private final InetSocketAddress address;
private final ReconnectStrategyFactory strategyFactory;
- private final Bootstrap b;
- private final AbstractDispatcher.PipelineInitializer<S> initializer;
+ private final Bootstrap bootstrap;
+ private final AbstractNetconfDispatcher.PipelineInitializer<S> initializer;
private Future<?> pending;
- public ReconnectPromise(final EventExecutor executor, final AbstractDispatcher<S, L> dispatcher, final InetSocketAddress address,
- final ReconnectStrategyFactory connectStrategyFactory, final Bootstrap b, final AbstractDispatcher.PipelineInitializer<S> initializer) {
+ ReconnectPromise(final EventExecutor executor, final AbstractNetconfDispatcher<S, L> dispatcher,
+ final InetSocketAddress address, final ReconnectStrategyFactory connectStrategyFactory,
+ final Bootstrap bootstrap, final AbstractNetconfDispatcher.PipelineInitializer<S> initializer) {
super(executor);
- this.b = b;
+ this.bootstrap = bootstrap;
this.initializer = Preconditions.checkNotNull(initializer);
this.dispatcher = Preconditions.checkNotNull(dispatcher);
this.address = Preconditions.checkNotNull(address);
synchronized void connect() {
final ReconnectStrategy cs = this.strategyFactory.createReconnectStrategy();
- // Set up a client with pre-configured bootstrap, but add a closed channel handler into the pipeline to support reconnect attempts
- pending = this.dispatcher.createClient(this.address, cs, b, (channel, promise) -> {
+ // Set up a client with pre-configured bootstrap, but add a closed channel handler into the pipeline to support
+ // reconnect attempts
+ pending = this.dispatcher.createClient(this.address, cs, bootstrap, (channel, promise) -> {
initializer.initializeChannel(channel, promise);
// add closed channel handler
- // This handler has to be added as last channel handler and the channel inactive event has to be caught by it
- // Handlers in front of it can react to channelInactive event, but have to forward the event or the reconnect will not work
- // This handler is last so all handlers in front of it can handle channel inactive (to e.g. resource cleanup) before a new connection is started
+ // This handler has to be added as last channel handler and the channel inactive event has to be caught by
+ // it
+ // Handlers in front of it can react to channelInactive event, but have to forward the event or the
+ // reconnect will not work
+ // This handler is last so all handlers in front of it can handle channel inactive (to e.g. resource
+ // cleanup) before a new connection is started
channel.pipeline().addLast(new ClosedChannelHandler(ReconnectPromise.this));
});
}
/**
+ * Indicate if the initial connection succeeded.
*
- * @return true if initial connection was established successfully, false if initial connection failed due to e.g. Connection refused, Negotiation failed
+ * @return true if initial connection was established successfully, false if initial connection failed due to e.g.
+ * Connection refused, Negotiation failed
*/
- private boolean isInitialConnectFinished() {
+ private synchronized boolean isInitialConnectFinished() {
Preconditions.checkNotNull(pending);
return pending.isDone() && pending.isSuccess();
}
private static final class ClosedChannelHandler extends ChannelInboundHandlerAdapter {
private final ReconnectPromise<?, ?> promise;
- public ClosedChannelHandler(final ReconnectPromise<?, ?> promise) {
+ ClosedChannelHandler(final ReconnectPromise<?, ?> promise) {
this.promise = promise;
}
promise.connect();
}
}
-
}
* 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.protocol.framework;
+package org.opendaylight.netconf.nettyutil;
import io.netty.util.concurrent.Future;
* Interface exposed by a reconnection strategy provider. A reconnection
* strategy decides whether to attempt reconnection and when to do that.
*
+ * <p>
* The proper way of using this API is such that when a connection attempt
* has failed, the user will call scheduleReconnect() to obtain a future,
* which tracks schedule of the next connect attempt. The user should add its
* 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.protocol.framework;
+package org.opendaylight.netconf.nettyutil;
/**
* Factory interface for creating new ReconnectStrategy instances. This is
* 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.protocol.framework;
+package org.opendaylight.netconf.nettyutil;
+import com.google.common.base.Preconditions;
import io.netty.util.concurrent.EventExecutor;
import io.netty.util.concurrent.Future;
-
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
-
import javax.annotation.concurrent.GuardedBy;
import javax.annotation.concurrent.ThreadSafe;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Preconditions;
-
/**
* Swiss army knife equivalent for reconnect strategies.
*
+ * <p>
* This strategy continues to schedule reconnect attempts, each having to complete in a fixed time (connectTime).
*
+ * <p>
* Initial sleep time is specified as minSleep. Each subsequent unsuccessful attempt multiplies this time by a constant
* factor (sleepFactor) -- this allows for either constant reconnect times (sleepFactor = 1), or various degrees of
* exponential back-off (sleepFactor > 1). Maximum sleep time between attempts can be capped to a specific value
* (maxSleep).
*
+ * <p>
* The strategy can optionally give up based on two criteria:
*
+ * <p>
* A preset number of connection retries (maxAttempts) has been reached, or
*
+ * <p>
* A preset absolute deadline is reached (deadline nanoseconds, as reported by System.nanoTime(). In this specific case,
* both connectTime and maxSleep will be controlled such that the connection attempt is resolved as closely to the
* deadline as possible.
*
+ * <p>
* Both these caps can be combined, with the strategy giving up as soon as the first one is reached.
*/
@Deprecated
public final class TimedReconnectStrategy implements ReconnectStrategy {
private static final Logger LOG = LoggerFactory.getLogger(TimedReconnectStrategy.class);
private final EventExecutor executor;
- private final Long deadline, maxAttempts, maxSleep;
+ private final Long deadline;
+ private final Long maxAttempts;
+ private final Long maxSleep;
private final double sleepFactor;
private final int connectTime;
private final long minSleep;
@GuardedBy("this")
private boolean scheduled;
- public TimedReconnectStrategy(final EventExecutor executor, final int connectTime, final long minSleep, final double sleepFactor,
- final Long maxSleep, final Long maxAttempts, final Long deadline) {
+ public TimedReconnectStrategy(final EventExecutor executor, final int connectTime, final long minSleep,
+ final double sleepFactor, final Long maxSleep, final Long maxAttempts, final Long deadline) {
Preconditions.checkArgument(maxSleep == null || minSleep <= maxSleep);
Preconditions.checkArgument(sleepFactor >= 1);
Preconditions.checkArgument(connectTime >= 0);
return this.executor.newSucceededFuture(null);
}
- // Need to retain a final reference to this for locking purposes,
- // also set the scheduled flag.
- final Object lock = this;
+ // Set the scheduled flag.
this.scheduled = true;
// Schedule a task for the right time. It will also clear the flag.
return this.executor.schedule(() -> {
- synchronized (lock) {
+ synchronized (TimedReconnectStrategy.this) {
Preconditions.checkState(TimedReconnectStrategy.this.scheduled);
TimedReconnectStrategy.this.scheduled = false;
}
* 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.protocol.framework;
+package org.opendaylight.netconf.nettyutil;
import io.netty.util.concurrent.EventExecutor;
import java.math.BigDecimal;
import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfiguration;
import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfigurationBuilder;
+import org.opendaylight.netconf.nettyutil.ReconnectStrategyFactory;
+import org.opendaylight.netconf.nettyutil.TimedReconnectStrategyFactory;
import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.LoginPasswordHandler;
import org.opendaylight.netconf.sal.connect.api.RemoteDevice;
import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfConnectorDTO;
import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologySetup;
import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologyUtils;
-import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
-import org.opendaylight.protocol.framework.TimedReconnectStrategyFactory;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfiguration;
import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfigurationBuilder;
+import org.opendaylight.netconf.nettyutil.ReconnectStrategyFactory;
+import org.opendaylight.netconf.nettyutil.TimedReconnectStrategyFactory;
import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.LoginPasswordHandler;
import org.opendaylight.netconf.sal.connect.api.DeviceActionFactory;
import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
import org.opendaylight.netconf.topology.api.NetconfTopology;
import org.opendaylight.netconf.topology.api.SchemaRepositoryProvider;
-import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
-import org.opendaylight.protocol.framework.TimedReconnectStrategyFactory;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
* 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.sal.connect.netconf.listener;
import static org.junit.Assert.assertEquals;
import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfiguration;
import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfigurationBuilder;
+import org.opendaylight.netconf.nettyutil.ReconnectStrategy;
+import org.opendaylight.netconf.nettyutil.TimedReconnectStrategy;
import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.LoginPasswordHandler;
import org.opendaylight.netconf.sal.connect.api.RemoteDevice;
import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil;
import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.protocol.framework.ReconnectStrategy;
-import org.opendaylight.protocol.framework.TimedReconnectStrategy;
import org.opendaylight.yangtools.util.xml.UntrustedXML;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.RpcError;
import org.opendaylight.netconf.client.NetconfClientSession;
import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
import org.opendaylight.netconf.client.conf.NetconfClientConfigurationBuilder;
+import org.opendaylight.netconf.nettyutil.NeverReconnectStrategy;
import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.LoginPasswordHandler;
import org.opendaylight.netconf.sal.connect.api.RemoteDevice;
import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCommunicator;
import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.protocol.framework.NeverReconnectStrategy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
<module>features</module>
<module>karaf</module>
<module>netconf</module>
- <module>protocol-framework</module>
<module>restconf</module>
</modules>
+++ /dev/null
-target
-.classpath
-.settings
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- vi: set et smarttab sw=4 tabstop=4: -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.opendaylight.odlparent</groupId>
- <artifactId>bundle-parent</artifactId>
- <version>4.0.7</version>
- <relativePath/>
- </parent>
-
- <groupId>org.opendaylight.netconf</groupId>
- <artifactId>protocol-framework</artifactId>
- <version>1.3.0-SNAPSHOT</version>
- <packaging>bundle</packaging>
- <name>${project.artifactId}</name>
- <description>Common protocol framework</description>
-
- <dependencies>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-buffer</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-codec</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-common</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-transport</artifactId>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </dependency>
-
- <!-- Testing dependencies -->
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>mockito-configuration</artifactId>
- <version>2.1.6</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <executions>
- <execution>
- <goals>
- <goal>test-jar</goal>
- </goals>
- <phase>package</phase>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-
- <scm>
- <connection>scm:git:ssh://git.opendaylight.org:29418/netconf.git</connection>
- <developerConnection>scm:git:ssh://git.opendaylight.org:29418/netconf.git</developerConnection>
- <tag>HEAD</tag>
- <url>https://git.opendaylight.org/gerrit/gitweb?p=netconf.git;a=summary</url>
- </scm>
-</project>
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.protocol.framework;
-
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.SimpleChannelInboundHandler;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Deprecated
-public abstract class AbstractProtocolSession<M> extends SimpleChannelInboundHandler<Object> implements ProtocolSession<M> {
- private static final Logger LOG = LoggerFactory.getLogger(AbstractProtocolSession.class);
-
- /**
- * Handles incoming message (parsing, reacting if necessary).
- *
- * @param msg incoming message
- */
- protected abstract void handleMessage(final M msg);
-
- /**
- * Called when reached the end of input stream while reading.
- */
- protected abstract void endOfInput();
-
- /**
- * Called when the session is added to the pipeline.
- */
- protected abstract void sessionUp();
-
- @Override
- public final void channelInactive(final ChannelHandlerContext ctx) {
- LOG.debug("Channel {} inactive.", ctx.channel());
- endOfInput();
- try {
- // Forward channel inactive event, all handlers in pipeline might be interested in the event e.g. close channel handler of reconnect promise
- super.channelInactive(ctx);
- } catch (final Exception e) {
- throw new RuntimeException("Failed to delegate channel inactive event on channel " + ctx.channel(), e);
- }
- }
-
- @Override
- @SuppressWarnings("unchecked")
- protected final void channelRead0(final ChannelHandlerContext ctx, final Object msg) {
- LOG.debug("Message was received: {}", msg);
- handleMessage((M) msg);
- }
-
- @Override
- public final void handlerAdded(final ChannelHandlerContext ctx) {
- sessionUp();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.protocol.framework;
-
-import com.google.common.base.Preconditions;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInboundHandlerAdapter;
-import io.netty.util.concurrent.Promise;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Abstract base class for session negotiators. It implements the basic
- * substrate to implement SessionNegotiator API specification, with subclasses
- * needing to provide only
- *
- * @param <M> Protocol message type
- * @param <S> Protocol session type, has to extend {@code ProtocolSession<M>}
- */
-@Deprecated
-public abstract class AbstractSessionNegotiator<M, S extends AbstractProtocolSession<?>>
- extends ChannelInboundHandlerAdapter implements SessionNegotiator<S> {
- private final Logger LOG = LoggerFactory.getLogger(AbstractSessionNegotiator.class);
- private final Promise<S> promise;
- protected final Channel channel;
-
- public AbstractSessionNegotiator(final Promise<S> promise, final Channel channel) {
- this.promise = Preconditions.checkNotNull(promise);
- this.channel = Preconditions.checkNotNull(channel);
- }
-
- protected abstract void startNegotiation() throws Exception;
- protected abstract void handleMessage(M msg) throws Exception;
-
- protected final void negotiationSuccessful(final S session) {
- LOG.debug("Negotiation on channel {} successful with session {}", channel, session);
- channel.pipeline().replace(this, "session", session);
- promise.setSuccess(session);
- }
-
- protected void negotiationFailed(final Throwable cause) {
- LOG.debug("Negotiation on channel {} failed", channel, cause);
- channel.close();
- promise.setFailure(cause);
- }
-
- /**
- * Send a message to peer and fail negotiation if it does not reach
- * the peer.
- *
- * @param msg Message which should be sent.
- */
- protected final void sendMessage(final M msg) {
- this.channel.writeAndFlush(msg).addListener(f -> {
- if (!f.isSuccess()) {
- LOG.info("Failed to send message {}", msg, f.cause());
- negotiationFailed(f.cause());
- } else {
- LOG.trace("Message {} sent to socket", msg);
- }
- });
- }
-
- @Override
- public final void channelActive(final ChannelHandlerContext ctx) {
- LOG.debug("Starting session negotiation on channel {}", channel);
- try {
- startNegotiation();
- } catch (final Exception e) {
- LOG.warn("Unexpected negotiation failure", e);
- negotiationFailed(e);
- }
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public final void channelRead(final ChannelHandlerContext ctx, final Object msg) {
- LOG.debug("Negotiation read invoked on channel {}", channel);
- try {
- handleMessage((M)msg);
- } catch (final Exception e) {
- LOG.debug("Unexpected error while handling negotiation message {}", msg, e);
- negotiationFailed(e);
- }
- }
-
- @Override
- public void exceptionCaught(final ChannelHandlerContext ctx, final Throwable cause) {
- LOG.info("Unexpected error during negotiation", cause);
- negotiationFailed(cause);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.protocol.framework;
-
-import java.io.Closeable;
-
-/**
- * Protocol Session represents the finite state machine in underlying protocol, including timers and its purpose is to
- * create a connection between server and client. Session is automatically started, when TCP connection is created, but
- * can be stopped manually. If the session is up, it has to redirect messages to/from user. Handles also malformed
- * messages and unknown requests.
- *
- * This interface should be implemented by a final class representing a protocol specific session.
- */
-@Deprecated
-public interface ProtocolSession<T> extends Closeable {
- @Override
- void close();
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.protocol.framework;
-
-import java.util.EventListener;
-
-/**
- * Listener that receives session state information. This interface should be
- * implemented by a protocol specific abstract class, that is extended by
- * a final class that implements the methods.
- */
-@Deprecated
-public interface SessionListener<M, S extends ProtocolSession<?>, T extends TerminationReason> extends EventListener {
- /**
- * Fired when the session was established successfully.
- *
- * @param session New session
- */
- void onSessionUp(S session);
-
- /**
- * Fired when the session went down because of an IO error. Implementation should take care of closing underlying
- * session.
- *
- * @param session that went down
- * @param e Exception that was thrown as the cause of session being down
- */
- void onSessionDown(S session, Exception e);
-
- /**
- * Fired when the session is terminated locally. The session has already been closed and transitioned to IDLE state.
- * Any outstanding queued messages were not sent. The user should not attempt to make any use of the session.
- *
- * @param reason the cause why the session went down
- */
- void onSessionTerminated(S session, T reason);
-
- /**
- * Fired when a normal protocol message is received.
- *
- * @param message Protocol message
- */
- void onMessage(S session, M message);
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.protocol.framework;
-
-/**
- * Marker interface for grouping session termination cause.
- */
-@Deprecated
-public interface TerminationReason {
-
- /**
- * Get cause of session termination.
- * @return human-readable cause.
- */
- String getErrorMessage();
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.protocol.framework;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.util.concurrent.DefaultPromise;
-import io.netty.util.concurrent.Future;
-import io.netty.util.concurrent.GlobalEventExecutor;
-import io.netty.util.concurrent.Promise;
-import io.netty.util.concurrent.SucceededFuture;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-@Deprecated
-public class ServerTest {
- SimpleDispatcher clientDispatcher, dispatcher;
-
- SimpleSession session = null;
-
- ChannelFuture server = null;
-
- InetSocketAddress serverAddress;
- private NioEventLoopGroup eventLoopGroup;
- // Dedicated loop group for server, needed for testing reconnection client
- // With dedicated server group we can simulate session drop by shutting only the server group down
- private NioEventLoopGroup serverLoopGroup;
-
- @Before
- public void setUp() {
- final int port = 10000 + (int)(10000 * Math.random());
- serverAddress = new InetSocketAddress("127.0.0.1", port);
- eventLoopGroup = new NioEventLoopGroup();
- serverLoopGroup = new NioEventLoopGroup();
- }
-
- @After
- public void tearDown() throws IOException, InterruptedException, ExecutionException {
- if(server != null) {
- this.server.channel().close();
- }
- this.eventLoopGroup.shutdownGracefully().get();
- this.serverLoopGroup.shutdownGracefully().get();
- try {
- Thread.sleep(500);
- } catch (final InterruptedException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Test
- public void testConnectionRefused() throws Exception {
- this.clientDispatcher = getClientDispatcher();
-
- final ReconnectStrategy mockReconnectStrategy = getMockedReconnectStrategy();
-
- this.clientDispatcher.createClient(this.serverAddress, mockReconnectStrategy, SimpleSessionListener::new);
-
- Mockito.verify(mockReconnectStrategy, timeout(5000).atLeast(2)).scheduleReconnect(any(Throwable.class));
- }
-
- @Test
- public void testConnectionReestablishInitial() throws Exception {
- this.clientDispatcher = getClientDispatcher();
-
- final ReconnectStrategy mockReconnectStrategy = getMockedReconnectStrategy();
-
- this.clientDispatcher.createClient(this.serverAddress, mockReconnectStrategy, SimpleSessionListener::new);
-
- Mockito.verify(mockReconnectStrategy, timeout(5000).atLeast(2)).scheduleReconnect(any(Throwable.class));
-
- final Promise<Boolean> p = new DefaultPromise<>(GlobalEventExecutor.INSTANCE);
- this.dispatcher = getServerDispatcher(p);
-
- this.server = this.dispatcher.createServer(this.serverAddress, SimpleSessionListener::new);
-
- this.server.get();
-
- assertEquals(true, p.get(3, TimeUnit.SECONDS));
- }
-
- @Test
- public void testConnectionDrop() throws Exception {
- final Promise<Boolean> p = new DefaultPromise<>(GlobalEventExecutor.INSTANCE);
-
- this.dispatcher = getServerDispatcher(p);
-
- this.server = this.dispatcher.createServer(this.serverAddress, SimpleSessionListener::new);
-
- this.server.get();
-
- this.clientDispatcher = getClientDispatcher();
-
- final ReconnectStrategy reconnectStrategy = getMockedReconnectStrategy();
- this.session = this.clientDispatcher.createClient(this.serverAddress,
- reconnectStrategy, SimpleSessionListener::new).get(6, TimeUnit.SECONDS);
-
- assertEquals(true, p.get(3, TimeUnit.SECONDS));
-
- shutdownServer();
-
- // No reconnect should be scheduled after server drops connection with not-reconnecting client
- verify(reconnectStrategy, times(0)).scheduleReconnect(any(Throwable.class));
- }
-
- @Test
- public void testConnectionReestablishAfterDrop() throws Exception {
- final Promise<Boolean> p = new DefaultPromise<>(GlobalEventExecutor.INSTANCE);
-
- this.dispatcher = getServerDispatcher(p);
-
- this.server = this.dispatcher.createServer(this.serverAddress, SimpleSessionListener::new);
-
- this.server.get();
-
- this.clientDispatcher = getClientDispatcher();
-
- final ReconnectStrategyFactory reconnectStrategyFactory = mock(ReconnectStrategyFactory.class);
- final ReconnectStrategy reconnectStrategy = getMockedReconnectStrategy();
- doReturn(reconnectStrategy).when(reconnectStrategyFactory).createReconnectStrategy();
-
- this.clientDispatcher.createReconnectingClient(this.serverAddress,
- reconnectStrategyFactory, SimpleSessionListener::new);
-
- assertEquals(true, p.get(3, TimeUnit.SECONDS));
- shutdownServer();
-
- verify(reconnectStrategyFactory, timeout(20000).atLeast(2)).createReconnectStrategy();
- }
-
- @Test
- public void testConnectionEstablished() throws Exception {
- final Promise<Boolean> p = new DefaultPromise<>(GlobalEventExecutor.INSTANCE);
-
- this.dispatcher = getServerDispatcher(p);
-
- this.server = this.dispatcher.createServer(this.serverAddress, SimpleSessionListener::new);
-
- this.server.get();
-
- this.clientDispatcher = getClientDispatcher();
-
- this.session = this.clientDispatcher.createClient(this.serverAddress,
- new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, 5000), SimpleSessionListener::new).get(6,
- TimeUnit.SECONDS);
-
- assertEquals(true, p.get(3, TimeUnit.SECONDS));
- }
-
- @Test
- public void testConnectionFailed() throws IOException, InterruptedException, ExecutionException, TimeoutException {
- final Promise<Boolean> p = new DefaultPromise<>(GlobalEventExecutor.INSTANCE);
-
- this.dispatcher = getServerDispatcher(p);
-
- this.server = this.dispatcher.createServer(this.serverAddress, SimpleSessionListener::new);
-
- this.server.get();
-
- this.clientDispatcher = getClientDispatcher();
-
- this.session = this.clientDispatcher.createClient(this.serverAddress,
- new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, 5000), SimpleSessionListener::new).get(6,
- TimeUnit.SECONDS);
-
- final Future<?> session = this.clientDispatcher.createClient(this.serverAddress,
- new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, 5000), SimpleSessionListener::new);
- assertFalse(session.isSuccess());
- }
-
- @Test
- public void testNegotiationFailedReconnect() throws Exception {
- final Promise<Boolean> p = new DefaultPromise<>(GlobalEventExecutor.INSTANCE);
-
- this.dispatcher = getServerDispatcher(p);
-
- this.server = this.dispatcher.createServer(this.serverAddress, SimpleSessionListener::new);
-
- this.server.get();
-
- this.clientDispatcher = new SimpleDispatcher(
- (factory, channel, promise) -> new SimpleSessionNegotiator(promise, channel) {
- @Override
- protected void startNegotiation() throws Exception {
- negotiationFailed(new IllegalStateException("Negotiation failed"));
- }
- }, new DefaultPromise<>(GlobalEventExecutor.INSTANCE), eventLoopGroup);
-
- final ReconnectStrategyFactory reconnectStrategyFactory = mock(ReconnectStrategyFactory.class);
- final ReconnectStrategy reconnectStrategy = getMockedReconnectStrategy();
- doReturn(reconnectStrategy).when(reconnectStrategyFactory).createReconnectStrategy();
-
- this.clientDispatcher.createReconnectingClient(this.serverAddress,
- reconnectStrategyFactory, SimpleSessionListener::new);
-
-
- // Reconnect strategy should be consulted at least twice, for initial connect and reconnect attempts after drop
- verify(reconnectStrategyFactory, timeout((int) TimeUnit.MINUTES.toMillis(3)).atLeast(2)).createReconnectStrategy();
- }
-
- private SimpleDispatcher getClientDispatcher() {
- return new SimpleDispatcher((factory, channel, promise) -> new SimpleSessionNegotiator(promise, channel), new DefaultPromise<>(GlobalEventExecutor.INSTANCE), eventLoopGroup);
- }
-
- private ReconnectStrategy getMockedReconnectStrategy() throws Exception {
- final ReconnectStrategy mockReconnectStrategy = mock(ReconnectStrategy.class);
- final Future<Void> future = new SucceededFuture<>(GlobalEventExecutor.INSTANCE, null);
- doReturn(future).when(mockReconnectStrategy).scheduleReconnect(any(Throwable.class));
- doReturn(5000).when(mockReconnectStrategy).getConnectTimeout();
- doNothing().when(mockReconnectStrategy).reconnectSuccessful();
- return mockReconnectStrategy;
- }
-
-
- private void shutdownServer() throws InterruptedException, ExecutionException {
- // Shutdown server
- server.channel().close().get();
- // Closing server channel does not close established connections, eventLoop has to be closed as well to simulate dropped session
- serverLoopGroup.shutdownGracefully().get();
- }
-
- private SimpleDispatcher getServerDispatcher(final Promise<Boolean> p) {
- return new SimpleDispatcher((factory, channel, promise) -> {
- p.setSuccess(true);
- return new SimpleSessionNegotiator(promise, channel);
- }, null, serverLoopGroup);
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.protocol.framework;
-
-import com.google.common.collect.Lists;
-import java.util.List;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Deprecated
-public class Session extends AbstractProtocolSession<SimpleMessage> {
-
- private static final Logger LOG = LoggerFactory.getLogger(Session.class);
-
- public final List<SimpleMessage> msgs = Lists.newArrayList();
-
- public boolean up = false;
-
- @Override
- public void close() {
-
- }
-
- @Override
- public void handleMessage(final SimpleMessage msg) {
- LOG.debug("Message received: {}", msg.getMessage());
- this.up = true;
- this.msgs.add(msg);
- LOG.debug(this.msgs.size() + "");
- }
-
- @Override
- public void endOfInput() {
- LOG.debug("End of input reported.");
- }
-
- @Override
- protected void sessionUp() {
- LOG.debug("Session up reported.");
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.protocol.framework;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.codec.ByteToMessageDecoder;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-
-@Deprecated
-public class SimpleByteToMessageDecoder extends ByteToMessageDecoder {
- @Override
- protected void decode(final ChannelHandlerContext ctx, final ByteBuf in, final List<Object> out) {
- out.add(new SimpleMessage(StandardCharsets.UTF_8.decode(in.nioBuffer()).toString()));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.protocol.framework;
-
-import com.google.common.base.Preconditions;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelOutboundHandler;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.socket.SocketChannel;
-import io.netty.util.concurrent.Future;
-import io.netty.util.concurrent.Promise;
-import java.net.InetSocketAddress;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Deprecated
-public class SimpleDispatcher extends AbstractDispatcher<SimpleSession, SimpleSessionListener> {
- private static final Logger LOG = LoggerFactory.getLogger(SimpleDispatcher.class);
-
- private final SessionNegotiatorFactory<SimpleMessage, SimpleSession, SimpleSessionListener> negotiatorFactory;
- private final ChannelOutboundHandler encoder = new SimpleMessageToByteEncoder();
-
- private final class SimplePipelineInitializer implements PipelineInitializer<SimpleSession> {
- final SessionListenerFactory<SimpleSessionListener> listenerFactory;
-
- SimplePipelineInitializer(final SessionListenerFactory<SimpleSessionListener> listenerFactory) {
- this.listenerFactory = Preconditions.checkNotNull(listenerFactory);
- }
-
- @Override
- public void initializeChannel(final SocketChannel channel, final Promise<SimpleSession> promise) {
- channel.pipeline().addLast(new SimpleByteToMessageDecoder());
- channel.pipeline().addLast("negotiator", negotiatorFactory.getSessionNegotiator(listenerFactory, channel, promise));
- channel.pipeline().addLast(encoder);
- LOG.debug("initialization completed for channel {}", channel);
- }
-
- }
-
- public SimpleDispatcher(final SessionNegotiatorFactory<SimpleMessage, SimpleSession, SimpleSessionListener> negotiatorFactory,
- final Promise<SimpleSession> promise, final EventLoopGroup eventLoopGroup) {
- super(eventLoopGroup, eventLoopGroup);
- this.negotiatorFactory = Preconditions.checkNotNull(negotiatorFactory);
- }
-
- public Future<SimpleSession> createClient(final InetSocketAddress address, final ReconnectStrategy strategy, final SessionListenerFactory<SimpleSessionListener> listenerFactory) {
- return super.createClient(address, strategy, new SimplePipelineInitializer(listenerFactory));
- }
-
- public Future<Void> createReconnectingClient(final InetSocketAddress address, final ReconnectStrategyFactory strategy, final SessionListenerFactory<SimpleSessionListener> listenerFactory) {
- return super.createReconnectingClient(address, strategy, new SimplePipelineInitializer(listenerFactory));
- }
-
- public ChannelFuture createServer(final InetSocketAddress address, final SessionListenerFactory<SimpleSessionListener> listenerFactory) {
- return super.createServer(address, new SimplePipelineInitializer(listenerFactory));
- }
-
- @Override
- public void close() {
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.protocol.framework;
-
-@Deprecated
-public class SimpleMessage {
-
- private final String s;
-
- public SimpleMessage(final String s) {
- this.s = s;
- }
-
- public String getMessage() {
- return this.s;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.protocol.framework;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.channel.ChannelHandler.Sharable;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.codec.MessageToByteEncoder;
-
-@Deprecated
-@Sharable
-public class SimpleMessageToByteEncoder extends MessageToByteEncoder<SimpleMessage> {
- @Override
- protected void encode(final ChannelHandlerContext ctx, final SimpleMessage msg, final ByteBuf out) {
- out.writeBytes(msg.getMessage().getBytes());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.protocol.framework;
-
-@Deprecated
-public final class SimpleSession extends AbstractProtocolSession<SimpleMessage> {
-
- public SimpleSession() {
- }
-
- @Override
- public void close() {
- }
-
- @Override
- public void handleMessage(final SimpleMessage msg) {
- }
-
- @Override
- public void endOfInput() {
- }
-
- @Override
- protected void sessionUp() {
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.protocol.framework;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Simple Session Listener that is notified about messages and changes in the session.
- */
-@Deprecated
-public class SimpleSessionListener implements SessionListener<SimpleMessage, SimpleSession, TerminationReason> {
- private static final Logger LOG = LoggerFactory.getLogger(SimpleSessionListener.class);
-
- public List<SimpleMessage> messages = new ArrayList<>();
-
- public boolean up = false;
-
- public boolean failed = false;
-
- @Override
- public void onMessage(final SimpleSession session, final SimpleMessage message) {
- LOG.debug("Received message: " + message.getClass() + " " + message);
- this.messages.add(message);
- }
-
- @Override
- public void onSessionUp(final SimpleSession session) {
- this.up = true;
- }
-
- @Override
- public void onSessionDown(final SimpleSession session, final Exception e) {
- this.failed = true;
- this.notifyAll();
- }
-
- @Override
- public void onSessionTerminated(final SimpleSession session, final TerminationReason reason) {
- this.failed = true;
- this.notifyAll();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.protocol.framework;
-
-@Deprecated
-public class SimpleSessionListenerFactory implements SessionListenerFactory<SimpleSessionListener> {
-
- @Override
- public SimpleSessionListener getSessionListener() {
- return new SimpleSessionListener();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * 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.protocol.framework;
-
-import io.netty.channel.Channel;
-import io.netty.util.concurrent.Promise;
-
-@Deprecated
-public class SimpleSessionNegotiator extends AbstractSessionNegotiator<SimpleMessage, SimpleSession> {
-
- public SimpleSessionNegotiator(final Promise<SimpleSession> promise, final Channel channel) {
- super(promise, channel);
- }
-
- @Override
- protected void startNegotiation() throws Exception {
- negotiationSuccessful(new SimpleSession());
- }
-
- @Override
- protected void handleMessage(final SimpleMessage msg) throws Exception {
- throw new IllegalStateException("This method should never be invoked");
- }
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<configuration>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern>
- </encoder>
- </appender>
-
- <root level="TRACE">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration>