<version>${project.version}</version>
<classifier>features</classifier>
<type>xml</type>
- <scope>runtime</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>features-netconf</artifactId>
<version>${project.version}</version>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+
+ <!-- netconf features -->
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>features4-netconf</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-aaa-netconf-plugin</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-aaa-netconf-plugin-no-cluster</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-config-netconf-connector</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-all</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-api</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-client</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-impl</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-mapping-api</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-mdsal</artifactId>
+ <version>1.6.0-SNAPSHOT</version>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-monitoring</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-netty-util</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-notifications-api</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-notifications-impl</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
<classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-ssh</artifactId>
+ <version>${project.version}</version>
<type>xml</type>
- <scope>runtime</scope>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-tcp</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-util</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+
+ <!-- netconf-connector features -->
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>features4-netconf-connector</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-message-bus</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>features</classifier>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>odl-netconf-clustered-topology</artifactId>
<version>${project.version}</version>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-connector</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-connector-all</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-connector-ssh</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
<classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-callhome-ssh</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-console</artifactId>
+ <version>${project.version}</version>
<type>xml</type>
- <scope>runtime</scope>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-netconf-topology</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+
+ <!-- yanglib features -->
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>features4-yanglib</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-yanglib</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>features</classifier>
</dependency>
</dependencies>
</dependencyManagement>
</execution>
</executions>
</plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <configuration>
+ <propertyExpansion>checkstyle.violationSeverity=error</propertyExpansion>
+ </configuration>
+ </plugin>
</plugins>
</build>
public interface NetconfClientDispatcher {
/**
+ * Create netconf client. Network communication has to be set up based on network protocol specified in
+ * clientConfiguration
*
- * Create netconf client. Network communication has to be set up based on network protocol specified in clientConfiguration
- *
- * @param clientConfiguration
+ * @param clientConfiguration Configuration of client
* @return netconf client based on provided configuration
*/
Future<NetconfClientSession> createClient(NetconfClientConfiguration clientConfiguration);
private final Timer timer;
- public NetconfClientDispatcherImpl(final EventLoopGroup bossGroup, final EventLoopGroup workerGroup, final Timer timer) {
+ public NetconfClientDispatcherImpl(final EventLoopGroup bossGroup, final EventLoopGroup workerGroup,
+ final Timer timer) {
super(bossGroup, workerGroup);
this.timer = timer;
}
@Override
public Future<NetconfClientSession> createClient(final NetconfClientConfiguration clientConfiguration) {
switch (clientConfiguration.getProtocol()) {
- case TCP:
- return createTcpClient(clientConfiguration);
- case SSH:
- return createSshClient(clientConfiguration);
+ case TCP:
+ return createTcpClient(clientConfiguration);
+ case SSH:
+ return createSshClient(clientConfiguration);
+ default:
+ throw new IllegalArgumentException("Unknown client protocol " + clientConfiguration.getProtocol());
}
- throw new IllegalArgumentException("Unknown client protocol " + clientConfiguration.getProtocol());
}
@Override
public Future<Void> createReconnectingClient(final NetconfReconnectingClientConfiguration clientConfiguration) {
switch (clientConfiguration.getProtocol()) {
- case TCP:
- return createReconnectingTcpClient(clientConfiguration);
- case SSH:
- return createReconnectingSshClient(clientConfiguration);
+ case TCP:
+ return createReconnectingTcpClient(clientConfiguration);
+ case SSH:
+ return createReconnectingSshClient(clientConfiguration);
+ default:
+ throw new IllegalArgumentException("Unknown client protocol " + clientConfiguration.getProtocol());
}
- throw new IllegalArgumentException("Unknown client protocol " + clientConfiguration.getProtocol());
}
private Future<NetconfClientSession> createTcpClient(final NetconfClientConfiguration currentConfiguration) {
LOG.debug("Creating TCP client with configuration: {}", currentConfiguration);
return super.createClient(currentConfiguration.getAddress(), currentConfiguration.getReconnectStrategy(),
- (ch, promise) -> new TcpClientChannelInitializer(getNegotiatorFactory(currentConfiguration), currentConfiguration
- .getSessionListener()).initialize(ch, promise));
+ (ch, promise) -> new TcpClientChannelInitializer(getNegotiatorFactory(currentConfiguration),
+ currentConfiguration
+ .getSessionListener()).initialize(ch, promise));
}
- private Future<Void> createReconnectingTcpClient(final NetconfReconnectingClientConfiguration currentConfiguration) {
+ private Future<Void> createReconnectingTcpClient(
+ final NetconfReconnectingClientConfiguration currentConfiguration) {
LOG.debug("Creating reconnecting TCP client with configuration: {}", currentConfiguration);
- final TcpClientChannelInitializer init = new TcpClientChannelInitializer(getNegotiatorFactory(currentConfiguration),
+ final TcpClientChannelInitializer init =
+ new TcpClientChannelInitializer(getNegotiatorFactory(currentConfiguration),
currentConfiguration.getSessionListener());
- return super.createReconnectingClient(currentConfiguration.getAddress(), currentConfiguration.getConnectStrategyFactory(),
+ return super.createReconnectingClient(currentConfiguration.getAddress(), currentConfiguration
+ .getConnectStrategyFactory(),
currentConfiguration.getReconnectStrategy(), init::initialize);
}
private Future<NetconfClientSession> createSshClient(final NetconfClientConfiguration currentConfiguration) {
LOG.debug("Creating SSH client with configuration: {}", currentConfiguration);
return super.createClient(currentConfiguration.getAddress(), currentConfiguration.getReconnectStrategy(),
- (ch, sessionPromise) -> new SshClientChannelInitializer(currentConfiguration.getAuthHandler(),
+ (ch, sessionPromise) -> new SshClientChannelInitializer(currentConfiguration.getAuthHandler(),
getNegotiatorFactory(currentConfiguration), currentConfiguration.getSessionListener())
.initialize(ch, sessionPromise));
}
- private Future<Void> createReconnectingSshClient(final NetconfReconnectingClientConfiguration currentConfiguration) {
+ private Future<Void> createReconnectingSshClient(
+ final NetconfReconnectingClientConfiguration currentConfiguration) {
LOG.debug("Creating reconnecting SSH client with configuration: {}", currentConfiguration);
final SshClientChannelInitializer init = new SshClientChannelInitializer(currentConfiguration.getAuthHandler(),
getNegotiatorFactory(currentConfiguration), currentConfiguration.getSessionListener());
- return super.createReconnectingClient(currentConfiguration.getAddress(), currentConfiguration.getConnectStrategyFactory(), currentConfiguration.getReconnectStrategy(),
+ return super.createReconnectingClient(currentConfiguration.getAddress(), currentConfiguration
+ .getConnectStrategyFactory(), currentConfiguration.getReconnectStrategy(),
init::initialize);
}
/**
* Construct a new session.
*
- * @param sessionListener
- * @param channel
- * @param sessionId
- * @param capabilities set of advertised capabilities. Expected to be immutable.
+ * @param sessionListener Netconf client session listener.
+ * @param channel Channel.
+ * @param sessionId Session Id.
+ * @param capabilities Set of advertised capabilities. Expected to be immutable.
*/
- public NetconfClientSession(final NetconfClientSessionListener sessionListener, final Channel channel, final long sessionId,
- final Collection<String> capabilities) {
+ public NetconfClientSession(final NetconfClientSessionListener sessionListener, final Channel channel,
+ final long sessionId, final Collection<String> capabilities) {
super(sessionListener, channel, sessionId);
this.capabilities = capabilities;
LOG.debug("Client Session {} created", this);
}
@Override
- protected void addExiHandlers(final ByteToMessageDecoder decoder, final MessageToByteEncoder<NetconfMessage> encoder) {
+ protected void addExiHandlers(final ByteToMessageDecoder decoder,
+ final MessageToByteEncoder<NetconfMessage> encoder) {
// TODO used only in negotiator, client supports only auto start-exi
replaceMessageDecoder(decoder);
replaceMessageEncoder(encoder);
import org.w3c.dom.NodeList;
public class NetconfClientSessionNegotiator extends
- AbstractNetconfSessionNegotiator<NetconfClientSessionPreferences, NetconfClientSession, NetconfClientSessionListener>
-{
+ AbstractNetconfSessionNegotiator<NetconfClientSessionPreferences, NetconfClientSession,
+ NetconfClientSessionListener> {
private static final Logger LOG = LoggerFactory.getLogger(NetconfClientSessionNegotiator.class);
- private static final XPathExpression sessionIdXPath = XMLNetconfUtil
+ private static final XPathExpression SESSION_ID_X_PATH = XMLNetconfUtil
.compileXPath("/netconf:hello/netconf:session-id");
- private static final XPathExpression sessionIdXPathNoNamespace = XMLNetconfUtil
+ private static final XPathExpression SESSION_ID_X_PATH_NO_NAMESPACE = XMLNetconfUtil
.compileXPath("/hello/session-id");
private static final String EXI_1_0_CAPABILITY_MARKER = "exi:1.0";
/**
* Initiates exi communication by sending start-exi message and waiting for positive/negative response.
*
- * @param startExiMessage
+ * @param startExiMessage Exi message for initilization of exi communication.
*/
void tryToInitiateExi(final NetconfClientSession session, final NetconfStartExiMessage startExiMessage) {
channel.pipeline().addAfter(AbstractChannelInitializer.NETCONF_MESSAGE_DECODER,
session.sendMessage(startExiMessage).addListener(new ChannelFutureListener() {
@Override
- public void operationComplete(final ChannelFuture f) {
- if (!f.isSuccess()) {
- LOG.warn("Failed to send start-exi message {} on session {}", startExiMessage, this, f.cause());
+ public void operationComplete(final ChannelFuture channelFuture) {
+ if (!channelFuture.isSuccess()) {
+ LOG.warn("Failed to send start-exi message {} on session {}", startExiMessage, this,
+ channelFuture.cause());
channel.pipeline().remove(ExiConfirmationInboundHandler.EXI_CONFIRMED_HANDLER);
} else {
LOG.trace("Start-exi message {} sent to socket on session {}", startExiMessage, this);
}
private static long extractSessionId(final Document doc) {
- String textContent = getSessionIdWithXPath(doc, sessionIdXPath);
+ String textContent = getSessionIdWithXPath(doc, SESSION_ID_X_PATH);
if (Strings.isNullOrEmpty(textContent)) {
- textContent = getSessionIdWithXPath(doc, sessionIdXPathNoNamespace);
+ textContent = getSessionIdWithXPath(doc, SESSION_ID_X_PATH_NO_NAMESPACE);
if (Strings.isNullOrEmpty(textContent)) {
- throw new IllegalStateException("Session id not received from server, hello message: " + XmlUtil.toString(doc));
+ throw new IllegalStateException("Session id not received from server, hello message: " + XmlUtil
+ .toString(doc));
}
}
final long sessionId = extractSessionId(message.getDocument());
// Copy here is important: it disconnects the strings from the document
- Set<String> capabilities = ImmutableSet.copyOf(NetconfMessageUtil.extractCapabilitiesFromHello(message.getDocument()));
+ Set<String> capabilities = ImmutableSet.copyOf(NetconfMessageUtil.extractCapabilitiesFromHello(message
+ .getDocument()));
capabilities = INTERNER.intern(capabilities);
}
/**
- * Handler to process response for start-exi message
+ * Handler to process response for start-exi message.
*/
private final class ExiConfirmationInboundHandler extends ChannelInboundHandlerAdapter {
private static final String EXI_CONFIRMED_HANDLER = "exiConfirmedHandler";
private final NetconfClientSession session;
private final NetconfStartExiMessage startExiMessage;
- ExiConfirmationInboundHandler(final NetconfClientSession session, final NetconfStartExiMessage startExiMessage) {
+ ExiConfirmationInboundHandler(final NetconfClientSession session,
+ final NetconfStartExiMessage startExiMessage) {
this.session = session;
this.startExiMessage = startExiMessage;
}
+ @SuppressWarnings("checkstyle:IllegalCatch")
@Override
public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {
ctx.pipeline().remove(ExiConfirmationInboundHandler.EXI_CONFIRMED_HANDLER);
session.startExiCommunication(startExiMessage);
} catch (RuntimeException e) {
// Unable to add exi, continue without exi
- LOG.warn("Unable to start exi communication, Communication will continue without exi on session {}", session, e);
+ LOG.warn("Unable to start exi communication, Communication will continue without exi on session "
+ + "{}", session, e);
}
// Error response
- } else if(NetconfMessageUtil.isErrorMessage(netconfMessage)) {
+ } else if (NetconfMessageUtil.isErrorMessage(netconfMessage)) {
LOG.warn(
"Error response to start-exi message {}, Communication will continue without exi on session {}",
netconfMessage, session);
// Unexpected response to start-exi, throwing message away, continue without exi
} else {
- LOG.warn("Unexpected response to start-exi message, should be ok, was {}, " +
- "Communication will continue without exi and response message will be thrown away on session {}",
- netconfMessage, session);
+ LOG.warn("Unexpected response to start-exi message, should be ok, was {}, "
+ + "Communication will continue without exi "
+ + "and response message will be thrown away on session {}",
+ netconfMessage, session);
}
negotiationSuccessful(session);
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class NetconfClientSessionNegotiatorFactory implements SessionNegotiatorFactory<NetconfMessage, NetconfClientSession, NetconfClientSessionListener> {
+public class NetconfClientSessionNegotiatorFactory implements SessionNegotiatorFactory<NetconfMessage,
+ NetconfClientSession, NetconfClientSessionListener> {
public static final Set<String> EXI_CLIENT_CAPABILITIES = ImmutableSet.of(
XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0,
public NetconfClientSessionNegotiatorFactory(final Timer timer,
final Optional<NetconfHelloMessageAdditionalHeader> additionalHeader,
- final long connectionTimeoutMillis, final EXIOptions exiOptions, final Set<String> capabilities) {
+ final long connectionTimeoutMillis, final EXIOptions exiOptions,
+ final Set<String> capabilities) {
this.timer = Preconditions.checkNotNull(timer);
this.additionalHeader = additionalHeader;
this.connectionTimeoutMillis = connectionTimeoutMillis;
}
@Override
- public SessionNegotiator<NetconfClientSession> getSessionNegotiator(final SessionListenerFactory<NetconfClientSessionListener> sessionListenerFactory,
- final Channel channel,
- final Promise<NetconfClientSession> promise) {
+ public SessionNegotiator<NetconfClientSession> getSessionNegotiator(
+ final SessionListenerFactory<NetconfClientSessionListener> sessionListenerFactory,
+ final Channel channel, final Promise<NetconfClientSession> promise) {
NetconfMessage startExiMessage = NetconfStartExiMessage.create(options, START_EXI_MESSAGE_ID);
NetconfHelloMessage helloMessage = null;
try {
helloMessage = NetconfHelloMessage.createClientHello(clientCapabilities, additionalHeader);
} catch (NetconfDocumentedException e) {
- LOG.error("Unable to create client hello message with capabilities {} and additional handler {}", clientCapabilities,additionalHeader);
+ LOG.error("Unable to create client hello message with capabilities {} and additional handler {}",
+ clientCapabilities, additionalHeader);
throw new IllegalStateException(e);
}
NetconfClientSessionPreferences proposal = new NetconfClientSessionPreferences(helloMessage, startExiMessage);
return new NetconfClientSessionNegotiator(proposal, promise, channel, timer,
- sessionListenerFactory.getSessionListener(),connectionTimeoutMillis);
+ sessionListenerFactory.getSessionListener(), connectionTimeoutMillis);
}
}
private final Promise<NetconfMessage> promise;
private final NetconfMessage request;
- public RequestEntry(Promise<NetconfMessage> future, NetconfMessage request) {
+ RequestEntry(Promise<NetconfMessage> future, NetconfMessage request) {
this.promise = Preconditions.checkNotNull(future);
this.request = Preconditions.checkNotNull(request);
}
}
@Override
- public final void onSessionDown(NetconfClientSession clientSession, Exception e) {
- LOG.debug("Client Session {} went down unexpectedly", clientSession, e);
- tearDown(e);
+ public final void onSessionDown(NetconfClientSession clientSession, Exception exception) {
+ LOG.debug("Client Session {} went down unexpectedly", clientSession, exception);
+ tearDown(exception);
}
@Override
public final void onSessionTerminated(NetconfClientSession clientSession,
- NetconfTerminationReason netconfTerminationReason) {
+ NetconfTerminationReason netconfTerminationReason) {
LOG.debug("Client Session {} terminated, reason: {}", clientSession,
netconfTerminationReason.getErrorMessage());
tearDown(new RuntimeException(netconfTerminationReason.getErrorMessage()));
private final NetconfClientSessionNegotiatorFactory negotiatorFactory;
private final NetconfClientSessionListener sessionListener;
- public SshClientChannelInitializer(final AuthenticationHandler authHandler,
- final NetconfClientSessionNegotiatorFactory negotiatorFactory,
- final NetconfClientSessionListener sessionListener) {
+ SshClientChannelInitializer(final AuthenticationHandler authHandler,
+ final NetconfClientSessionNegotiatorFactory negotiatorFactory,
+ final NetconfClientSessionListener sessionListener) {
this.authenticationHandler = authHandler;
this.negotiatorFactory = negotiatorFactory;
this.sessionListener = sessionListener;
try {
// ssh handler has to be the first handler in pipeline
ch.pipeline().addFirst(AsyncSshHandler.createForNetconfSubsystem(authenticationHandler, promise));
- super.initialize(ch,promise);
+ super.initialize(ch, promise);
} catch (final IOException e) {
throw new RuntimeException(e);
}
@Override
protected void initializeSessionNegotiator(final Channel ch,
final Promise<NetconfClientSession> promise) {
- ch.pipeline().addAfter(NETCONF_MESSAGE_DECODER, AbstractChannelInitializer.NETCONF_SESSION_NEGOTIATOR,
+ ch.pipeline().addAfter(NETCONF_MESSAGE_DECODER, AbstractChannelInitializer.NETCONF_SESSION_NEGOTIATOR,
negotiatorFactory.getSessionNegotiator(() -> sessionListener, ch, promise));
}
}
GenericFutureListener<Future<NetconfClientSession>> negotiationFutureListener;
@Override
- public void connect(final ChannelHandlerContext ctx, final SocketAddress remoteAddress, final SocketAddress localAddress,
+ public void connect(final ChannelHandlerContext ctx, final SocketAddress remoteAddress,
+ final SocketAddress localAddress,
final ChannelPromise channelPromise) throws Exception {
connectPromise = channelPromise;
ChannelPromise tcpConnectFuture = new DefaultChannelPromise(ch);
};
tcpConnectFuture.addListener(future -> {
- if(future.isSuccess()) {
+ if (future.isSuccess()) {
//complete connection promise with netconf negotiation future
negotiationFuture.addListener(negotiationFutureListener);
} else {
@Override
public void disconnect(final ChannelHandlerContext ctx, final ChannelPromise promise) throws Exception {
- // If we have already succeeded and the session was dropped after, we need to fire inactive to notify reconnect logic
- if(connectPromise.isSuccess()) {
+ // If we have already succeeded and the session was dropped after, we need to fire inactive to notify
+ // reconnect logic
+ if (connectPromise.isSuccess()) {
ctx.fireChannelInactive();
}
//If connection promise is not already set, it means negotiation failed
//we must set connection promise to failure
- if(!connectPromise.isDone()) {
+ if (!connectPromise.isDone()) {
connectPromise.setFailure(new IllegalStateException("Negotiation failed"));
}
import org.opendaylight.netconf.client.NetconfClientSessionListener;
import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
import org.opendaylight.protocol.framework.ReconnectStrategy;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class NetconfClientConfiguration {
+ private static final Logger LOG = LoggerFactory.getLogger(NetconfClientConfiguration.class);
+
private final NetconfClientProtocol clientProtocol;
private final InetSocketAddress address;
private final Long connectionTimeoutMillis;
private final AuthenticationHandler authHandler;
- NetconfClientConfiguration(final NetconfClientProtocol protocol, final InetSocketAddress address, final Long connectionTimeoutMillis, final NetconfHelloMessageAdditionalHeader additionalHeader, final NetconfClientSessionListener sessionListener, final ReconnectStrategy reconnectStrategy, final AuthenticationHandler authHandler) {
+ NetconfClientConfiguration(final NetconfClientProtocol protocol, final InetSocketAddress address,
+ final Long connectionTimeoutMillis,
+ final NetconfHelloMessageAdditionalHeader additionalHeader,
+ final NetconfClientSessionListener sessionListener,
+ final ReconnectStrategy reconnectStrategy, final AuthenticationHandler authHandler) {
this.address = address;
this.connectionTimeoutMillis = connectionTimeoutMillis;
this.additionalHeader = additionalHeader;
return clientProtocol;
}
+ @SuppressWarnings("checkstyle:FallThrough")
private void validateConfiguration() {
Preconditions.checkNotNull(clientProtocol, " ");
switch (clientProtocol) {
- case SSH:
- validateSshConfiguration();
- // Fall through intentional (ssh validation is a superset of tcp validation)
- case TCP:
- validateTcpConfiguration();
+ case SSH:
+ validateSshConfiguration();
+ // Fall through intentional (ssh validation is a superset of tcp validation)
+ case TCP:
+ validateTcpConfiguration();
+ default:
+ LOG.warn("Unexpected protocol: {} in netconf client configuration.", clientProtocol);
}
}
.add("authHandler", authHandler);
}
- public static enum NetconfClientProtocol {
+ public enum NetconfClientProtocol {
TCP, SSH
}
}
\ No newline at end of file
public class NetconfClientConfigurationBuilder {
public static final int DEFAULT_CONNECTION_TIMEOUT_MILLIS = 5000;
- public static final NetconfClientConfiguration.NetconfClientProtocol DEFAULT_CLIENT_PROTOCOL = NetconfClientConfiguration.NetconfClientProtocol.TCP;
+ public static final NetconfClientConfiguration.NetconfClientProtocol DEFAULT_CLIENT_PROTOCOL =
+ NetconfClientConfiguration.NetconfClientProtocol.TCP;
private InetSocketAddress address;
private long connectionTimeoutMillis = DEFAULT_CONNECTION_TIMEOUT_MILLIS;
return this;
}
- public NetconfClientConfigurationBuilder withProtocol(final NetconfClientConfiguration.NetconfClientProtocol clientProtocol) {
+ public NetconfClientConfigurationBuilder withProtocol(
+ final NetconfClientConfiguration.NetconfClientProtocol clientProtocol) {
this.clientProtocol = clientProtocol;
return this;
}
- public NetconfClientConfigurationBuilder withAdditionalHeader(final NetconfHelloMessageAdditionalHeader additionalHeader) {
+ public NetconfClientConfigurationBuilder withAdditionalHeader(
+ final NetconfHelloMessageAdditionalHeader additionalHeader) {
this.additionalHeader = additionalHeader;
return this;
}
}
public NetconfClientConfiguration build() {
- return new NetconfClientConfiguration(clientProtocol, address, connectionTimeoutMillis, additionalHeader, sessionListener, reconnectStrategy, authHandler);
+ return new NetconfClientConfiguration(clientProtocol, address, connectionTimeoutMillis, additionalHeader,
+ sessionListener, reconnectStrategy, authHandler);
}
}
private final ReconnectStrategyFactory connectStrategyFactory;
NetconfReconnectingClientConfiguration(final NetconfClientProtocol clientProtocol, final InetSocketAddress address,
- final Long connectionTimeoutMillis, final NetconfHelloMessageAdditionalHeader additionalHeader,
- final NetconfClientSessionListener sessionListener, final ReconnectStrategy reconnectStrategy,
- final ReconnectStrategyFactory connectStrategyFactory, final AuthenticationHandler authHandler) {
+ final Long connectionTimeoutMillis,
+ final NetconfHelloMessageAdditionalHeader additionalHeader,
+ final NetconfClientSessionListener sessionListener,
+ final ReconnectStrategy reconnectStrategy,
+ final ReconnectStrategyFactory connectStrategyFactory,
+ final AuthenticationHandler authHandler) {
super(clientProtocol, address, connectionTimeoutMillis, additionalHeader, sessionListener, reconnectStrategy,
authHandler);
this.connectStrategyFactory = connectStrategyFactory;
}
- public NetconfReconnectingClientConfigurationBuilder withConnectStrategyFactory(final ReconnectStrategyFactory connectStrategyFactory) {
+ public NetconfReconnectingClientConfigurationBuilder withConnectStrategyFactory(
+ final ReconnectStrategyFactory connectStrategyFactory) {
this.connectStrategyFactory = connectStrategyFactory;
return this;
}
@Override
public NetconfReconnectingClientConfiguration build() {
- return new NetconfReconnectingClientConfiguration(getProtocol(), getAddress(), getConnectionTimeoutMillis(), getAdditionalHeader(), getSessionListener(), getReconnectStrategy(), connectStrategyFactory, getAuthHandler());
+ return new NetconfReconnectingClientConfiguration(getProtocol(), getAddress(), getConnectionTimeoutMillis(),
+ getAdditionalHeader(), getSessionListener(), getReconnectStrategy(), connectStrategyFactory,
+ getAuthHandler());
}
// Override setter methods to return subtype
}
@Override
- public NetconfReconnectingClientConfigurationBuilder withConnectionTimeoutMillis(final long connectionTimeoutMillis) {
- return (NetconfReconnectingClientConfigurationBuilder) super.withConnectionTimeoutMillis(connectionTimeoutMillis);
+ public NetconfReconnectingClientConfigurationBuilder withConnectionTimeoutMillis(
+ final long connectionTimeoutMillis) {
+ return (NetconfReconnectingClientConfigurationBuilder)
+ super.withConnectionTimeoutMillis(connectionTimeoutMillis);
}
@Override
- public NetconfReconnectingClientConfigurationBuilder withAdditionalHeader(final NetconfHelloMessageAdditionalHeader additionalHeader) {
+ public NetconfReconnectingClientConfigurationBuilder withAdditionalHeader(
+ final NetconfHelloMessageAdditionalHeader additionalHeader) {
return (NetconfReconnectingClientConfigurationBuilder) super.withAdditionalHeader(additionalHeader);
}
@Override
- public NetconfReconnectingClientConfigurationBuilder withSessionListener(final NetconfClientSessionListener sessionListener) {
+ public NetconfReconnectingClientConfigurationBuilder withSessionListener(
+ final NetconfClientSessionListener sessionListener) {
return (NetconfReconnectingClientConfigurationBuilder) super.withSessionListener(sessionListener);
}
@Override
- public NetconfReconnectingClientConfigurationBuilder withReconnectStrategy(final ReconnectStrategy reconnectStrategy) {
+ public NetconfReconnectingClientConfigurationBuilder withReconnectStrategy(
+ final ReconnectStrategy reconnectStrategy) {
return (NetconfReconnectingClientConfigurationBuilder) super.withReconnectStrategy(reconnectStrategy);
}
}
@Override
- public NetconfReconnectingClientConfigurationBuilder withProtocol(NetconfClientConfiguration.NetconfClientProtocol clientProtocol) {
+ public NetconfReconnectingClientConfigurationBuilder withProtocol(
+ NetconfClientConfiguration.NetconfClientProtocol clientProtocol) {
return (NetconfReconnectingClientConfigurationBuilder) super.withProtocol(clientProtocol);
}
}
@Test
public void testNetconfClientConfiguration() throws Exception {
Long timeout = 200L;
- NetconfHelloMessageAdditionalHeader header = new NetconfHelloMessageAdditionalHeader("a", "host", "port", "trans", "id");
+ NetconfHelloMessageAdditionalHeader header =
+ new NetconfHelloMessageAdditionalHeader("a", "host", "port", "trans", "id");
NetconfClientSessionListener listener = new SimpleNetconfClientSessionListener();
InetSocketAddress address = InetSocketAddress.createUnresolved("host", 830);
ReconnectStrategy strategy = Mockito.mock(ReconnectStrategy.class);
AuthenticationHandler handler = Mockito.mock(AuthenticationHandler.class);
- NetconfClientConfiguration cfg = NetconfClientConfigurationBuilder.create().
- withProtocol(NetconfClientConfiguration.NetconfClientProtocol.SSH).
- withAddress(address).
- withConnectionTimeoutMillis(timeout).
- withReconnectStrategy(strategy).
- withAdditionalHeader(header).
- withSessionListener(listener).
- withAuthHandler(handler).build();
+ NetconfClientConfiguration cfg = NetconfClientConfigurationBuilder.create()
+ .withProtocol(NetconfClientConfiguration.NetconfClientProtocol.SSH)
+ .withAddress(address)
+ .withConnectionTimeoutMillis(timeout)
+ .withReconnectStrategy(strategy)
+ .withAdditionalHeader(header)
+ .withSessionListener(listener)
+ .withAuthHandler(handler).build();
Assert.assertEquals(timeout, cfg.getConnectionTimeoutMillis());
Assert.assertEquals(Optional.fromNullable(header), cfg.getAdditionalHeader());
doReturn(thr).when(chf).cause();
Long timeout = 200L;
- NetconfHelloMessageAdditionalHeader header = new NetconfHelloMessageAdditionalHeader("a", "host", "port", "trans", "id");
+ NetconfHelloMessageAdditionalHeader header =
+ new NetconfHelloMessageAdditionalHeader("a", "host", "port", "trans", "id");
NetconfClientSessionListener listener = new SimpleNetconfClientSessionListener();
InetSocketAddress address = InetSocketAddress.createUnresolved("host", 830);
ReconnectStrategyFactory reconnectStrategyFactory = Mockito.mock(ReconnectStrategyFactory.class);
doReturn("").when(reconnectStrategyFactory).toString();
doReturn(reconnect).when(reconnectStrategyFactory).createReconnectStrategy();
- NetconfReconnectingClientConfiguration cfg = NetconfReconnectingClientConfigurationBuilder.create().
- withProtocol(NetconfClientConfiguration.NetconfClientProtocol.SSH).
- withAddress(address).
- withConnectionTimeoutMillis(timeout).
- withReconnectStrategy(reconnect).
- withAdditionalHeader(header).
- withSessionListener(listener).
- withConnectStrategyFactory(reconnectStrategyFactory).
- withAuthHandler(handler).build();
+ NetconfReconnectingClientConfiguration cfg = NetconfReconnectingClientConfigurationBuilder.create()
+ .withProtocol(NetconfClientConfiguration.NetconfClientProtocol.SSH)
+ .withAddress(address)
+ .withConnectionTimeoutMillis(timeout)
+ .withReconnectStrategy(reconnect)
+ .withAdditionalHeader(header)
+ .withSessionListener(listener)
+ .withConnectStrategyFactory(reconnectStrategyFactory)
+ .withAuthHandler(handler).build();
- NetconfReconnectingClientConfiguration cfg2 = NetconfReconnectingClientConfigurationBuilder.create().
- withProtocol(NetconfClientConfiguration.NetconfClientProtocol.TCP).
- withAddress(address).
- withConnectionTimeoutMillis(timeout).
- withReconnectStrategy(reconnect).
- withAdditionalHeader(header).
- withSessionListener(listener).
- withConnectStrategyFactory(reconnectStrategyFactory).
- withAuthHandler(handler).build();
+ NetconfReconnectingClientConfiguration cfg2 = NetconfReconnectingClientConfigurationBuilder.create()
+ .withProtocol(NetconfClientConfiguration.NetconfClientProtocol.TCP)
+ .withAddress(address)
+ .withConnectionTimeoutMillis(timeout)
+ .withReconnectStrategy(reconnect)
+ .withAdditionalHeader(header)
+ .withSessionListener(listener)
+ .withConnectStrategyFactory(reconnectStrategyFactory)
+ .withAuthHandler(handler).build();
NetconfClientDispatcherImpl dispatcher = new NetconfClientDispatcherImpl(bossGroup, workerGroup, timer);
Future<NetconfClientSession> sshSession = dispatcher.createClient(cfg);
Future<NetconfClientSession> tcpSession = dispatcher.createClient(cfg2);
Future<Void> sshReconn = dispatcher.createReconnectingClient(cfg);
- Future<Void> tcpReconn = dispatcher.createReconnectingClient(cfg2);
+ final Future<Void> tcpReconn = dispatcher.createReconnectingClient(cfg2);
assertNotNull(sshSession);
assertNotNull(tcpSession);
NetconfClientSessionNegotiatorFactory negotiatorFactory = new NetconfClientSessionNegotiatorFactory(timer,
Optional.<NetconfHelloMessageAdditionalHeader>absent(), 200L);
- SessionNegotiator<?> sessionNegotiator = negotiatorFactory.getSessionNegotiator(listenerFactory, channel, promise);
+ SessionNegotiator<?> sessionNegotiator = negotiatorFactory.getSessionNegotiator(listenerFactory, channel,
+ promise);
assertNotNull(sessionNegotiator);
}
}
@Before
public void setUp() throws Exception {
- helloMessage = NetconfHelloMessage.createClientHello(Sets.newSet("exi:1.0"), Optional.<NetconfHelloMessageAdditionalHeader>absent());
+ helloMessage = NetconfHelloMessage.createClientHello(Sets.newSet("exi:1.0"), Optional
+ .<NetconfHelloMessageAdditionalHeader>absent());
pipeline = mockChannelPipeline();
future = mockChannelFuture();
channel = mockChannel();
doReturn(handler).when(pipeline).replace(anyString(), anyString(), any(ChunkedFramingMechanismEncoder.class));
NetconfXMLToHelloMessageDecoder messageDecoder = new NetconfXMLToHelloMessageDecoder();
- doReturn(messageDecoder).when(pipeline).replace(anyString(), anyString(), any(NetconfXMLToMessageDecoder.class));
- doReturn(pipeline).when(pipeline).replace(any(ChannelHandler.class), anyString(), any(NetconfClientSession.class));
+ doReturn(messageDecoder).when(pipeline).replace(anyString(), anyString(), any(NetconfXMLToMessageDecoder
+ .class));
+ doReturn(pipeline).when(pipeline).replace(any(ChannelHandler.class), anyString(), any(NetconfClientSession
+ .class));
return pipeline;
}
}).when(eventLoop).execute(any(Runnable.class));
}
- private NetconfClientSessionNegotiator createNetconfClientSessionNegotiator(final Promise<NetconfClientSession> promise,
- final NetconfMessage startExi) {
+ private NetconfClientSessionNegotiator createNetconfClientSessionNegotiator(
+ final Promise<NetconfClientSession> promise,
+ final NetconfMessage startExi) {
ChannelProgressivePromise progressivePromise = mock(ChannelProgressivePromise.class);
NetconfClientSessionPreferences preferences = new NetconfClientSessionPreferences(helloMessage, startExi);
doReturn(progressivePromise).when(promise).setFailure(any(Throwable.class));
NetconfClientSessionListener sessionListener = mock(NetconfClientSessionListener.class);
NetconfClientSessionNegotiator negotiator = createNetconfClientSessionNegotiator(promise, null);
- Set<String> set = createCapabilities("/helloMessage3.xml");
+ Set<String> set = createCapabilities("/helloMessage3.xml");
- final Set<String> cachedS1 = (Set<String>) negotiator.getSession(sessionListener,channel,createHelloMsg("/helloMessage1.xml")).getServerCapabilities();
+ final Set<String> cachedS1 = (Set<String>) negotiator.getSession(sessionListener, channel,
+ createHelloMsg("/helloMessage1.xml")).getServerCapabilities();
//helloMessage2 and helloMessage3 are the same with different order
- final Set<String> cachedS2 = (Set<String>) negotiator.getSession(sessionListener,channel,createHelloMsg("/helloMessage2.xml")).getServerCapabilities();
- final Set<String> cachedS3 = (Set<String>) negotiator.getSession(sessionListener,channel,createHelloMsg("/helloMessage3.xml")).getServerCapabilities();
+ final Set<String> cachedS2 = (Set<String>) negotiator.getSession(sessionListener, channel,
+ createHelloMsg("/helloMessage2.xml")).getServerCapabilities();
+ final Set<String> cachedS3 = (Set<String>) negotiator.getSession(sessionListener, channel,
+ createHelloMsg("/helloMessage3.xml")).getServerCapabilities();
assertEquals(cachedS3, set);
assertNotEquals(cachedS1, set);
@Test
public void testNetconfReconnectingClientConfiguration() throws Exception {
Long timeout = 200L;
- NetconfHelloMessageAdditionalHeader header = new NetconfHelloMessageAdditionalHeader("a", "host", "port", "trans", "id");
+ NetconfHelloMessageAdditionalHeader header =
+ new NetconfHelloMessageAdditionalHeader("a", "host", "port", "trans", "id");
NetconfClientSessionListener listener = new SimpleNetconfClientSessionListener();
InetSocketAddress address = InetSocketAddress.createUnresolved("host", 830);
ReconnectStrategyFactory strategy = Mockito.mock(ReconnectStrategyFactory.class);
AuthenticationHandler handler = Mockito.mock(AuthenticationHandler.class);
ReconnectStrategy reconnect = Mockito.mock(ReconnectStrategy.class);
- NetconfReconnectingClientConfiguration cfg = NetconfReconnectingClientConfigurationBuilder.create().
- withProtocol(NetconfClientConfiguration.NetconfClientProtocol.SSH).
- withAddress(address).
- withConnectionTimeoutMillis(timeout).
- withReconnectStrategy(reconnect).
- withAdditionalHeader(header).
- withSessionListener(listener).
- withConnectStrategyFactory(strategy).
- withAuthHandler(handler).build();
+ NetconfReconnectingClientConfiguration cfg = NetconfReconnectingClientConfigurationBuilder.create()
+ .withProtocol(NetconfClientConfiguration.NetconfClientProtocol.SSH)
+ .withAddress(address)
+ .withConnectionTimeoutMillis(timeout)
+ .withReconnectStrategy(reconnect)
+ .withAdditionalHeader(header)
+ .withSessionListener(listener)
+ .withConnectStrategyFactory(strategy)
+ .withAuthHandler(handler).build();
Assert.assertEquals(timeout, cfg.getConnectionTimeoutMillis());
Assert.assertEquals(Optional.fromNullable(header), cfg.getAdditionalHeader());
@Test
public void testSessionDown() throws Exception {
SimpleNetconfClientSessionListener simpleListener = new SimpleNetconfClientSessionListener();
- Future<NetconfMessage> promise = simpleListener.sendRequest(message);
+ final Future<NetconfMessage> promise = simpleListener.sendRequest(message);
simpleListener.onSessionUp(clientSession);
verify(channel, times(1)).writeAndFlush(anyObject());
@Test
public void testSendRequest() throws Exception {
SimpleNetconfClientSessionListener simpleListener = new SimpleNetconfClientSessionListener();
- Future<NetconfMessage> promise = simpleListener.sendRequest(message);
+ final Future<NetconfMessage> promise = simpleListener.sendRequest(message);
simpleListener.onSessionUp(clientSession);
verify(channel, times(1)).writeAndFlush(anyObject());
@Test
public void testOnMessage() throws Exception {
SimpleNetconfClientSessionListener simpleListener = new SimpleNetconfClientSessionListener();
- Future<NetconfMessage> promise = simpleListener.sendRequest(message);
+ final Future<NetconfMessage> promise = simpleListener.sendRequest(message);
simpleListener.onSessionUp(clientSession);
verify(channel, times(1)).writeAndFlush(anyObject());
SessionNegotiator<?> sessionNegotiator = mock(SessionNegotiator.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(SessionListenerFactory.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);
Promise<NetconfClientSession> promise = mock(Promise.class);
doReturn("").when(promise).toString();
- SshClientChannelInitializer initializer = new SshClientChannelInitializer(authenticationHandler, negotiatorFactory,
- sessionListener);
+ SshClientChannelInitializer initializer = new SshClientChannelInitializer(authenticationHandler,
+ negotiatorFactory, sessionListener);
initializer.initialize(channel, promise);
verify(pipeline, times(1)).addFirst(any(ChannelHandler.class));
}
NetconfClientSessionNegotiatorFactory factory = mock(NetconfClientSessionNegotiatorFactory.class);
SessionNegotiator<?> sessionNegotiator = mock(SessionNegotiator.class);
doReturn("").when(sessionNegotiator).toString();
- doReturn(sessionNegotiator).when(factory).getSessionNegotiator(any(SessionListenerFactory.class), any(Channel.class), any(Promise.class));
+ doReturn(sessionNegotiator).when(factory).getSessionNegotiator(any(SessionListenerFactory.class),
+ any(Channel.class), any(Promise.class));
NetconfClientSessionListener listener = mock(NetconfClientSessionListener.class);
- TcpClientChannelInitializer initializer = new TcpClientChannelInitializer(factory, listener);
+ final TcpClientChannelInitializer initializer = new TcpClientChannelInitializer(factory, listener);
ChannelPipeline pipeline = mock(ChannelPipeline.class);
doReturn(pipeline).when(pipeline).addAfter(anyString(), anyString(), any(ChannelHandler.class));
Channel channel = mock(Channel.class);
/**
- * Synchronous netconf client suitable for testing
+ * Synchronous netconf client suitable for testing.
*/
public class TestingNetconfClient implements Closeable {
private final long sessionId;
public TestingNetconfClient(String clientLabel,
- NetconfClientDispatcher netconfClientDispatcher, final NetconfClientConfiguration config) throws InterruptedException {
+ NetconfClientDispatcher netconfClientDispatcher,
+ final NetconfClientConfiguration config) throws InterruptedException {
this.label = clientLabel;
sessionListener = config.getSessionListener();
Future<NetconfClientSession> clientFuture = netconfClientDispatcher.createClient(config);
}
public Future<NetconfMessage> sendRequest(NetconfMessage message) {
- return ((SimpleNetconfClientSessionListener)sessionListener).sendRequest(message);
+ return ((SimpleNetconfClientSessionListener) sessionListener).sendRequest(message);
}
public NetconfMessage sendMessage(NetconfMessage message, int attemptMsDelay) throws ExecutionException,
public static void main(String[] args) throws Exception {
HashedWheelTimer hashedWheelTimer = new HashedWheelTimer();
NioEventLoopGroup nettyGroup = new NioEventLoopGroup();
- NetconfClientDispatcherImpl netconfClientDispatcher = new NetconfClientDispatcherImpl(nettyGroup, nettyGroup, hashedWheelTimer);
+ NetconfClientDispatcherImpl netconfClientDispatcher = new NetconfClientDispatcherImpl(nettyGroup, nettyGroup,
+ hashedWheelTimer);
LoginPassword authHandler = new LoginPassword("admin", "admin");
- TestingNetconfClient client = new TestingNetconfClient("client", netconfClientDispatcher, getClientConfig("127.0.0.1", 1830, true, Optional.of(authHandler)));
+ TestingNetconfClient client = new TestingNetconfClient("client", netconfClientDispatcher,
+ getClientConfig("127.0.0.1", 1830, true, Optional.of(authHandler)));
System.console().writer().println(client.getCapabilities());
}
- private static NetconfClientConfiguration getClientConfig(String host ,int port, boolean ssh, Optional<? extends AuthenticationHandler> maybeAuthHandler) throws UnknownHostException {
+ private static NetconfClientConfiguration getClientConfig(String host, int port, boolean ssh, Optional<? extends
+ AuthenticationHandler> maybeAuthHandler) throws UnknownHostException {
InetSocketAddress netconfAddress = new InetSocketAddress(InetAddress.getByName(host), port);
final NetconfClientConfigurationBuilder b = NetconfClientConfigurationBuilder.create();
b.withAddress(netconfAddress);
</execution>
</executions>
</plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <configuration>
+ <propertyExpansion>checkstyle.violationSeverity=error</propertyExpansion>
+ </configuration>
+ </plugin>
</plugins>
</build>
public void initialize(Channel ch, Promise<S> promise) {
ch.pipeline().addLast(NETCONF_MESSAGE_AGGREGATOR, new NetconfEOMAggregator());
initializeMessageDecoder(ch);
- ch.pipeline().addLast(NETCONF_MESSAGE_FRAME_ENCODER, FramingMechanismHandlerFactory.createHandler(FramingMechanism.EOM));
+ ch.pipeline().addLast(NETCONF_MESSAGE_FRAME_ENCODER,
+ FramingMechanismHandlerFactory.createHandler(FramingMechanism.EOM));
initializeMessageEncoder(ch);
initializeSessionNegotiator(ch, promise);
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 {
+public abstract class AbstractNetconfSession<S extends NetconfSession,L extends NetconfSessionListener<S>>
+ extends AbstractProtocolSession<NetconfMessage> implements NetconfSession, NetconfExiSession {
private static final Logger LOG = LoggerFactory.getLogger(AbstractNetconfSession.class);
private final L sessionListener;
private final long sessionId;
LOG.debug("Session {} end of input detected while session was in state {}", toString(), isUp() ? "up"
: "initialized");
if (isUp()) {
- this.sessionListener.onSessionDown(thisInstance(), new IOException("End of input detected. Close the session."));
+ this.sessionListener.onSessionDown(thisInstance(),
+ new IOException("End of input detected. Close the session."));
}
}
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
-public abstract class AbstractNetconfSessionNegotiator<P extends NetconfSessionPreferences, S extends AbstractNetconfSession<S, L>, L extends NetconfSessionListener<S>>
+public abstract class AbstractNetconfSessionNegotiator<P extends NetconfSessionPreferences,
+ S extends AbstractNetconfSession<S, L>, L extends NetconfSessionListener<S>>
extends AbstractSessionNegotiator<NetconfHelloMessage, S> {
private static final Logger LOG = LoggerFactory.getLogger(AbstractNetconfSessionNegotiator.class);
private Timeout timeout;
/**
- * Possible states for Finite State Machine
+ * Possible states for Finite State Machine.
*/
protected enum State {
IDLE, OPEN_WAIT, FAILED, ESTABLISHED
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) {
+ 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.sessionPreferences = sessionPreferences;
this.promise = promise;
private static Optional<SslHandler> getSslHandler(final Channel channel) {
final SslHandler sslHandler = channel.pipeline().get(SslHandler.class);
- return sslHandler == null ? Optional.<SslHandler> absent() : Optional.of(sslHandler);
+ return sslHandler == null ? Optional.<SslHandler>absent() : Optional.of(sslHandler);
}
public P getSessionPreferences() {
channel.close().addListener(new GenericFutureListener<ChannelFuture>() {
@Override
public void operationComplete(final ChannelFuture future) throws Exception {
- if(future.isSuccess()) {
+ if (future.isSuccess()) {
LOG.debug("Channel {} closed: success", future.channel());
} else {
LOG.warn("Channel {} closed: fail", future.channel());
}
});
}
- } else if(channel.isOpen()) {
+ } else if (channel.isOpen()) {
channel.pipeline().remove(NAME_OF_EXCEPTION_HANDLER);
}
}
}
private void cancelTimeout() {
- if(timeout!=null) {
+ if (timeout != null) {
timeout.cancel();
}
}
- protected final S getSessionForHelloMessage(final NetconfHelloMessage netconfMessage) throws NetconfDocumentedException {
+ protected final S getSessionForHelloMessage(final NetconfHelloMessage netconfMessage)
+ throws NetconfDocumentedException {
Preconditions.checkNotNull(netconfMessage, "netconfMessage");
final Document doc = netconfMessage.getDocument();
}
/**
- * Insert chunk framing handlers into the pipeline
+ * Insert chunk framing handlers into the pipeline.
*/
private void insertChunkFramingToPipeline() {
replaceChannelHandler(channel, AbstractChannelInitializer.NETCONF_MESSAGE_FRAME_ENCODER,
/**
* Remove special inbound handler for hello message. Insert regular netconf xml message (en|de)coders.
*
+ * <p>
* Inbound hello message handler should be kept until negotiation is successful
* It caches any non-hello messages while negotiation is still in progress
*/
protected final void replaceHelloMessageInboundHandler(final S session) {
- ChannelHandler helloMessageHandler = replaceChannelHandler(channel, AbstractChannelInitializer.NETCONF_MESSAGE_DECODER, new NetconfXMLToMessageDecoder());
+ ChannelHandler helloMessageHandler = replaceChannelHandler(channel,
+ AbstractChannelInitializer.NETCONF_MESSAGE_DECODER, new NetconfXMLToMessageDecoder());
Preconditions.checkState(helloMessageHandler instanceof NetconfXMLToHelloMessageDecoder,
"Pipeline handlers misplaced on session: %s, pipeline: %s", session, channel.pipeline());
((NetconfXMLToHelloMessageDecoder) helloMessageHandler).getPostHelloNetconfMessages();
// Process messages received during negotiation
- // The hello message handler does not have to be synchronized, since it is always call from the same thread by netty
+ // The hello message handler does not have to be synchronized,
+ // since it is always call from the same thread by netty.
// It means, we are now using the thread now
for (NetconfMessage message : netconfMessagesFromNegotiation) {
session.handleMessage(message);
* Remove special outbound handler for hello message. Insert regular netconf xml message (en|de)coders.
*/
private void replaceHelloMessageOutboundHandler() {
- replaceChannelHandler(channel, AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER, new NetconfMessageToXMLEncoder());
+ replaceChannelHandler(channel, AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER,
+ new NetconfMessageToXMLEncoder());
}
- private static ChannelHandler replaceChannelHandler(final Channel channel, final String handlerKey, final ChannelHandler decoder) {
+ private static ChannelHandler replaceChannelHandler(final Channel channel, final String handlerKey,
+ final ChannelHandler decoder) {
return channel.pipeline().replace(handlerKey, handlerKey, decoder);
}
- protected abstract S getSession(L sessionListener, Channel channel, NetconfHelloMessage message) throws NetconfDocumentedException;
+ protected abstract S getSession(L sessionListener, Channel channel, NetconfHelloMessage message)
+ throws NetconfDocumentedException;
private synchronized void changeState(final State newState) {
LOG.debug("Changing state from : {} to : {} for channel: {}", state, newState, channel);
- Preconditions.checkState(isStateChangePermitted(state, newState), "Cannot change state from %s to %s for chanel %s", state,
- newState, channel);
+ Preconditions.checkState(isStateChangePermitted(state, newState),
+ "Cannot change state from %s to %s for chanel %s", state, newState, channel);
this.state = newState;
}
}
/**
- * Handler to catch exceptions in pipeline during negotiation
+ * Handler to catch exceptions in pipeline during negotiation.
*/
private final class ExceptionHandlingInboundChannelHandler extends ChannelInboundHandlerAdapter {
@Override
package org.opendaylight.netconf.nettyutil.handler;
-
import com.google.common.base.Preconditions;
import java.io.IOException;
import java.io.Writer;
/**
* Custom BufferedWriter optimized for netconf pipeline implemented instead of default BufferedWriter provided by jdk.
+ *
* <p>
* The line separator instance field in java.io.BufferedWriter is
* assigned using AccessController and takes considerable amount of time especially
* if lots of BufferedWriters are created in the system.
+ *
* <p>
* This implementation should only be used if newLine method is not required
* such as netconf message to XML encoders.
private static final int DEFAULT_CHAR_BUFFER_SIZE = 8192;
private final Writer writer;
- private final char buffer[];
+ private final char[] buffer;
private final int bufferSize;
private int nextChar = 0;
}
private void flushBuffer() throws IOException {
- if (nextChar == 0)
+ if (nextChar == 0) {
return;
+ }
writer.write(buffer, 0, nextChar);
nextChar = 0;
}
@Override
- public void write(final int c) throws IOException {
- if (nextChar >= bufferSize)
+ public void write(final int character) throws IOException {
+ if (nextChar >= bufferSize) {
flushBuffer();
- buffer[nextChar++] = (char) c;
+ }
+ buffer[nextChar++] = (char) character;
}
@Override
public void write(final char[] buffer, final int offset, final int length) throws IOException {
- if ((offset < 0) || (offset > buffer.length) || (length < 0) ||
- ((offset + length) > buffer.length) || ((offset + length) < 0)) {
- throw new IndexOutOfBoundsException(String.format("Buffer size: %d, Offset: %d, Length: %d", buffer.length, offset, length));
+ if ((offset < 0) || (offset > buffer.length)
+ || (length < 0) || ((offset + length) > buffer.length) || ((offset + length) < 0)) {
+ throw new IndexOutOfBoundsException(
+ String.format("Buffer size: %d, Offset: %d, Length: %d", buffer.length, offset, length));
} else if (length == 0) {
return;
}
return;
}
- int b = offset;
+ int bufferOffset = offset;
final int t = offset + length;
- while (b < t) {
- final int d = Math.min(bufferSize - nextChar, t - b);
- System.arraycopy(buffer, b, this.buffer, nextChar, d);
- b += d;
+ while (bufferOffset < t) {
+ final int d = Math.min(bufferSize - nextChar, t - bufferOffset);
+ System.arraycopy(buffer, bufferOffset, this.buffer, nextChar, d);
+ bufferOffset += d;
nextChar += d;
- if (nextChar >= bufferSize)
+ if (nextChar >= bufferSize) {
flushBuffer();
+ }
}
}
@Override
public void write(final String string, final int offset, final int length) throws IOException {
- int b = offset;
+ int bufferOffset = offset;
final int t = offset + length;
- while (b < t) {
- final int d = Math.min(bufferSize - nextChar, t - b);
- string.getChars(b, b + d, buffer, nextChar);
- b += d;
+ while (bufferOffset < t) {
+ final int d = Math.min(bufferSize - nextChar, t - bufferOffset);
+ string.getChars(bufferOffset, bufferOffset + d, buffer, nextChar);
+ bufferOffset += d;
nextChar += d;
- if (nextChar >= bufferSize)
+ if (nextChar >= bufferSize) {
flushBuffer();
+ }
}
}
}
public ChunkedFramingMechanismEncoder(final int chunkSize) {
- Preconditions.checkArgument(chunkSize >= MIN_CHUNK_SIZE && chunkSize <= MAX_CHUNK_SIZE, "Unsupported chunk size %s", chunkSize);
+ Preconditions.checkArgument(chunkSize >= MIN_CHUNK_SIZE && chunkSize <= MAX_CHUNK_SIZE,
+ "Unsupported chunk size %s", chunkSize);
this.chunkSize = chunkSize;
}
import org.slf4j.LoggerFactory;
public class NetconfChunkAggregator extends ByteToMessageDecoder {
- private final static Logger LOG = LoggerFactory.getLogger(NetconfChunkAggregator.class);
+ private static final Logger LOG = LoggerFactory.getLogger(NetconfChunkAggregator.class);
private static final String GOT_PARAM_WHILE_WAITING_FOR_PARAM = "Got byte {} while waiting for {}";
private static final String GOT_PARAM_WHILE_WAITING_FOR_PARAM_PARAM = "Got byte {} while waiting for {}-{}";
public static final int DEFAULT_MAXIMUM_CHUNK_SIZE = 16 * 1024 * 1024;
- private static enum State {
+ private enum State {
HEADER_ONE, // \n
HEADER_TWO, // #
HEADER_LENGTH_FIRST, // [1-9]
private long chunkSize;
private CompositeByteBuf chunk;
- private static void checkNewLine(final byte b,final String errorMessage) {
- if (b != '\n') {
- LOG.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM, b, (byte)'\n');
+ private static void checkNewLine(final byte byteToCheck, final String errorMessage) {
+ if (byteToCheck != '\n') {
+ LOG.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM, byteToCheck, (byte)'\n');
throw new IllegalStateException(errorMessage);
}
}
- private static void checkHash(final byte b,final String errorMessage) {
- if (b != '#') {
- LOG.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM, b, (byte)'#');
+ private static void checkHash(final byte byteToCheck, final String errorMessage) {
+ if (byteToCheck != '#') {
+ LOG.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM, byteToCheck, (byte)'#');
throw new IllegalStateException(errorMessage);
}
}
}
@Override
- protected void decode(final ChannelHandlerContext ctx, final ByteBuf in, final List<Object> out) throws IllegalStateException {
+ protected void decode(final ChannelHandlerContext ctx,
+ final ByteBuf in, final List<Object> out) throws IllegalStateException {
while (in.isReadable()) {
switch (state) {
- case HEADER_ONE:
- {
- final byte b = in.readByte();
- checkNewLine(b, "Malformed chunk header encountered (byte 0)");
-
- state = State.HEADER_TWO;
-
- initChunk();
- break;
- }
- case HEADER_TWO:
- {
- final byte b = in.readByte();
- checkHash(b, "Malformed chunk header encountered (byte 1)");
-
- state = State.HEADER_LENGTH_FIRST;
- break;
- }
- case HEADER_LENGTH_FIRST:
- {
- final byte b = in.readByte();
- chunkSize = processHeaderLengthFirst(b);
- state = State.HEADER_LENGTH_OTHER;
- break;
- }
- case HEADER_LENGTH_OTHER:
- {
- final byte b = in.readByte();
- if (b == '\n') {
- state = State.DATA;
+ case HEADER_ONE:
+ {
+ final byte b = in.readByte();
+ checkNewLine(b, "Malformed chunk header encountered (byte 0)");
+ state = State.HEADER_TWO;
+ initChunk();
break;
}
-
- if (b < '0' || b > '9') {
- LOG.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM_PARAM, b, (byte)'0', (byte)'9');
- throw new IllegalStateException("Invalid chunk size encountered");
+ case HEADER_TWO:
+ {
+ final byte b = in.readByte();
+ checkHash(b, "Malformed chunk header encountered (byte 1)");
+ state = State.HEADER_LENGTH_FIRST;
+ break;
}
-
- chunkSize *= 10;
- chunkSize += b - '0';
- checkChunkSize();
- break;
- }
- case DATA:
- /*
- * FIXME: this gathers all data into one big chunk before passing
- * it on. Make sure the pipeline can work with partial data
- * and then change this piece to pass the data on as it
- * comes through.
- */
- if (in.readableBytes() < chunkSize) {
- LOG.debug("Buffer has {} bytes, need {} to complete chunk", in.readableBytes(), chunkSize);
- in.discardReadBytes();
- return;
+ case HEADER_LENGTH_FIRST:
+ {
+ final byte b = in.readByte();
+ chunkSize = processHeaderLengthFirst(b);
+ state = State.HEADER_LENGTH_OTHER;
+ break;
+ }
+ case HEADER_LENGTH_OTHER:
+ {
+ final byte b = in.readByte();
+ if (b == '\n') {
+ state = State.DATA;
+ break;
+ }
+ if (b < '0' || b > '9') {
+ LOG.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM_PARAM, b, (byte)'0', (byte)'9');
+ throw new IllegalStateException("Invalid chunk size encountered");
+ }
+ chunkSize *= 10;
+ chunkSize += b - '0';
+ checkChunkSize();
+ break;
+ }
+ case DATA:
+ /*
+ * FIXME: this gathers all data into one big chunk before passing
+ * it on. Make sure the pipeline can work with partial data
+ * and then change this piece to pass the data on as it
+ * comes through.
+ */
+ if (in.readableBytes() < chunkSize) {
+ LOG.debug("Buffer has {} bytes, need {} to complete chunk", in.readableBytes(), chunkSize);
+ in.discardReadBytes();
+ return;
+ }
+ aggregateChunks(in.readBytes((int) chunkSize));
+ state = State.FOOTER_ONE;
+ break;
+ case FOOTER_ONE:
+ {
+ final byte b = in.readByte();
+ checkNewLine(b,"Malformed chunk footer encountered (byte 0)");
+ state = State.FOOTER_TWO;
+ chunkSize = 0;
+ break;
+ }
+ case FOOTER_TWO:
+ {
+ final byte b = in.readByte();
+ checkHash(b,"Malformed chunk footer encountered (byte 1)");
+ state = State.FOOTER_THREE;
+ break;
+ }
+ case FOOTER_THREE:
+ {
+ final byte b = in.readByte();
+ // In this state, either header-of-new-chunk or message-end is expected
+ // Depends on the next character
+ extractNewChunkOrMessageEnd(b);
+ break;
+ }
+ case FOOTER_FOUR:
+ {
+ final byte b = in.readByte();
+ checkNewLine(b,"Malformed chunk footer encountered (byte 3)");
+ state = State.HEADER_ONE;
+ out.add(chunk);
+ chunk = null;
+ break;
+ }
+ default :
+ {
+ LOG.info("Unknown state.");
}
- aggregateChunks(in.readBytes((int) chunkSize));
- state = State.FOOTER_ONE;
- break;
- case FOOTER_ONE:
- {
- final byte b = in.readByte();
- checkNewLine(b,"Malformed chunk footer encountered (byte 0)");
- state = State.FOOTER_TWO;
- chunkSize = 0;
- break;
- }
- case FOOTER_TWO:
- {
- final byte b = in.readByte();
- checkHash(b,"Malformed chunk footer encountered (byte 1)");
- state = State.FOOTER_THREE;
- break;
- }
- case FOOTER_THREE:
- {
- final byte b = in.readByte();
-
- // In this state, either header-of-new-chunk or message-end is expected
- // Depends on the next character
-
- extractNewChunkOrMessageEnd(b);
-
- break;
- }
- case FOOTER_FOUR:
- {
- final byte b = in.readByte();
- checkNewLine(b,"Malformed chunk footer encountered (byte 3)");
- state = State.HEADER_ONE;
- out.add(chunk);
- chunk = null;
- break;
- }
}
}
in.discardReadBytes();
}
- private void extractNewChunkOrMessageEnd(final byte b) {
- if (isHeaderLengthFirst(b)) {
+ private void extractNewChunkOrMessageEnd(final byte byteToCheck) {
+ if (isHeaderLengthFirst(byteToCheck)) {
// Extract header length#1 from new chunk
- chunkSize = processHeaderLengthFirst(b);
+ chunkSize = processHeaderLengthFirst(byteToCheck);
// Proceed with next chunk processing
state = State.HEADER_LENGTH_OTHER;
- } else if (b == '#') {
+ } else if (byteToCheck == '#') {
state = State.FOOTER_FOUR;
} else {
- LOG.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM_PARAM, b, (byte) '#', (byte) '1', (byte) '9');
+ LOG.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM_PARAM, byteToCheck, (byte) '#', (byte) '1', (byte) '9');
throw new IllegalStateException("Malformed chunk footer encountered (byte 2)");
}
}
chunk.writerIndex(chunk.writerIndex() + newChunk.readableBytes());
}
- private static int processHeaderLengthFirst(final byte b) {
- if (!isHeaderLengthFirst(b)) {
- LOG.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM_PARAM, b, (byte)'1', (byte)'9');
+ private static int processHeaderLengthFirst(final byte byteToCheck) {
+ if (!isHeaderLengthFirst(byteToCheck)) {
+ LOG.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM_PARAM, byteToCheck, (byte)'1', (byte)'9');
throw new IllegalStateException("Invalid chunk size encountered (byte 0)");
}
- return b - '0';
+ return byteToCheck - '0';
}
- private static boolean isHeaderLengthFirst(final byte b) {
- return b >= '1' && b <= '9';
+ private static boolean isHeaderLengthFirst(final byte byteToCheck) {
+ return byteToCheck >= '1' && byteToCheck <= '9';
}
}
* Since we have a limited number of options we can have, instantiating a weak cache
* will allow us to reuse instances where possible.
*/
- private static final LoadingCache<Short, GrammarCache> GRAMMAR_CACHES = CacheBuilder.newBuilder().weakValues().build(new CacheLoader<Short, GrammarCache>() {
- @Override
- public GrammarCache load(final Short key) {
- return new GrammarCache(key);
- }
- });
+ private static final LoadingCache<Short, GrammarCache> GRAMMAR_CACHES =
+ CacheBuilder.newBuilder().weakValues().build(new CacheLoader<Short, GrammarCache>() {
+ @Override
+ public GrammarCache load(final Short key) {
+ return new GrammarCache(key);
+ }
+ });
/**
* Grammar cache acts as a template and is duplicated by the Transmogrifier and the Reader
private static final Logger LOG = LoggerFactory.getLogger(NetconfEXIToMessageDecoder.class);
private static final SAXTransformerFactory FACTORY;
+
static {
final TransformerFactory f = SAXTransformerFactory.newInstance();
if (!f.getFeature(SAXTransformerFactory.FEATURE)) {
- throw new TransformerFactoryConfigurationError(String.format("Factory %s is not a SAXTransformerFactory", f));
+ throw new TransformerFactoryConfigurationError(
+ String.format("Factory %s is not a SAXTransformerFactory", f));
}
FACTORY = (SAXTransformerFactory)f;
}
@Override
- protected void decode(final ChannelHandlerContext ctx, final ByteBuf in, final List<Object> out) throws EXIOptionsException, IOException, SAXException, TransformerConfigurationException {
+ protected void decode(final ChannelHandlerContext ctx, final ByteBuf in, final List<Object> out)
+ throws EXIOptionsException, IOException, SAXException, TransformerConfigurationException {
/*
* Note that we could loop here and process all the messages, but we can't do that.
* The reason is <stop-exi> operation, which has the contract of immediately stopping
final DOMResult domResult = new DOMResult(documentBuilder.newDocument());
handler.setResult(domResult);
- try (final InputStream is = new ByteBufInputStream(in)) {
+ try (InputStream is = new ByteBufInputStream(in)) {
// Performs internal reset before doing anything
reader.parse(new InputSource(is));
}
* {@link NetconfHelloMessage}
* . Used by netconf clients to send information about the user, ip address,
* protocol etc.
+ *
* <p>
* Hello message with header example:
+ *
* <p>
*
* <pre>
* {@code
* [tomas;10.0.0.0/10000;tcp;1000;1000;;/home/tomas;;]
- * <hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- * <capabilities>
- * <capability>urn:ietf:params:netconf:base:1.0</capability>
- * </capabilities>
- * </hello>
+ * < hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+ * < capabilities>
+ * < capability>urn:ietf:params:netconf:base:1.0< /capability>
+ * < /capabilities>
+ * < /hello>
* }
* </pre>
*/
public final class NetconfHelloMessageToXMLEncoder extends NetconfMessageToXMLEncoder {
@Override
@VisibleForTesting
- public void encode(ChannelHandlerContext ctx, NetconfMessage msg, ByteBuf out) throws IOException, TransformerException {
+ public void encode(ChannelHandlerContext ctx, NetconfMessage msg, ByteBuf out)
+ throws IOException, TransformerException {
Preconditions.checkState(msg instanceof NetconfHelloMessage, "Netconf message of type %s expected, was %s",
NetconfHelloMessage.class, msg.getClass());
Optional<NetconfHelloMessageAdditionalHeader> headerOptional = ((NetconfHelloMessage) msg)
this.transmogrifier = Preconditions.checkNotNull(transmogrifier);
}
- public static NetconfMessageToEXIEncoder create(final NetconfEXICodec codec) throws EXIOptionsException, TransmogrifierException {
+ public static NetconfMessageToEXIEncoder create(final NetconfEXICodec codec)
+ throws EXIOptionsException, TransmogrifierException {
return new NetconfMessageToEXIEncoder(codec.getTransmogrifier());
}
@Override
- protected void encode(final ChannelHandlerContext ctx, final NetconfMessage msg, final ByteBuf out) throws EXIOptionsException, IOException, TransformerException, TransmogrifierException {
+ protected void encode(final ChannelHandlerContext ctx, final NetconfMessage msg, final ByteBuf out)
+ throws EXIOptionsException, IOException, TransformerException, TransmogrifierException {
LOG.trace("Sent to encode : {}", msg);
- try (final OutputStream os = new ByteBufOutputStream(out)) {
+ try (OutputStream os = new ByteBufOutputStream(out)) {
transmogrifier.setOutputStream(os);
final ContentHandler handler = transmogrifier.getSAXTransmogrifier();
final Transformer transformer = ThreadLocalTransformers.getDefaultTransformer();
@Override
@VisibleForTesting
- public void encode(final ChannelHandlerContext ctx, final NetconfMessage msg, final ByteBuf out) throws IOException, TransformerException {
+ public void encode(final ChannelHandlerContext ctx, final NetconfMessage msg, final ByteBuf out)
+ throws IOException, TransformerException {
LOG.trace("Sent to encode : {}", msg);
if (clientId.isPresent()) {
// Using custom BufferedWriter that does not provide newLine method as performance improvement
// see javadoc for BufferedWriter
- StreamResult result = new StreamResult(new BufferedWriter(new OutputStreamWriter(os, StandardCharsets.UTF_8)));
+ StreamResult result =
+ new StreamResult(new BufferedWriter(new OutputStreamWriter(os, StandardCharsets.UTF_8)));
DOMSource source = new DOMSource(msg.getDocument());
ThreadLocalTransformers.getPrettyTransformer().transform(source, result);
}
/**
* Customized NetconfXMLToMessageDecoder that reads additional header with
* session metadata from
- * {@link NetconfHelloMessage}
- *
- *
+ * {@link NetconfHelloMessage}*
* This handler should be replaced in pipeline by regular message handler as last step of negotiation.
* It serves as a message barrier and halts all non-hello netconf messages.
* Netconf messages after hello should be processed once the negotiation succeeded.
@Override
@VisibleForTesting
- public void decode(final ChannelHandlerContext ctx, final ByteBuf in, final List<Object> out) throws IOException, SAXException, NetconfDocumentedException {
+ public void decode(final ChannelHandlerContext ctx, final ByteBuf in, final List<Object> out)
+ throws IOException, SAXException, NetconfDocumentedException {
if (in.readableBytes() == 0) {
LOG.debug("No more content in incoming buffer.");
return;
}
}
- private static NetconfMessage getNetconfMessage(final String additionalHeader, final Document doc) throws NetconfDocumentedException {
+ private static NetconfMessage getNetconfMessage(final String additionalHeader, final Document doc)
+ throws NetconfDocumentedException {
NetconfMessage msg = new NetconfMessage(doc);
- if(NetconfHelloMessage.isHelloMessage(msg)) {
+ if (NetconfHelloMessage.isHelloMessage(msg)) {
if (additionalHeader != null) {
return new NetconfHelloMessage(doc, NetconfHelloMessageAdditionalHeader.fromString(additionalHeader));
} else {
return -1;
}
}
- int j = 0;
+ int index = 0;
for (int i = 0; i < bytes.length; i++) {
- if (bytes[i] == sequence[j]) {
- j++;
- if (j == sequence.length) {
- return i - j + 1;
+ if (bytes[i] == sequence[index]) {
+ index++;
+ if (index == sequence.length) {
+ return i - index + 1;
}
} else {
- j = 0;
+ index = 0;
}
}
return -1;
private static void logMessage(final byte[] bytes) {
if (LOG.isDebugEnabled()) {
- String s = StandardCharsets.UTF_8.decode(ByteBuffer.wrap(bytes)).toString();
- LOG.debug("Parsing message \n{}", s);
+ String string = StandardCharsets.UTF_8.decode(ByteBuffer.wrap(bytes)).toString();
+ LOG.debug("Parsing message \n{}", string);
}
}
private static boolean startsWithAdditionalHeader(final byte[] bytes) {
for (byte[] possibleStart : POSSIBLE_STARTS) {
- int i = 0;
+ int index = 0;
for (byte b : possibleStart) {
- if(bytes[i++] != b) {
+ if (bytes[index++] != b) {
break;
}
- if(i == possibleStart.length) {
+ if (index == possibleStart.length) {
return true;
}
}
}
/**
- * @return Collection of NetconfMessages that were not hello, but were received during negotiation
+ * Get netconf messages received during negotiation.
+ *
+ * @return Collection of NetconfMessages that were not hello, but were received during negotiation.
*/
public Iterable<NetconfMessage> getPostHelloNetconfMessages() {
return nonHelloMessages;
private static final Logger LOG = LoggerFactory.getLogger(NetconfXMLToMessageDecoder.class);
@Override
- public void decode(final ChannelHandlerContext ctx, final ByteBuf in, final List<Object> out) throws IOException, SAXException {
+ public void decode(final ChannelHandlerContext ctx, final ByteBuf in,
+ final List<Object> out) throws IOException, SAXException {
if (in.isReadable()) {
if (LOG.isTraceEnabled()) {
LOG.trace("Received to decode: {}", ByteBufUtil.hexDump(in));
* Check whether a byte is whitespace/control character. Considered whitespace characters: <br/>
* SPACE, \t, \n, \v, \r, \f
*
- * @param b byte to check
+ * @param byteToCheck byte to check
* @return true if the byte is a whitespace/control character
*/
- private static boolean isWhitespace(final byte b) {
- return b <= 0x0d && b >= 0x09 || b == 0x20;
+ private static boolean isWhitespace(final byte byteToCheck) {
+ return byteToCheck <= 0x0d && byteToCheck >= 0x09 || byteToCheck == 0x20;
}
}
this.options = Preconditions.checkNotNull(options);
}
-
+ @SuppressWarnings("checkstyle:FallThrough")
public static EXIParameters fromXmlElement(final XmlElement root) throws EXIOptionsException {
final EXIOptions options = new EXIOptions();
final NodeList alignmentElements = root.getElementsByTagName(EXI_PARAMETER_ALIGNMENT);
final String alignmentTextContent = alignmentElement.getTextContent().trim();
switch (alignmentTextContent) {
- case EXI_PARAMETER_BYTE_ALIGNED:
- options.setAlignmentType(AlignmentType.byteAligned);
- break;
- case EXI_PARAMETER_COMPRESSED:
- options.setAlignmentType(AlignmentType.compress);
- break;
- case EXI_PARAMETER_PRE_COMPRESSION:
- options.setAlignmentType(AlignmentType.preCompress);
- break;
- default:
- LOG.warn("Unexpected value in alignmentTextContent: {} , using default value", alignmentTextContent);
- case EXI_PARAMETER_BIT_PACKED:
- options.setAlignmentType(AlignmentType.bitPacked);
- break;
+ case EXI_PARAMETER_BYTE_ALIGNED:
+ options.setAlignmentType(AlignmentType.byteAligned);
+ break;
+ case EXI_PARAMETER_COMPRESSED:
+ options.setAlignmentType(AlignmentType.compress);
+ break;
+ case EXI_PARAMETER_PRE_COMPRESSION:
+ options.setAlignmentType(AlignmentType.preCompress);
+ break;
+ default:
+ LOG.warn("Unexpected value in alignmentTextContent: {} , using default value",
+ alignmentTextContent);
+ case EXI_PARAMETER_BIT_PACKED:
+ options.setAlignmentType(AlignmentType.bitPacked);
+ break;
}
} else {
options.setAlignmentType(AlignmentType.bitPacked);
public static final String PIS_KEY = "pis";
public static final String PREFIXES_KEY = "prefixes";
private static final Logger LOG = LoggerFactory.getLogger(NetconfStartExiMessage.class);
+
private NetconfStartExiMessage(final Document doc) {
super(doc);
}
}
}
+ @SuppressWarnings("checkstyle:FallThrough")
private static void addAlignment(final EXIOptions exiOptions, final Document doc, final Element startExiElement) {
final Element alignmentElement = doc.createElementNS(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_EXI_1_0,
ALIGNMENT_KEY);
String alignmentString;
switch (exiOptions.getAlignmentType()) {
- case byteAligned: {
- alignmentString = EXIParameters.EXI_PARAMETER_BYTE_ALIGNED;
- break;
- }
- case compress: {
- alignmentString = EXIParameters.EXI_PARAMETER_COMPRESSED;
- break;
- }
- case preCompress: {
- alignmentString = EXIParameters.EXI_PARAMETER_PRE_COMPRESSION;
- break;
- }
- default:
- LOG.warn("Unexpected value in EXI alignment type: {} , using default value", exiOptions.getAlignmentType());
- case bitPacked: {
- alignmentString = EXIParameters.EXI_PARAMETER_BIT_PACKED;
- break;
- }
+ case byteAligned: {
+ alignmentString = EXIParameters.EXI_PARAMETER_BYTE_ALIGNED;
+ break;
+ }
+ case compress: {
+ alignmentString = EXIParameters.EXI_PARAMETER_COMPRESSED;
+ break;
+ }
+ case preCompress: {
+ alignmentString = EXIParameters.EXI_PARAMETER_PRE_COMPRESSION;
+ break;
+ }
+ default:
+ LOG.warn("Unexpected value in EXI alignment type: {} , using default value",
+ exiOptions.getAlignmentType());
+ case bitPacked: {
+ alignmentString = EXIParameters.EXI_PARAMETER_BIT_PACKED;
+ break;
+ }
}
alignmentElement.setTextContent(alignmentString);
startExiElement.appendChild(alignmentElement);
}
- private static void createFidelityElement(final Document doc, final List<Element> fidelityElements, final boolean fidelity, final String fidelityName) {
+ private static void createFidelityElement(final Document doc, final List<Element> fidelityElements,
+ final boolean fidelity, final String fidelityName) {
if (fidelity) {
fidelityElements.add(doc.createElementNS(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_EXI_1_0,
public abstract String getUsername();
- public abstract org.apache.sshd.client.future.AuthFuture authenticate(final ClientSession session) throws IOException;
+ public abstract org.apache.sshd.client.future.AuthFuture authenticate(ClientSession session)
+ throws IOException;
}
/**
* Class Providing username/password authentication option to
- * {@link org.opendaylight.netconf.nettyutil.handler.ssh.client.AsyncSshHandler}
+ * {@link org.opendaylight.netconf.nettyutil.handler.ssh.client.AsyncSshHandler}.
*/
public class LoginPassword extends AuthenticationHandler {
private final String username;
private static final long DEFAULT_TIMEOUT = -1L;
public static final SshClient DEFAULT_CLIENT;
+
static {
final Map<String, String> props = new HashMap<>();
props.put(SshClient.AUTH_TIMEOUT, Long.toString(DEFAULT_TIMEOUT));
}
/**
+ * Constructor of {@code AsyncSshHandler}.
*
- * @param authenticationHandler
- * @param sshClient started SshClient
- * @throws IOException
+ * @param authenticationHandler authentication handler
+ * @param sshClient started SshClient
+ * @throws IOException if the I/O operation fails
*/
- public AsyncSshHandler(final AuthenticationHandler authenticationHandler, final SshClient sshClient) throws IOException {
+ public AsyncSshHandler(final AuthenticationHandler authenticationHandler,
+ final SshClient sshClient) throws IOException {
this.authenticationHandler = Preconditions.checkNotNull(authenticationHandler);
this.sshClient = Preconditions.checkNotNull(sshClient);
}
- public static AsyncSshHandler createForNetconfSubsystem(final AuthenticationHandler authenticationHandler) throws IOException {
+ public static AsyncSshHandler createForNetconfSubsystem(final AuthenticationHandler authenticationHandler)
+ throws IOException {
return new AsyncSshHandler(authenticationHandler, DEFAULT_CLIENT);
}
/**
+ * Create AsyncSshHandler for netconf subsystem. Negotiation future has to be set to success after successful
+ * netconf negotiation.
*
- * Create AsyncSshHandler for netconf subsystem. Negotiation future has to be set to success after successful netconf
- * negotiation.
- *
- * @param authenticationHandler
- * @param negotiationFuture
- * @return
- * @throws IOException
+ * @param authenticationHandler authentication handler
+ * @param negotiationFuture negotiation future
+ * @return {@code AsyncSshHandler}
+ * @throws IOException if the I/O operation fails
*/
public static AsyncSshHandler createForNetconfSubsystem(final AuthenticationHandler authenticationHandler,
final Future<?> negotiationFuture) throws IOException {
handleSshAuthenticated(session, ctx);
} else {
// Exception does not have to be set in the future, add simple exception in such case
- final Throwable exception = future.getException() == null ?
- new IllegalStateException("Authentication failed") :
- future.getException();
+ final Throwable exception = future.getException() == null
+ ? new IllegalStateException("Authentication failed") : future.getException();
handleSshSetupFailure(ctx, exception);
}
}
private synchronized void handleSshAuthenticated(final ClientSession session, final ChannelHandlerContext ctx) {
try {
- LOG.debug("SSH session authenticated on channel: {}, server version: {}", ctx.channel(), session.getServerVersion());
+ LOG.debug("SSH session authenticated on channel: {}, server version: {}", ctx.channel(),
+ session.getServerVersion());
channel = session.createSubsystemChannel(SUBSYSTEM);
channel.setStreaming(ClientChannel.Streaming.Async);
channel.open().addListener(new SshFutureListener<OpenFuture>() {
@Override
public void operationComplete(final OpenFuture future) {
- if(future.isOpened()) {
+ if (future.isOpened()) {
handleSshChanelOpened(ctx);
} else {
handleSshSetupFailure(ctx, future.getException());
private synchronized void handleSshChanelOpened(final ChannelHandlerContext ctx) {
LOG.trace("SSH subsystem channel opened successfully on channel: {}", ctx.channel());
- if(negotiationFuture == null) {
+ if (negotiationFuture == null) {
connectPromise.setSuccess();
}
}
}, channel.toString(), channel.getAsyncOut());
- // if readAsyncListener receives immediate close, it will close this handler and closing this handler sets channel variable to null
- if(channel != null) {
+ // if readAsyncListener receives immediate close,
+ // it will close this handler and closing this handler sets channel variable to null
+ if (channel != null) {
sshWriteAsyncHandler = new AsyncSshHandlerWriter(channel.getAsyncIn());
ctx.fireChannelActive();
}
}
- private synchronized void handleSshSetupFailure(final ChannelHandlerContext ctx, final Throwable e) {
- LOG.warn("Unable to setup SSH connection on channel: {}", ctx.channel(), e);
+ private synchronized void handleSshSetupFailure(final ChannelHandlerContext ctx, final Throwable error) {
+ LOG.warn("Unable to setup SSH connection on channel: {}", ctx.channel(), error);
// If the promise is not yet done, we have failed with initial connect and set connectPromise to failure
- if(!connectPromise.isDone()) {
- connectPromise.setFailure(e);
+ if (!connectPromise.isDone()) {
+ connectPromise.setFailure(error);
}
disconnect(ctx, ctx.newPromise());
}
@Override
- public synchronized void connect(final ChannelHandlerContext ctx, final SocketAddress remoteAddress, final SocketAddress localAddress, final ChannelPromise promise) throws Exception {
+ public synchronized void connect(final ChannelHandlerContext ctx, final SocketAddress remoteAddress,
+ final SocketAddress localAddress, final ChannelPromise promise) throws Exception {
LOG.debug("SSH session connecting on channel {}. promise: {} ", ctx.channel(), connectPromise);
this.connectPromise = promise;
- if(negotiationFuture != null) {
+ if (negotiationFuture != null) {
negotiationFutureListener = new GenericFutureListener<Future<?>>() {
@Override
disconnect(ctx, promise);
}
+ @SuppressWarnings("checkstyle:IllegalCatch")
@Override
public synchronized void disconnect(final ChannelHandlerContext ctx, final ChannelPromise promise) {
- LOG.trace("Closing SSH session on channel: {} with connect promise in state: {}", ctx.channel(), connectPromise);
+ LOG.trace("Closing SSH session on channel: {} with connect promise in state: {}",
+ ctx.channel(),connectPromise);
- // If we have already succeeded and the session was dropped after, we need to fire inactive to notify reconnect logic
- if(connectPromise.isSuccess()) {
+ // If we have already succeeded and the session was dropped after,
+ // we need to fire inactive to notify reconnect logic
+ if (connectPromise.isSuccess()) {
ctx.fireChannelInactive();
}
- if(sshWriteAsyncHandler != null) {
+ if (sshWriteAsyncHandler != null) {
sshWriteAsyncHandler.close();
}
- if(sshReadAsyncListener != null) {
+ if (sshReadAsyncListener != null) {
sshReadAsyncListener.close();
}
//If connection promise is not already set, it means negotiation failed
//we must set connection promise to failure
- if(!connectPromise.isDone()) {
+ if (!connectPromise.isDone()) {
connectPromise.setFailure(new IllegalStateException("Negotiation failed"));
}
//Remove listener from negotiation future, we don't want notifications
//from negotiation anymore
- if(negotiationFuture != null) {
+ if (negotiationFuture != null) {
negotiationFuture.removeListener(negotiationFutureListener);
}
- if(session!= null && !session.isClosed() && !session.isClosing()) {
+ if (session != null && !session.isClosed() && !session.isClosing()) {
session.close(false).addListener(new SshFutureListener<CloseFuture>() {
@Override
public void operationComplete(final CloseFuture future) {
});
}
- // Super disconnect is necessary in this case since we are using NioSocketChannel and it needs to cleanup its resources
- // e.g. Socket that it tries to open in its constructor (https://bugs.opendaylight.org/show_bug.cgi?id=2430)
- // TODO better solution would be to implement custom ChannelFactory + Channel that will use mina SSH lib internally: port this to custom channel implementation
+ // Super disconnect is necessary in this case since we are using NioSocketChannel and it needs
+ // to cleanup its resources e.g. Socket that it tries to open in its constructor
+ // (https://bugs.opendaylight.org/show_bug.cgi?id=2430)
+ // TODO better solution would be to implement custom ChannelFactory + Channel
+ // that will use mina SSH lib internally: port this to custom channel implementation
try {
// Disconnect has to be closed after inactive channel event was fired, because it interferes with it
super.disconnect(ctx, ctx.newPromise());
private Buffer buf;
private IoReadFuture currentReadFuture;
- public AsyncSshHandlerReader(final AutoCloseable connectionClosedCallback, final ReadMsgHandler readHandler, final String channelId, final IoInputStream asyncOut) {
+ public AsyncSshHandlerReader(final AutoCloseable connectionClosedCallback, final ReadMsgHandler readHandler,
+ final String channelId, final IoInputStream asyncOut) {
this.connectionClosedCallback = connectionClosedCallback;
this.readHandler = readHandler;
this.channelId = channelId;
@Override
public synchronized void operationComplete(final IoReadFuture future) {
- if(future.getException() != null) {
+ if (future.getException() != null) {
//if asyncout is already set to null by close method, do nothing
- if(asyncOut == null) {
+ if (asyncOut == null) {
return;
}
- if(asyncOut.isClosed() || asyncOut.isClosing()) {
+ if (asyncOut.isClosed() || asyncOut.isClosing()) {
// Ssh dropped
LOG.debug("Ssh session dropped on channel: {}", channelId, future.getException());
} else {
if (future.getRead() > 0) {
final ByteBuf msg = Unpooled.wrappedBuffer(buf.array(), 0, future.getRead());
- if(LOG.isTraceEnabled()) {
- LOG.trace("Reading message on channel: {}, message: {}", channelId, AsyncSshHandlerWriter.byteBufToString(msg));
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Reading message on channel: {}, message: {}",
+ channelId, AsyncSshHandlerWriter.byteBufToString(msg));
}
readHandler.onMessageRead(msg);
}
}
+ @SuppressWarnings("checkstyle:IllegalCatch")
private void invokeDisconnect() {
try {
connectionClosedCallback.close();
@Override
public synchronized void close() {
// Remove self as listener on close to prevent reading from closed input
- if(currentReadFuture != null) {
+ if (currentReadFuture != null) {
currentReadFuture.removeListener(this);
currentReadFuture = null;
}
// TODO implement Limiting mechanism for pending writes
// But there is a possible issue with limiting:
// 1. What to do when queue is full ? Immediate Fail for every request ?
- // 2. At this level we might be dealing with Chunks of messages(not whole messages) and unexpected behavior might occur
- // when we send/queue 1 chunk and fail the other chunks
+ // 2. At this level we might be dealing with Chunks of messages(not whole messages)
+ // and unexpected behavior might occur when we send/queue 1 chunk and fail the other chunks
private volatile IoOutputStream asyncIn;
//sending message with pending
//if resending message not succesfull, then attribute wasPending is true
- private void writeWithPendingDetection(final ChannelHandlerContext ctx, final ChannelPromise promise, final ByteBuf byteBufMsg, final boolean wasPending) {
+ private void writeWithPendingDetection(final ChannelHandlerContext ctx, final ChannelPromise promise,
+ final ByteBuf byteBufMsg, final boolean wasPending) {
try {
if (LOG.isTraceEnabled()) {
// while the pending write was in progress from the write callback
synchronized (asyncIn) {
if (LOG.isTraceEnabled()) {
- LOG.trace("Ssh write request finished on channel: {} with result: {}: and ex:{}, message: {}",
- ctx.channel(), future.isWritten(), future.getException(), byteBufToString(byteBufMsg));
+ LOG.trace(
+ "Ssh write request finished on channel: {} with result: {}: and ex:{}, message: {}",
+ ctx.channel(), future.isWritten(), future.getException(), byteBufToString(byteBufMsg));
}
// Notify success or failure
if (future.isWritten()) {
promise.setSuccess();
} else {
- LOG.warn("Ssh write request failed on channel: {} for message: {}", ctx.channel(), byteBufToString(byteBufMsg), future.getException());
+ LOG.warn("Ssh write request failed on channel: {} for message: {}", ctx.channel(),
+ byteBufToString(byteBufMsg), future.getException());
promise.setFailure(future.getException());
}
}
// Check pending queue and schedule next
- // At this time we are guaranteed that we are not in pending state anymore so the next request should succeed
+ // At this time we are guaranteed that we are not in pending state anymore
+ // so the next request should succeed
writePendingIfAny();
}
});
} catch (final WritePendingException e) {
- if(wasPending == false){
+ if (wasPending == false) {
queueRequest(ctx, byteBufMsg, promise);
}
}
final PendingWriteRequest pendingWrite = pending.peek();
final ByteBuf msg = pendingWrite.msg;
if (LOG.isTraceEnabled()) {
- LOG.trace("Writing pending request on channel: {}, message: {}", pendingWrite.ctx.channel(), byteBufToString(msg));
+ LOG.trace("Writing pending request on channel: {}, message: {}",
+ pendingWrite.ctx.channel(), byteBufToString(msg));
}
writeWithPendingDetection(pendingWrite.ctx, pendingWrite.promise, msg, true);
}
new PendingWriteRequest(ctx, msg, promise).pend(pending);
// } catch (final Exception ex) {
-// LOG.warn("Unable to queue write request on channel: {}. Setting fail for the request: {}", ctx.channel(), ex, byteBufToString(msg));
+// LOG.warn("Unable to queue write request on channel: {}. Setting fail for the request: {}",
+// ctx.channel(), ex, byteBufToString(msg));
// msg.release();
// promise.setFailure(ex);
// }
private final ByteBuf msg;
private final ChannelPromise promise;
- public PendingWriteRequest(final ChannelHandlerContext ctx, final ByteBuf msg, final ChannelPromise promise) {
+ PendingWriteRequest(final ChannelHandlerContext ctx, final ByteBuf msg, final ChannelPromise promise) {
this.ctx = ctx;
// Reset reader index, last write (failed) attempt moved index to the end
msg.resetReaderIndex();
// Preconditions.checkState(pending.size() < MAX_PENDING_WRITES,
// "Too much pending writes(%s) on channel: %s, remote window is not getting read or is too small",
// pending.size(), ctx.channel());
- Preconditions.checkState(pending.offer(this), "Cannot pend another request write (pending count: %s) on channel: %s",
- pending.size(), ctx.channel());
+ Preconditions.checkState(pending.offer(this),
+ "Cannot pend another request write (pending count: %s) on channel: %s", pending.size(), ctx.channel());
}
}
}
MockitoAnnotations.initMocks(this);
channel = new EmbeddedChannel();
xmlToHello = new NetconfXMLToHelloMessageDecoder();
- channel.pipeline().addLast(AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER, new ChannelInboundHandlerAdapter());
+ channel.pipeline().addLast(AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER,
+ new ChannelInboundHandlerAdapter());
channel.pipeline().addLast(AbstractChannelInitializer.NETCONF_MESSAGE_DECODER, xmlToHello);
- channel.pipeline().addLast(NETCONF_MESSAGE_FRAME_ENCODER, FramingMechanismHandlerFactory.createHandler(FramingMechanism.EOM));
+ channel.pipeline().addLast(NETCONF_MESSAGE_FRAME_ENCODER,
+ FramingMechanismHandlerFactory.createHandler(FramingMechanism.EOM));
channel.pipeline().addLast(NETCONF_MESSAGE_AGGREGATOR, new NetconfEOMAggregator());
hello = NetconfHelloMessage.createClientHello(Collections.emptySet(), Optional.absent());
- helloBase11 = NetconfHelloMessage.createClientHello(Collections.singleton(XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_1), Optional.absent());
+ helloBase11 = NetconfHelloMessage.createClientHello(Collections
+ .singleton(XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_1), Optional.absent());
prefs = new NetconfSessionPreferences(helloBase11);
doReturn(promise).when(promise).setFailure(any());
doReturn(promise).when(promise).setSuccess(any());
final AbstractNetconfSession session = negotiator.getSessionForHelloMessage(helloBase11);
Assert.assertNotNull(session);
Assert.assertTrue(channel.pipeline().get(NETCONF_MESSAGE_AGGREGATOR) instanceof NetconfChunkAggregator);
- Assert.assertTrue(channel.pipeline().get(NETCONF_MESSAGE_FRAME_ENCODER) instanceof ChunkedFramingMechanismEncoder);
+ Assert.assertTrue(channel.pipeline().get(NETCONF_MESSAGE_FRAME_ENCODER)
+ instanceof ChunkedFramingMechanismEncoder);
}
@Test
@Override
protected TestingNetconfSession getSession(final NetconfSessionListener sessionListener, final Channel channel,
- final NetconfHelloMessage message) throws NetconfDocumentedException {
+ final NetconfHelloMessage message) throws NetconfDocumentedException {
return new TestingNetconfSession(sessionListener, channel, 0L);
}
doNothing().when(listener).onMessage(any(TestingNetconfSession.class), any(NetconfMessage.class));
doNothing().when(listener).onSessionUp(any(TestingNetconfSession.class));
doNothing().when(listener).onSessionDown(any(TestingNetconfSession.class), any(Exception.class));
- doNothing().when(listener).onSessionTerminated(any(TestingNetconfSession.class), any(NetconfTerminationReason.class));
+ doNothing().when(listener).onSessionTerminated(any(TestingNetconfSession.class),
+ any(NetconfTerminationReason.class));
doReturn(writeFuture).when(writeFuture).addListener(any(GenericFutureListener.class));
}
}).when(eventLoop).execute(any(Runnable.class));
- clientHello = NetconfHelloMessage.createClientHello(Collections.<String>emptySet(), Optional.<NetconfHelloMessageAdditionalHeader>absent());
+ clientHello = NetconfHelloMessage.createClientHello(Collections.<String>emptySet(),
+ Optional.<NetconfHelloMessageAdditionalHeader>absent());
}
@Test
doReturn("handler").when(mock).toString();
testingNetconfSession.replaceMessageDecoder(mock);
- verify(pipeline).replace(AbstractChannelInitializer.NETCONF_MESSAGE_DECODER, AbstractChannelInitializer.NETCONF_MESSAGE_DECODER, mock);
+ verify(pipeline).replace(AbstractChannelInitializer.NETCONF_MESSAGE_DECODER,
+ AbstractChannelInitializer.NETCONF_MESSAGE_DECODER, mock);
testingNetconfSession.replaceMessageEncoder(mock);
- verify(pipeline).replace(AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER, AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER, mock);
+ verify(pipeline).replace(AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER,
+ AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER, mock);
testingNetconfSession.replaceMessageEncoderAfterNextMessage(mock);
verifyNoMoreInteractions(pipeline);
testingNetconfSession.sendMessage(clientHello);
- verify(pipeline, times(2)).replace(AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER, AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER, mock);
+ verify(pipeline, times(2)).replace(AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER,
+ AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER, mock);
}
@Test
@Test
public void testSendMessage() throws Exception {
final TestingNetconfSession testingNetconfSession = new TestingNetconfSession(listener, channel, 1L);
- final NetconfHelloMessage clientHello = NetconfHelloMessage.createClientHello(Collections.<String>emptySet(), Optional.<NetconfHelloMessageAdditionalHeader>absent());
+ final NetconfHelloMessage clientHello = NetconfHelloMessage.createClientHello(Collections.<String>emptySet(),
+ Optional.<NetconfHelloMessageAdditionalHeader>absent());
testingNetconfSession.sendMessage(clientHello);
verify(channel).writeAndFlush(clientHello);
}
import org.opendaylight.netconf.api.NetconfMessage;
import org.opendaylight.netconf.api.NetconfSessionListener;
-class TestingNetconfSession extends AbstractNetconfSession<TestingNetconfSession, NetconfSessionListener<TestingNetconfSession>> {
+class TestingNetconfSession
+ extends AbstractNetconfSession<TestingNetconfSession, NetconfSessionListener<TestingNetconfSession>> {
- TestingNetconfSession(final NetconfSessionListener<TestingNetconfSession> sessionListener, final Channel channel, final long sessionId) {
+ TestingNetconfSession(final NetconfSessionListener<TestingNetconfSession> sessionListener,
+ final Channel channel, final long sessionId) {
super(sessionListener, channel, sessionId);
}
}
@Override
- protected void addExiHandlers(final ByteToMessageDecoder decoder, final MessageToByteEncoder<NetconfMessage> encoder) {
+ protected void addExiHandlers(final ByteToMessageDecoder decoder,
+ final MessageToByteEncoder<NetconfMessage> encoder) {
}
@Override
byte[] buf = new byte[destination.readableBytes()];
destination.readBytes(buf);
- String s = StandardCharsets.US_ASCII.decode(ByteBuffer.wrap(buf)).toString();
+ String string = StandardCharsets.US_ASCII.decode(ByteBuffer.wrap(buf)).toString();
- assertTrue(s.startsWith("\n#256\na"));
- assertTrue(s.endsWith("\n#20\naaaaaaaaaaaaaaaaaaaa\n##\n"));
+ assertTrue(string.startsWith("\n#256\na"));
+ assertTrue(string.endsWith("\n#20\naaaaaaaaaaaaaaaaaaaa\n##\n"));
}
private static byte[] getByteArray(final int size) {
public class NetconfChunkAggregatorTest {
- private static final String CHUNKED_MESSAGE = "\n#4\n" +
- "<rpc" +
- "\n#18\n" +
- " message-id=\"102\"\n" +
- "\n#79\n" +
- " xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
- " <close-session/>\n" +
- "</rpc>" +
- "\n##\n";
-
- public static final String EXPECTED_MESSAGE = "<rpc message-id=\"102\"\n" +
- " xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
- " <close-session/>\n" +
- "</rpc>";
+ private static final String CHUNKED_MESSAGE = "\n#4\n"
+ + "<rpc"
+ + "\n#18\n"
+ + " message-id=\"102\"\n"
+ + "\n#79\n"
+ + " xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
+ + " <close-session/>\n"
+ + "</rpc>"
+ + "\n##\n";
+
+ public static final String EXPECTED_MESSAGE = "<rpc message-id=\"102\"\n"
+ + " xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
+ + " <close-session/>\n"
+ + "</rpc>";
private static final String CHUNKED_MESSAGE_ONE = "\n#101\n" + EXPECTED_MESSAGE + "\n##\n";
this.msgAsExi = msgToExi(msgAsString, codec);
}
- private static byte[] msgToExi(final String msgAsString, final NetconfEXICodec codec) throws EXIOptionsException, TransmogrifierException, IOException {
+ private static byte[] msgToExi(final String msgAsString,final NetconfEXICodec codec)
+ throws EXIOptionsException, TransmogrifierException, IOException {
final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
final Transmogrifier transmogrifier = codec.getTransmogrifier();
transmogrifier.setOutputStream(byteArrayOutputStream);
@Test
public void testEncode() throws Exception {
- final NetconfMessage msg = new NetconfHelloMessage(XmlUtil.readXmlToDocument("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>"),
+ final NetconfMessage msg = new NetconfHelloMessage(XmlUtil.readXmlToDocument(
+ "<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>"),
NetconfHelloMessageAdditionalHeader.fromString("[tomas;10.0.0.0:10000;tcp;client;]"));
final ByteBuf destination = Unpooled.buffer();
new NetconfHelloMessageToXMLEncoder().encode(ctx, msg, destination);
@Test
public void testEncodeNoHeader() throws Exception {
- final NetconfMessage msg = new NetconfHelloMessage(XmlUtil.readXmlToDocument("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>"));
+ final NetconfMessage msg = new NetconfHelloMessage(XmlUtil.readXmlToDocument(
+ "<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>"));
final ByteBuf destination = Unpooled.buffer();
new NetconfHelloMessageToXMLEncoder().encode(ctx, msg, destination);
@Test(expected = IllegalStateException.class)
public void testEncodeNotHello() throws Exception {
- final NetconfMessage msg = new NetconfMessage(XmlUtil.readXmlToDocument("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>"));
+ final NetconfMessage msg = new NetconfMessage(XmlUtil.readXmlToDocument(
+ "<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>"));
new NetconfHelloMessageToXMLEncoder().encode(ctx, msg, null);
}
}
\ No newline at end of file
@Test
public void testDecodeWithHeader() throws Exception {
final ByteBuf src = Unpooled.wrappedBuffer(String.format("%s\n%s",
- "[tomas;10.0.0.0:10000;tcp;client;]", "<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>").getBytes());
+ "[tomas;10.0.0.0:10000;tcp;client;]",
+ "<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>").getBytes());
final List<Object> out = Lists.newArrayList();
new NetconfXMLToHelloMessageDecoder().decode(null, src, out);
assertThat(out.get(0), CoreMatchers.instanceOf(NetconfHelloMessage.class));
final NetconfHelloMessage hello = (NetconfHelloMessage) out.get(0);
assertTrue(hello.getAdditionalHeader().isPresent());
- assertEquals("[tomas;10.0.0.0:10000;tcp;client;]" + System.lineSeparator(), hello.getAdditionalHeader().get().toFormattedString());
- assertThat(XmlUtil.toString(hello.getDocument()), CoreMatchers.containsString("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\""));
+ assertEquals("[tomas;10.0.0.0:10000;tcp;client;]" + System.lineSeparator(),
+ hello.getAdditionalHeader().get().toFormattedString());
+ assertThat(XmlUtil.toString(hello.getDocument()),
+ CoreMatchers.containsString("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\""));
}
@Test
public void testDecodeNoHeader() throws Exception {
- final ByteBuf src = Unpooled.wrappedBuffer("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>".getBytes());
+ final ByteBuf src =
+ Unpooled.wrappedBuffer("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>".getBytes());
final List<Object> out = Lists.newArrayList();
new NetconfXMLToHelloMessageDecoder().decode(null, src, out);
@Test
public void testDecodeCaching() throws Exception {
- final ByteBuf msg1 = Unpooled.wrappedBuffer("<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>".getBytes());
- final ByteBuf msg2 = Unpooled.wrappedBuffer("<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>".getBytes());
- final ByteBuf src = Unpooled.wrappedBuffer("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>".getBytes());
+ final ByteBuf msg1 =
+ Unpooled.wrappedBuffer("<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>".getBytes());
+ final ByteBuf msg2 =
+ Unpooled.wrappedBuffer("<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>".getBytes());
+ final ByteBuf src =
+ Unpooled.wrappedBuffer("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>".getBytes());
final List<Object> out = Lists.newArrayList();
final NetconfXMLToHelloMessageDecoder decoder = new NetconfXMLToHelloMessageDecoder();
decoder.decode(null, src, out);
@Test(expected = IllegalStateException.class)
public void testDecodeNotHelloReceived() throws Exception {
- final ByteBuf msg1 = Unpooled.wrappedBuffer("<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>".getBytes());
+ final ByteBuf msg1 =
+ Unpooled.wrappedBuffer("<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>".getBytes());
final List<Object> out = Lists.newArrayList();
NetconfXMLToHelloMessageDecoder decoder = new NetconfXMLToHelloMessageDecoder();
decoder.decode(null, msg1, out);
* A leading LF is the case reported in BUG-2838.
*/
final ArrayList<Object> out = Lists.newArrayList();
- new NetconfXMLToMessageDecoder().decode(null, Unpooled.wrappedBuffer("\n<?xml version=\"1.0\" encoding=\"UTF-8\"?><msg/>".getBytes()), out);
+ new NetconfXMLToMessageDecoder().decode(null,
+ Unpooled.wrappedBuffer("\n<?xml version=\"1.0\" encoding=\"UTF-8\"?><msg/>".getBytes()), out);
assertEquals(1, out.size());
}
* (eg CSR1000V running IOS 15.4(1)S)
*/
final ArrayList<Object> out = Lists.newArrayList();
- new NetconfXMLToMessageDecoder().decode(null, Unpooled.wrappedBuffer("\r\n<?xml version=\"1.0\" encoding=\"UTF-8\"?><msg/>".getBytes()), out);
+ new NetconfXMLToMessageDecoder().decode(null,
+ Unpooled.wrappedBuffer("\r\n<?xml version=\"1.0\" encoding=\"UTF-8\"?><msg/>".getBytes()), out);
assertEquals(1, out.size());
}
- @Test(expected=SAXParseException.class)
+ @Test(expected = SAXParseException.class)
public void testDecodeGibberish() throws Exception {
/* Test that we reject inputs where we cannot find the xml start '<' character */
final ArrayList<Object> out = Lists.newArrayList();
*/
final ArrayList<Object> out = Lists.newArrayList();
- byte whitespaces[] = {' ', '\t', '\n', '\r', '\f', 0x0b /* vertical tab */};
+ byte[] whitespaces = {' ', '\t', '\n', '\r', '\f', 0x0b /* vertical tab */};
new NetconfXMLToMessageDecoder().decode(
null,
Unpooled.copiedBuffer(
@Parameterized.Parameters
public static Iterable<Object[]> data() throws Exception {
final String noChangeXml =
- "<start-exi xmlns=\"urn:ietf:params:xml:ns:netconf:exi:1.0\">\n" +
- "<alignment>bit-packed</alignment>\n" +
- "</start-exi>\n";
+ "<start-exi xmlns=\"urn:ietf:params:xml:ns:netconf:exi:1.0\">\n"
+ + "<alignment>bit-packed</alignment>\n"
+ + "</start-exi>\n";
final String fullOptionsXml =
- "<start-exi xmlns=\"urn:ietf:params:xml:ns:netconf:exi:1.0\">\n" +
- "<alignment>byte-aligned</alignment>\n" +
- "<fidelity>\n" +
- "<comments/>\n" +
- "<dtd/>\n" +
- "<lexical-values/>\n" +
- "<pis/>\n" +
- "<prefixes/>\n" +
- "</fidelity>\n" +
- "</start-exi>\n";
+ "<start-exi xmlns=\"urn:ietf:params:xml:ns:netconf:exi:1.0\">\n"
+ + "<alignment>byte-aligned</alignment>\n"
+ + "<fidelity>\n"
+ + "<comments/>\n"
+ + "<dtd/>\n"
+ + "<lexical-values/>\n"
+ + "<pis/>\n"
+ + "<prefixes/>\n"
+ + "</fidelity>\n"
+ + "</start-exi>\n";
final EXIOptions fullOptions = new EXIOptions();
fullOptions.setAlignmentType(AlignmentType.byteAligned);
@Parameterized.Parameters
public static Iterable<Object[]> data() throws Exception {
- final String noChangeXml = "<rpc xmlns:ns0=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ns0:message-id=\"id\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
- "<start-exi xmlns=\"urn:ietf:params:xml:ns:netconf:exi:1.0\">\n" +
- "<alignment>bit-packed</alignment>\n" +
- "</start-exi>\n" +
- "</rpc>";
+ final String noChangeXml = "<rpc xmlns:ns0=\"urn:ietf:params:xml:ns:netconf:base:1.0\" "
+ + "ns0:message-id=\"id\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
+ + "<start-exi xmlns=\"urn:ietf:params:xml:ns:netconf:exi:1.0\">\n"
+ + "<alignment>bit-packed</alignment>\n"
+ + "</start-exi>\n"
+ + "</rpc>";
- final String fullOptionsXml = "<rpc xmlns:ns0=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ns0:message-id=\"id\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
- "<start-exi xmlns=\"urn:ietf:params:xml:ns:netconf:exi:1.0\">\n" +
- "<alignment>byte-aligned</alignment>\n" +
- "<fidelity>\n" +
- "<comments/>\n" +
- "<dtd/>\n" +
- "<lexical-values/>\n" +
- "<pis/>\n" +
- "<prefixes/>\n" +
- "</fidelity>\n" +
- "</start-exi>\n" +
- "</rpc>";
+ final String fullOptionsXml = "<rpc xmlns:ns0=\"urn:ietf:params:xml:ns:netconf:base:1.0\" "
+ + "ns0:message-id=\"id\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
+ + "<start-exi xmlns=\"urn:ietf:params:xml:ns:netconf:exi:1.0\">\n"
+ + "<alignment>byte-aligned</alignment>\n"
+ + "<fidelity>\n"
+ + "<comments/>\n"
+ + "<dtd/>\n"
+ + "<lexical-values/>\n"
+ + "<pis/>\n"
+ + "<prefixes/>\n"
+ + "</fidelity>\n"
+ + "</start-exi>\n"
+ + "</rpc>";
final EXIOptions fullOptions = new EXIOptions();
fullOptions.setAlignmentType(AlignmentType.byteAligned);
@Override
public void onSuccess(final SshFutureListener<IoReadFuture> result) {
doReturn(new IllegalStateException()).when(mockedReadFuture).getException();
- doReturn(mockedReadFuture).when(mockedReadFuture).removeListener(Matchers.<SshFutureListener<IoReadFuture>>any());
+ doReturn(mockedReadFuture).when(mockedReadFuture)
+ .removeListener(Matchers.<SshFutureListener<IoReadFuture>>any());
doReturn(true).when(asyncOut).isClosing();
doReturn(true).when(asyncOut).isClosed();
result.operationComplete(mockedReadFuture);
@Override
public void onSuccess(final SshFutureListener<IoReadFuture> result) {
doReturn(new IllegalStateException()).when(mockedReadFuture).getException();
- doReturn(mockedReadFuture).when(mockedReadFuture).removeListener(Matchers.<SshFutureListener<IoReadFuture>>any());
+ doReturn(mockedReadFuture).when(mockedReadFuture)
+ .removeListener(Matchers.<SshFutureListener<IoReadFuture>>any());
result.operationComplete(mockedReadFuture);
}
});
final ChannelPromise firstWritePromise = getMockedPromise();
- // intercept listener for first write, so we can invoke successful write later thus simulate pending of the first write
- final ListenableFuture<SshFutureListener<IoWriteFuture>> firstWriteListenerFuture = stubAddListener(ioWriteFuture);
+ // intercept listener for first write,
+ // so we can invoke successful write later thus simulate pending of the first write
+ final ListenableFuture<SshFutureListener<IoWriteFuture>> firstWriteListenerFuture =
+ stubAddListener(ioWriteFuture);
asyncSshHandler.write(ctx, Unpooled.copiedBuffer(new byte[]{0,1,2,3,4,5}), firstWritePromise);
final SshFutureListener<IoWriteFuture> firstWriteListener = firstWriteListenerFuture.get();
- // intercept second listener, this is the listener for pending write for the pending write to know when pending state ended
+ // intercept second listener,
+ // this is the listener for pending write for the pending write to know when pending state ended
final ListenableFuture<SshFutureListener<IoWriteFuture>> pendingListener = stubAddListener(ioWriteFuture);
final ChannelPromise secondWritePromise = getMockedPromise();
final ChannelPromise firstWritePromise = getMockedPromise();
- // intercept listener for first write, so we can invoke successful write later thus simulate pending of the first write
- final ListenableFuture<SshFutureListener<IoWriteFuture>> firstWriteListenerFuture = stubAddListener(ioWriteFuture);
+ // intercept listener for first write,
+ // so we can invoke successful write later thus simulate pending of the first write
+ final ListenableFuture<SshFutureListener<IoWriteFuture>> firstWriteListenerFuture =
+ stubAddListener(ioWriteFuture);
asyncSshHandler.write(ctx, Unpooled.copiedBuffer(new byte[]{0,1,2,3,4,5}), firstWritePromise);
final ChannelPromise secondWritePromise = getMockedPromise();
return sshSession;
}
- private ChannelSubsystem getMockedSubsystemChannel(final IoInputStream asyncOut, final IoOutputStream asyncIn) throws IOException {
+ private ChannelSubsystem getMockedSubsystemChannel(final IoInputStream asyncOut,
+ final IoOutputStream asyncIn) throws IOException {
final ChannelSubsystem subsystemChannel = mock(ChannelSubsystem.class);
doReturn("subsystemChannel").when(subsystemChannel).toString();
return spy(new DefaultChannelPromise(channel));
}
- private static abstract class SuccessFutureListener<T extends SshFuture<T>> implements FutureCallback<SshFutureListener<T>> {
+ private abstract static class SuccessFutureListener<T extends SshFuture<T>>
+ implements FutureCallback<SshFutureListener<T>> {
@Override
- public abstract void onSuccess(final SshFutureListener<T> result);
+ public abstract void onSuccess(SshFutureListener<T> result);
@Override
- public void onFailure(final Throwable t) {
- throw new RuntimeException(t);
+ public void onFailure(final Throwable throwable) {
+ throw new RuntimeException(throwable);
}
}
}
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-maven-plugin</artifactId>
</plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <configuration>
+ <propertyExpansion>checkstyle.violationSeverity=error</propertyExpansion>
+ </configuration>
+ </plugin>
</plugins>
</build>
sshProxyServer = new SshProxyServer(Executors.newScheduledThreadPool(1), workerGroup, eventExecutor);
final InetSocketAddress inetAddress = getInetAddress(bindingAddress, portNumber);
- final SshProxyServerConfigurationBuilder sshProxyServerConfigurationBuilder = new SshProxyServerConfigurationBuilder();
+ final SshProxyServerConfigurationBuilder sshProxyServerConfigurationBuilder =
+ new SshProxyServerConfigurationBuilder();
sshProxyServerConfigurationBuilder.setBindingAddress(inetAddress);
sshProxyServerConfigurationBuilder.setLocalAddress(localAddress);
sshProxyServerConfigurationBuilder.setAuthenticator(authProvider);
private InetSocketAddress getInetAddress(final String bindingAddress, final String portNumber) {
try {
- IpAddress ipAddress= IpAddressBuilder.getDefaultInstance(bindingAddress);
- final InetAddress inetAd = InetAddress.getByName(ipAddress.getIpv4Address() == null ? ipAddress.getIpv6Address().getValue() : ipAddress.getIpv4Address().getValue());
+ IpAddress ipAddress = IpAddressBuilder.getDefaultInstance(bindingAddress);
+ final InetAddress inetAd = InetAddress.getByName(ipAddress.getIpv4Address() == null
+ ? ipAddress.getIpv6Address().getValue() : ipAddress.getIpv4Address().getValue());
return new InetSocketAddress(inetAd, Integer.valueOf(portNumber));
} catch (final UnknownHostException e) {
throw new IllegalArgumentException("Unable to bind netconf endpoint to address " + bindingAddress, e);
* This command handles all netconf related rpc and forwards to delegate server.
* Uses netty to make a local connection to delegate server.
*
+ * <p>
* Command is Apache Mina SSH terminology for objects handling ssh data.
*/
public class RemoteNetconfCommand implements AsyncCommand, SessionAware {
final Bootstrap clientBootstrap = new Bootstrap();
clientBootstrap.group(clientEventGroup).channel(LocalChannel.class);
- clientBootstrap
- .handler(new ChannelInitializer<LocalChannel>() {
- @Override
- public void initChannel(final LocalChannel ch) throws Exception {
- ch.pipeline().addLast(new SshProxyClientHandler(in, out, netconfHelloMessageAdditionalHeader, callback));
- }
- });
+ clientBootstrap.handler(new ChannelInitializer<LocalChannel>() {
+ @Override
+ public void initChannel(final LocalChannel ch) throws Exception {
+ ch.pipeline()
+ .addLast(new SshProxyClientHandler(in, out, netconfHelloMessageAdditionalHeader, callback));
+ }
+ });
clientChannelFuture = clientBootstrap.connect(localAddress);
clientChannelFuture.addListener(new GenericFutureListener<ChannelFuture>() {
@Override
public void operationComplete(final ChannelFuture future) throws Exception {
- if(future.isSuccess()) {
+ if (future.isSuccess()) {
clientChannel = clientChannelFuture.channel();
} else {
- LOG.warn("Unable to establish internal connection to netconf server for client: {}", getClientAddress());
+ LOG.warn("Unable to establish internal connection to netconf server for client: {}",
+ getClientAddress());
Preconditions.checkNotNull(callback, "Exit callback must be set");
- callback.onExit(1, "Unable to establish internal connection to netconf server for client: "+ getClientAddress());
+ callback.onExit(1, "Unable to establish internal connection to netconf server for client: "
+ + getClientAddress());
}
}
});
getClientAddress(), clientChannel);
clientChannelFuture.cancel(true);
- if(clientChannel != null) {
+ if (clientChannel != null) {
clientChannel.close().addListener(new GenericFutureListener<ChannelFuture>() {
@Override
public void operationComplete(final ChannelFuture future) throws Exception {
if (future.isSuccess() == false) {
- LOG.warn("Unable to release internal connection to netconf server on channel: {}", clientChannel);
+ LOG.warn("Unable to release internal connection to netconf server on channel: {}",
+ clientChannel);
}
}
});
final SocketAddress remoteAddress = session.getIoSession().getRemoteAddress();
String hostName = "";
String port = "";
- if(remoteAddress instanceof InetSocketAddress) {
+ if (remoteAddress instanceof InetSocketAddress) {
hostName = ((InetSocketAddress) remoteAddress).getAddress().getHostAddress();
port = Integer.toString(((InetSocketAddress) remoteAddress).getPort());
}
import org.slf4j.LoggerFactory;
/**
- * Netty handler that reads SSH from remote client and writes to delegate server and reads from delegate server and writes to remote client
+ * Netty handler that reads SSH from remote client and writes to delegate server
+ * and reads from delegate server and writes to remote client.
*/
final class SshProxyClientHandler extends ChannelInboundHandlerAdapter {
private final NetconfHelloMessageAdditionalHeader netconfHelloMessageAdditionalHeader;
private final ExitCallback callback;
- public SshProxyClientHandler(final IoInputStream in, final IoOutputStream out,
- final NetconfHelloMessageAdditionalHeader netconfHelloMessageAdditionalHeader,
- final ExitCallback callback) {
+ SshProxyClientHandler(final IoInputStream in, final IoOutputStream out,
+ final NetconfHelloMessageAdditionalHeader netconfHelloMessageAdditionalHeader,
+ final ExitCallback callback) {
this.in = in;
this.out = out;
this.netconfHelloMessageAdditionalHeader = netconfHelloMessageAdditionalHeader;
}, new AsyncSshHandlerReader.ReadMsgHandler() {
@Override
public void onMessageRead(final ByteBuf msg) {
- if(LOG.isTraceEnabled()) {
+ if (LOG.isTraceEnabled()) {
LOG.trace("Forwarding message for client: {} on channel: {}, message: {}",
- netconfHelloMessageAdditionalHeader.getAddress(), ctx.channel(), AsyncSshHandlerWriter.byteBufToString(msg));
+ netconfHelloMessageAdditionalHeader.getAddress(), ctx.channel(),
+ AsyncSshHandlerWriter.byteBufToString(msg));
}
// Just forward to delegate
ctx.writeAndFlush(msg);
public void channelInactive(final ChannelHandlerContext ctx) throws Exception {
LOG.debug("Internal connection to netconf server was dropped for client: {} on channel: ",
netconfHelloMessageAdditionalHeader.getAddress(), ctx.channel());
- callback.onExit(1, "Internal connection to netconf server was dropped for client: " +
- netconfHelloMessageAdditionalHeader.getAddress() + " on channel: " + ctx.channel());
+ callback.onExit(1, "Internal connection to netconf server was dropped for client: "
+ + netconfHelloMessageAdditionalHeader.getAddress() + " on channel: " + ctx.channel());
super.channelInactive(ctx);
}
private final EventLoopGroup clientGroup;
private final IoServiceFactoryFactory nioServiceWithPoolFactoryFactory;
- public SshProxyServer(final ScheduledExecutorService minaTimerExecutor, final EventLoopGroup clientGroup, final ExecutorService nioExecutor) {
+ public SshProxyServer(final ScheduledExecutorService minaTimerExecutor,
+ final EventLoopGroup clientGroup, final ExecutorService nioExecutor) {
this.minaTimerExecutor = minaTimerExecutor;
this.clientGroup = clientGroup;
- this.nioServiceWithPoolFactoryFactory = new NioServiceWithPoolFactory.NioServiceWithPoolFactoryFactory(nioExecutor);
+ this.nioServiceWithPoolFactoryFactory =
+ new NioServiceWithPoolFactory.NioServiceWithPoolFactoryFactory(nioExecutor);
this.sshServer = SshServer.setUpDefaultServer();
}
sshServer.setProperties(getProperties(sshProxyServerConfiguration));
final RemoteNetconfCommand.NetconfCommandFactory netconfCommandFactory =
- new RemoteNetconfCommand.NetconfCommandFactory(clientGroup, sshProxyServerConfiguration.getLocalAddress());
+ new RemoteNetconfCommand.NetconfCommandFactory(clientGroup,
+ sshProxyServerConfiguration.getLocalAddress());
sshServer.setSubsystemFactories(ImmutableList.of(netconfCommandFactory));
sshServer.start();
}
}
/**
- * Based on Nio2ServiceFactory with one addition: injectable executor
+ * Based on Nio2ServiceFactory with one addition: injectable executor.
*/
- private static final class NioServiceWithPoolFactory extends CloseableUtils.AbstractCloseable implements IoServiceFactory {
+ private static final class NioServiceWithPoolFactory
+ extends CloseableUtils.AbstractCloseable implements IoServiceFactory {
private final FactoryManager manager;
private final AsynchronousChannelGroup group;
- public NioServiceWithPoolFactory(final FactoryManager manager, final ExecutorService executor) {
+ NioServiceWithPoolFactory(final FactoryManager manager, final ExecutorService executor) {
this.manager = manager;
try {
group = AsynchronousChannelGroup.withThreadPool(executor);
return new Nio2Acceptor(manager, handler, group);
}
+ @SuppressWarnings("checkstyle:IllegalCatch")
@Override
protected void doCloseImmediately() {
try {
private final KeyPairProvider keyPairProvider;
private final int idleTimeout;
- SshProxyServerConfiguration(final InetSocketAddress bindingAddress, final LocalAddress localAddress, final AuthProvider authenticator, final KeyPairProvider keyPairProvider, final int idleTimeout) {
+ SshProxyServerConfiguration(final InetSocketAddress bindingAddress, final LocalAddress localAddress,
+ final AuthProvider authenticator, final KeyPairProvider keyPairProvider, final int idleTimeout) {
this.bindingAddress = Preconditions.checkNotNull(bindingAddress);
this.localAddress = Preconditions.checkNotNull(localAddress);
this.authenticator = Preconditions.checkNotNull(authenticator);
}
public SshProxyServerConfiguration createSshProxyServerConfiguration() {
- return new SshProxyServerConfiguration(bindingAddress, localAddress, authenticator, keyPairProvider, idleTimeout);
+ return new SshProxyServerConfiguration(bindingAddress, localAddress, authenticator,
+ keyPairProvider, idleTimeout);
}
public static SshProxyServerConfigurationBuilder create() {
private final ServiceTracker<AuthProvider, AuthProvider> listenerTracker;
private volatile AuthProvider authProvider;
- public AuthProviderTracker(final BundleContext bundleContext) {
+ AuthProviderTracker(final BundleContext bundleContext) {
this.bundleContext = bundleContext;
listenerTracker = new ServiceTracker<>(bundleContext, AuthProvider.class, this);
listenerTracker.open();
public void start(final BundleContext bundleContext) throws IOException, InvalidSyntaxException {
minaTimerExecutor = Executors.newScheduledThreadPool(POOL_SIZE, new ThreadFactory() {
@Override
- public Thread newThread(final Runnable r) {
- return new Thread(r, "netconf-ssh-server-mina-timers");
+ public Thread newThread(final Runnable runnable) {
+ return new Thread(runnable, "netconf-ssh-server-mina-timers");
}
});
clientGroup = new NioEventLoopGroup();
server.close();
}
- if(authProviderTracker != null) {
+ if (authProviderTracker != null) {
authProviderTracker.stop();
}
- if(nioExecutor!=null) {
+ if (nioExecutor != null) {
nioExecutor.shutdownNow();
}
- if(clientGroup != null) {
+ if (clientGroup != null) {
clientGroup.shutdownGracefully();
}
- if(minaTimerExecutor != null) {
+ if (minaTimerExecutor != null) {
minaTimerExecutor.shutdownNow();
}
}
this.channelInitializer = channelInitializer;
}
+ @SuppressWarnings("checkstyle:IllegalCatch")
@Override
public void run() {
// Configure the client.
EventLoopGroup group = new NioEventLoopGroup();
try {
- Bootstrap b = new Bootstrap();
+ Bootstrap bootstrap = new Bootstrap();
- b.group(group)
+ bootstrap.group(group)
.channel(LocalChannel.class)
.handler(channelInitializer);
// Start the client.
LocalAddress localAddress = new LocalAddress("foo");
- ChannelFuture f = b.connect(localAddress).sync();
+ ChannelFuture future = bootstrap.connect(localAddress).sync();
// Wait until the connection is closed.
- f.channel().closeFuture().sync();
+ future.channel().closeFuture().sync();
} catch (Exception e) {
LOG.error("Error in client", e);
throw new RuntimeException("Error in client", e);
private ChannelHandlerContext ctx;
private final StringBuilder fromServer = new StringBuilder();
- public static enum State {CONNECTING, CONNECTED, FAILED_TO_CONNECT, CONNECTION_CLOSED}
+ public enum State {
+ CONNECTING, CONNECTED, FAILED_TO_CONNECT, CONNECTION_CLOSED
+ }
private State state = State.CONNECTING;
public class EchoServer implements Runnable {
private static final Logger LOG = LoggerFactory.getLogger(EchoServer.class);
+ @SuppressWarnings("checkstyle:IllegalCatch")
public void run() {
// Configure the server.
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
- ServerBootstrap b = new ServerBootstrap();
- b.group(bossGroup, workerGroup)
+ ServerBootstrap bootstrap = new ServerBootstrap();
+ bootstrap.group(bossGroup, workerGroup)
.channel(LocalServerChannel.class)
.option(ChannelOption.SO_BACKLOG, 100)
.handler(new LoggingHandler(LogLevel.INFO))
// Start the server.
LocalAddress localAddress = NetconfConfiguration.NETCONF_LOCAL_ADDRESS;
- ChannelFuture f = b.bind(localAddress).sync();
+ ChannelFuture future = bootstrap.bind(localAddress).sync();
// Wait until the server socket is closed.
- f.channel().closeFuture().sync();
+ future.channel().closeFuture().sync();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
private static final Logger LOG = LoggerFactory.getLogger(EchoServerHandler.class);
private String fromLastNewLine = "";
private final Splitter splitter = Splitter.onPattern("\r?\n");
+
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
LOG.debug("sleep start");
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.netconf.netty;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import java.nio.charset.StandardCharsets;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class ProxyClientHandler extends ChannelInboundHandlerAdapter {
+ private static final Logger LOG = LoggerFactory.getLogger(ProxyClientHandler.class);
+
+ private final ChannelHandlerContext remoteCtx;
+
+
+ ProxyClientHandler(ChannelHandlerContext remoteCtx) {
+ this.remoteCtx = remoteCtx;
+ }
+
+ @Override
+ public void channelActive(ChannelHandlerContext ctx) {
+ LOG.info("client active");
+ }
+
+ @Override
+ public void channelRead(ChannelHandlerContext ctx, Object msg) {
+ ByteBuf bb = (ByteBuf) msg;
+ LOG.info(">{}", bb.toString(StandardCharsets.UTF_8));
+ remoteCtx.write(msg);
+ }
+
+ @Override
+ public void channelReadComplete(ChannelHandlerContext ctx) {
+ LOG.debug("Flushing server ctx");
+ remoteCtx.flush();
+ }
+
+ @Override
+ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
+ // Close the connection when an exception is raised.
+ LOG.warn("Unexpected exception from downstream", cause);
+ ctx.close();
+ }
+
+ // called both when local or remote connection dies
+ @Override
+ public void channelInactive(ChannelHandlerContext ctx) {
+ LOG.debug("channelInactive() called, closing remote client ctx");
+ remoteCtx.close();
+ }
+}
this.proxyHandlerFactory = proxyHandlerFactory;
}
+ @SuppressWarnings("checkstyle:IllegalCatch")
public void run() {
// Configure the server.
final EventLoopGroup bossGroup = new NioEventLoopGroup();
// Start the server.
InetSocketAddress address = new InetSocketAddress("127.0.0.1", 8080);
- ChannelFuture f = serverBootstrap.bind(address).sync();
+ ChannelFuture future = serverBootstrap.bind(address).sync();
// Wait until the server socket is closed.
- f.channel().closeFuture().sync();
+ future.channel().closeFuture().sync();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
workerGroup.shutdownGracefully();
}
}
- public static interface ProxyHandlerFactory {
+
+ public interface ProxyHandlerFactory {
ChannelHandler create(EventLoopGroup bossGroup, LocalAddress localAddress);
}
package org.opendaylight.netconf.netty;
import io.netty.bootstrap.Bootstrap;
-import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.local.LocalAddress;
import io.netty.channel.local.LocalChannel;
-import java.nio.charset.StandardCharsets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
}
}
-class ProxyClientHandler extends ChannelInboundHandlerAdapter {
- private static final Logger LOG = LoggerFactory.getLogger(ProxyClientHandler.class);
-
- private final ChannelHandlerContext remoteCtx;
-
-
- public ProxyClientHandler(ChannelHandlerContext remoteCtx) {
- this.remoteCtx = remoteCtx;
- }
-
- @Override
- public void channelActive(ChannelHandlerContext ctx) {
- LOG.info("client active");
- }
-
- @Override
- public void channelRead(ChannelHandlerContext ctx, Object msg) {
- ByteBuf bb = (ByteBuf) msg;
- LOG.info(">{}", bb.toString(StandardCharsets.UTF_8));
- remoteCtx.write(msg);
- }
-
- @Override
- public void channelReadComplete(ChannelHandlerContext ctx) {
- LOG.debug("Flushing server ctx");
- remoteCtx.flush();
- }
-
- @Override
- public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
- // Close the connection when an exception is raised.
- LOG.warn("Unexpected exception from downstream", cause);
- ctx.close();
- }
-
- // called both when local or remote connection dies
- @Override
- public void channelInactive(ChannelHandlerContext ctx) {
- LOG.debug("channelInactive() called, closing remote client ctx");
- remoteCtx.close();
- }
-}
final InetSocketAddress addr = new InetSocketAddress("127.0.0.1", 10831);
final SshProxyServer sshProxyServer = new SshProxyServer(minaTimerEx, nettyGroup, nioExec);
- sshProxyServer.bind(
- new SshProxyServerConfigurationBuilder().setBindingAddress(addr).setLocalAddress(NetconfConfiguration.NETCONF_LOCAL_ADDRESS).setAuthenticator(new AuthProvider() {
- @Override
- public boolean authenticated(final String username, final String password) {
- return true;
- }
- }).setKeyPairProvider(new PEMGeneratorHostKeyProvider(sshKeyPair.toPath().toAbsolutePath().toString())).setIdleTimeout(Integer.MAX_VALUE).createSshProxyServerConfiguration());
+ sshProxyServer.bind(new SshProxyServerConfigurationBuilder()
+ .setBindingAddress(addr).setLocalAddress(NetconfConfiguration.NETCONF_LOCAL_ADDRESS)
+ .setAuthenticator(new AuthProvider() {
+ @Override
+ public boolean authenticated(final String username, final String password) {
+ return true;
+ }
+ })
+ .setKeyPairProvider(new PEMGeneratorHostKeyProvider(sshKeyPair.toPath().toAbsolutePath().toString()))
+ .setIdleTimeout(Integer.MAX_VALUE).createSshProxyServerConfiguration());
final EchoClientHandler echoClientHandler = connectClient(addr);
Stopwatch stopwatch = Stopwatch.createStarted();
- while(echoClientHandler.isConnected() == false && stopwatch.elapsed(TimeUnit.SECONDS) < 30) {
+ while (echoClientHandler.isConnected() == false && stopwatch.elapsed(TimeUnit.SECONDS) < 30) {
Thread.sleep(500);
}
assertTrue(echoClientHandler.isConnected());
final InetSocketAddress address = new InetSocketAddress(12345);
final EchoClientHandler echoClientHandler = connectClient(address);
final Stopwatch stopwatch = Stopwatch.createStarted();
- while(echoClientHandler.getState() == State.CONNECTING && stopwatch.elapsed(TimeUnit.SECONDS) < 5) {
+ while (echoClientHandler.getState() == State.CONNECTING && stopwatch.elapsed(TimeUnit.SECONDS) < 5) {
Thread.sleep(100);
}
assertFalse(echoClientHandler.isConnected());
final InetSocketAddress addr = InetSocketAddress.createUnresolved(HOST, PORT);
server = new SshProxyServer(minaTimerEx, clientGroup, nioExec);
- server.bind(
- new SshProxyServerConfigurationBuilder().setBindingAddress(addr).setLocalAddress(NetconfConfiguration.NETCONF_LOCAL_ADDRESS).setAuthenticator(new AuthProvider() {
+ server.bind(new SshProxyServerConfigurationBuilder()
+ .setBindingAddress(addr).setLocalAddress(NetconfConfiguration.NETCONF_LOCAL_ADDRESS)
+ .setAuthenticator(new AuthProvider() {
@Override
public boolean authenticated(final String username, final String password) {
return true;
}
- }).setKeyPairProvider(new PEMGeneratorHostKeyProvider(sshKeyPair.toPath().toAbsolutePath().toString())).setIdleTimeout(Integer.MAX_VALUE).createSshProxyServerConfiguration());
+ })
+ .setKeyPairProvider(new PEMGeneratorHostKeyProvider(sshKeyPair.toPath().toAbsolutePath().toString()))
+ .setIdleTimeout(Integer.MAX_VALUE).createSshProxyServerConfiguration());
LOG.info("SSH server started on {}", PORT);
}
import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologySetup.NetconfTopologySetupBuilder;
import org.opendaylight.netconf.topology.singleton.impl.utils.NetconfTopologyUtils;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.topology.singleton.config.rev170419.Config;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopologyBuilder;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
final ClusterSingletonServiceProvider clusterSingletonServiceProvider,
final BindingAwareBroker bindingAwareBroker,
final ScheduledThreadPool keepaliveExecutor, final ThreadPool processingExecutor,
- final Broker domBroker, final ActorSystemProvider actorSystemProvider, final EventExecutor eventExecutor,
- final NetconfClientDispatcher clientDispatcher, final String topologyId,
- final int writeTxIdleTimeout) {
+ final Broker domBroker, final ActorSystemProvider actorSystemProvider,
+ final EventExecutor eventExecutor, final NetconfClientDispatcher clientDispatcher,
+ final String topologyId, final Config config) {
this.dataBroker = Preconditions.checkNotNull(dataBroker);
this.rpcProviderRegistry = Preconditions.checkNotNull(rpcProviderRegistry);
this.clusterSingletonServiceProvider = Preconditions.checkNotNull(clusterSingletonServiceProvider);
this.eventExecutor = Preconditions.checkNotNull(eventExecutor);
this.clientDispatcher = Preconditions.checkNotNull(clientDispatcher);
this.topologyId = Preconditions.checkNotNull(topologyId);
- this.writeTxIdleTimeout = Duration.apply(writeTxIdleTimeout, TimeUnit.SECONDS);
+ this.writeTxIdleTimeout = Duration.apply(config.getWriteTransactionIdleTimeout(), TimeUnit.SECONDS);
}
// Blueprint init method
<reference id="clientDispatcherDependency"
interface="org.opendaylight.netconf.client.NetconfClientDispatcher"
odl:type="netconf-client-dispatcher"/>
+ <odl:clustered-app-config
+ id="singletonConfig"
+ binding-class="org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.topology.singleton.config.rev170419.Config"
+ />
<bean id="netconfTopologyManager"
class="org.opendaylight.netconf.topology.singleton.impl.NetconfTopologyManager"
<argument ref="eventExecutor"/>
<argument ref="clientDispatcherDependency"/>
<argument value="topology-netconf"/>
- <argument value="0"/>
+ <argument ref="singletonConfig"/>
</bean>
<service ref="netconfTopologyManager"
interface="org.opendaylight.netconf.topology.singleton.api.NetconfTopologySingletonService"/>
--- /dev/null
+module netconf-clustered-topology-config {
+ yang-version 1;
+ namespace "urn:opendaylight:netconf:topology:singleton:config";
+ prefix nctc;
+
+ description
+ "Configuration for Netconf Clustered Topology";
+
+ revision "2017-04-19" {
+ description
+ "Initial revision.";
+ }
+
+ container config {
+ leaf write-transaction-idle-timeout {
+ type uint16;
+ default 0;
+ description "Idle time in seconds after which write transaction is cancelled
+ automatically. If 0, automatic cancellation is turned off.";
+ }
+ }
+}
\ No newline at end of file
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.topology.singleton.config.rev170419.Config;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.topology.singleton.config.rev170419.ConfigBuilder;
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;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
final EventExecutor eventExecutor = mock(EventExecutor.class);
final NetconfClientDispatcher clientDispatcher = mock(NetconfClientDispatcher.class);
+ final Config config = new ConfigBuilder().setWriteTransactionIdleTimeout(0).build();
netconfTopologyManager = new NetconfTopologyManager(dataBroker, rpcProviderRegistry,
clusterSingletonServiceProvider, bindingAwareBroker, keepaliveExecutor, processingExecutor, domBroker,
- actorSystemProvider, eventExecutor, clientDispatcher, topologyId, 0);
+ actorSystemProvider, eventExecutor, clientDispatcher, topologyId, config);
}
@Test
</execution>
</executions>
</plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <configuration>
+ <propertyExpansion>checkstyle.violationSeverity=error</propertyExpansion>
+ </configuration>
+ </plugin>
</plugins>
</build>
public class CloseableUtil {
+ @SuppressWarnings("checkstyle:IllegalCatch")
public static void closeAll(Iterable<? extends AutoCloseable> autoCloseables) throws Exception {
Exception lastException = null;
for (AutoCloseable autoCloseable : autoCloseables) {
+ XmlUtil.toString(response));
}
- public static void writeNormalizedNode(final NormalizedNode<?, ?> normalized, final DOMResult result, final SchemaPath schemaPath, final SchemaContext context)
+ @SuppressWarnings("checkstyle:IllegalCatch")
+ public static void writeNormalizedNode(final NormalizedNode<?, ?> normalized, final DOMResult result,
+ final SchemaPath schemaPath, final SchemaContext context)
throws IOException, XMLStreamException {
final XMLStreamWriter writer = XML_FACTORY.createXMLStreamWriter(result);
try (
- final NormalizedNodeStreamWriter normalizedNodeStreamWriter = XMLStreamNormalizedNodeStreamWriter.create(writer, context, schemaPath);
- final NormalizedNodeWriter normalizedNodeWriter = NormalizedNodeWriter.forStreamWriter(normalizedNodeStreamWriter)
+ NormalizedNodeStreamWriter normalizedNodeStreamWriter =
+ XMLStreamNormalizedNodeStreamWriter.create(writer, context, schemaPath);
+ NormalizedNodeWriter normalizedNodeWriter =
+ NormalizedNodeWriter.forStreamWriter(normalizedNodeStreamWriter)
) {
normalizedNodeWriter.write(normalized);
normalizedNodeWriter.flush();
} finally {
try {
- if(writer != null) {
+ if (writer != null) {
writer.close();
}
} catch (final Exception e) {
@Override
protected Element handle(final Document document, final XmlElement operationElement,
final NetconfOperationChainedExecution subsequentOperation) throws DocumentedException {
- if (!subsequentOperation.isExecutionTermination()){
- throw new DocumentedException(String.format("No netconf operation expected to be subsequent to %s, but is %s", this, subsequentOperation),
+ if (!subsequentOperation.isExecutionTermination()) {
+ throw new DocumentedException(String.format(
+ "No netconf operation expected to be subsequent to %s, but is %s", this, subsequentOperation),
DocumentedException.ErrorType.APPLICATION,
DocumentedException.ErrorTag.MALFORMED_MESSAGE,
DocumentedException.ErrorSeverity.ERROR);
return HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY;
}
- protected abstract Element handleWithNoSubsequentOperations(Document document, XmlElement operationElement) throws DocumentedException;
+ protected abstract Element handleWithNoSubsequentOperations(Document document,
+ XmlElement operationElement) throws DocumentedException;
}
return canHandle(operationNameAndNamespace.getOperationName(), operationNameAndNamespace.getNamespace());
}
+ protected HandlingPriority canHandle(final String operationName, final String operationNamespace) {
+ return operationName.equals(getOperationName()) && operationNamespace.equals(getOperationNamespace())
+ ? getHandlingPriority()
+ : HandlingPriority.CANNOT_HANDLE;
+ }
+
public static final class OperationNameAndNamespace {
- private final String operationName, namespace;
+ private final String operationName;
+ private final String namespace;
+
private final XmlElement operationElement;
public OperationNameAndNamespace(final Document message) throws DocumentedException {
public XmlElement getOperationElement() {
return operationElement;
}
+
}
protected static XmlElement getRequestElementWithCheck(final Document message) throws DocumentedException {
XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
}
- protected HandlingPriority canHandle(final String operationName, final String operationNamespace) {
- return operationName.equals(getOperationName()) && operationNamespace.equals(getOperationNamespace())
- ? getHandlingPriority()
- : HandlingPriority.CANNOT_HANDLE;
- }
-
protected HandlingPriority getHandlingPriority() {
return HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY;
}
Map<String, Attr> attributes = requestElement.getAttributes();
Element response = handle(document, operationElement, subsequentOperation);
- Element rpcReply = XmlUtil.createElement(document, XmlMappingConstants.RPC_REPLY_KEY, Optional.of(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0));
+ Element rpcReply = XmlUtil.createElement(document, XmlMappingConstants.RPC_REPLY_KEY,
+ Optional.of(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0));
- if(XmlElement.fromDomElement(response).hasNamespace()) {
+ if (XmlElement.fromDomElement(response).hasNamespace()) {
rpcReply.appendChild(response);
} else {
- Element responseNS = XmlUtil.createElement(document, response.getNodeName(), Optional.of(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0));
+ Element responseNS = XmlUtil.createElement(document, response.getNodeName(),
+ Optional.of(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0));
NodeList list = response.getChildNodes();
- while(list.getLength()!=0) {
+ while (list.getLength() != 0) {
responseNS.appendChild(list.item(0));
}
rpcReply.appendChild(responseNS);
return document;
}
- protected abstract Element handle(Document document, XmlElement message, NetconfOperationChainedExecution subsequentOperation)
+ protected abstract Element handle(Document document, XmlElement message,
+ NetconfOperationChainedExecution subsequentOperation)
throws DocumentedException;
@Override
final StringBuffer sb = new StringBuffer(getClass().getName());
try {
sb.append("{name=").append(getOperationName());
- } catch(UnsupportedOperationException e) {
+ } catch (UnsupportedOperationException e) {
// no problem
}
sb.append(", namespace=").append(getOperationNamespace());
*/
public enum FramingMechanism {
/**
+ * Chunked framing mechanism.
+ *
* @see <a href="http://tools.ietf.org/html/rfc6242#section-4.2">Chunked
* framing mechanism</a>
*/
CHUNK,
/**
+ * End-of-Message framing mechanism.
+ *
* @see <a
* href="http://tools.ietf.org/html/rfc6242#section-4.3">End-of-message
* framing mechanism</a>
}
public static boolean isOKMessage(XmlElement xmlElement) throws NetconfDocumentedException {
- if(xmlElement.getChildElements().size() != 1) {
+ if (xmlElement.getChildElements().size() != 1) {
return false;
}
try {
}
public static boolean isErrorMessage(XmlElement xmlElement) throws NetconfDocumentedException {
- if(xmlElement.getChildElements().size() != 1) {
+ if (xmlElement.getChildElements().size() != 1) {
return false;
}
try {
final DocumentedException sendErrorException) {
LOG.trace("Sending error {}", sendErrorException.getMessage(), sendErrorException);
final Document errorDocument = createDocument(sendErrorException);
- ChannelFuture f = session.sendMessage(new NetconfMessage(errorDocument));
- f.addListener(new SendErrorVerifyingListener(sendErrorException));
+ ChannelFuture channelFuture = session.sendMessage(new NetconfMessage(errorDocument));
+ channelFuture.addListener(new SendErrorVerifyingListener(sendErrorException));
}
public static void sendErrorMessage(final Channel channel, final DocumentedException sendErrorException) {
LOG.trace("Sending error {}", sendErrorException.getMessage(), sendErrorException);
final Document errorDocument = createDocument(sendErrorException);
- ChannelFuture f = channel.writeAndFlush(new NetconfMessage(errorDocument));
- f.addListener(new SendErrorVerifyingListener(sendErrorException));
+ ChannelFuture channelFuture = channel.writeAndFlush(new NetconfMessage(errorDocument));
+ channelFuture.addListener(new SendErrorVerifyingListener(sendErrorException));
}
public static void sendErrorMessage(final NetconfSession session, final DocumentedException sendErrorException,
}
tryToCopyAttributes(incommingMessage.getDocument(), errorDocument, sendErrorException);
- ChannelFuture f = session.sendMessage(new NetconfMessage(errorDocument));
- f.addListener(new SendErrorVerifyingListener(sendErrorException));
+ ChannelFuture channelFuture = session.sendMessage(new NetconfMessage(errorDocument));
+ channelFuture.addListener(new SendErrorVerifyingListener(sendErrorException));
}
+ @SuppressWarnings("checkstyle:IllegalCatch")
private static void tryToCopyAttributes(final Document incommingDocument, final Document errorDocument,
final DocumentedException sendErrorException) {
try {
final Element incommingRpc = incommingDocument.getDocumentElement();
- Preconditions.checkState(incommingRpc.getTagName().equals(XmlNetconfConstants.RPC_KEY), "Missing %s element",
- XmlNetconfConstants.RPC_KEY);
+ Preconditions.checkState(incommingRpc.getTagName().equals(XmlNetconfConstants.RPC_KEY),
+ "Missing %s element", XmlNetconfConstants.RPC_KEY);
final Element rpcReply = errorDocument.getDocumentElement();
- Preconditions.checkState(rpcReply.getTagName().equals(XmlMappingConstants.RPC_REPLY_KEY), "Missing %s element",
- XmlMappingConstants.RPC_REPLY_KEY);
+ Preconditions.checkState(rpcReply.getTagName().equals(XmlMappingConstants.RPC_REPLY_KEY),
+ "Missing %s element", XmlMappingConstants.RPC_REPLY_KEY);
final NamedNodeMap incomingAttributes = incommingRpc.getAttributes();
for (int i = 0; i < incomingAttributes.getLength(); i++) {
private static final class SendErrorVerifyingListener implements ChannelFutureListener {
private final DocumentedException sendErrorException;
- public SendErrorVerifyingListener(final DocumentedException sendErrorException) {
+ SendErrorVerifyingListener(final DocumentedException sendErrorException) {
this.sendErrorException = sendErrorException;
}
public class SubtreeFilter {
private static final Logger LOG = LoggerFactory.getLogger(SubtreeFilter.class);
- public static Document applyRpcSubtreeFilter(Document requestDocument, Document rpcReply) throws DocumentedException {
+ public static Document applyRpcSubtreeFilter(Document requestDocument,
+ Document rpcReply) throws DocumentedException {
OperationNameAndNamespace operationNameAndNamespace = new OperationNameAndNamespace(requestDocument);
- if (XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0.equals(operationNameAndNamespace.getNamespace()) &&
- XmlNetconfConstants.GET.equals(operationNameAndNamespace.getOperationName()) ||
- XmlNetconfConstants.GET_CONFIG.equals(operationNameAndNamespace.getOperationName())) {
+ if (XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0.equals(operationNameAndNamespace.getNamespace())
+ && XmlNetconfConstants.GET.equals(operationNameAndNamespace.getOperationName())
+ || XmlNetconfConstants.GET_CONFIG.equals(operationNameAndNamespace.getOperationName())) {
// process subtree filtering here, in case registered netconf operations do
// not implement filtering.
- Optional<XmlElement> maybeFilter = operationNameAndNamespace.getOperationElement().getOnlyChildElementOptionally(
- XmlNetconfConstants.FILTER, XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
+ Optional<XmlElement> maybeFilter = operationNameAndNamespace.getOperationElement()
+ .getOnlyChildElementOptionally(XmlNetconfConstants.FILTER,
+ XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
if (!maybeFilter.isPresent()) {
return rpcReply;
}
* @param filter filter
* @param notification notification
* @return document containing filtered notification content
- * @throws DocumentedException
+ * @throws DocumentedException if operation fails
*/
- public static Optional<Document> applySubtreeNotificationFilter(XmlElement filter, Document notification) throws DocumentedException {
+ public static Optional<Document> applySubtreeNotificationFilter(XmlElement filter,
+ Document notification) throws DocumentedException {
removeEventTimeNode(notification);
if (isSupported(filter)) {
return Optional.fromNullable(filteredNotification(filter, notification));
}
private static void removeEventTimeNode(Document document) {
- final Node eventTimeNode = document.getDocumentElement().getElementsByTagNameNS(
- XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_CAPABILITY_NOTIFICATION_1_0, XmlNetconfConstants.EVENT_TIME).item(0);
+ final Node eventTimeNode = document.getDocumentElement().getElementsByTagNameNS(XmlNetconfConstants
+ .URN_IETF_PARAMS_NETCONF_CAPABILITY_NOTIFICATION_1_0, XmlNetconfConstants.EVENT_TIME).item(0);
document.getDocumentElement().removeChild(eventTimeNode);
}
private static boolean isSupported(XmlElement filter) {
- return "subtree".equals(filter.getAttribute("type"))||
- "subtree".equals(filter.getAttribute("type", XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0));
+ return "subtree".equals(filter.getAttribute("type"))
+ || "subtree".equals(filter.getAttribute("type",
+ XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0));
}
private static Document extractNotificationContent(Document notification) throws DocumentedException {
return notification;
}
- private static Document filteredNotification(XmlElement filter, Document originalNotification) throws DocumentedException {
+ private static Document filteredNotification(XmlElement filter,
+ Document originalNotification) throws DocumentedException {
Document result = XmlUtil.newDocument();
XmlElement dataSrc = XmlElement.fromDomDocument(originalNotification);
Element dataDst = (Element) result.importNode(dataSrc.getDomElement(), false);
for (XmlElement filterChild : filter.getChildElements()) {
addSubtree2(filterChild, dataSrc.getOnlyChildElement(), XmlElement.fromDomElement(dataDst));
}
- if(dataDst.getFirstChild() != null) {
+ if (dataDst.getFirstChild() != null) {
result.appendChild(dataDst.getFirstChild());
return result;
} else {
Element rpcReply = originalReplyDocument.getDocumentElement();
Node rpcReplyDst = result.importNode(rpcReply, false);
result.appendChild(rpcReplyDst);
- XmlElement dataSrc = XmlElement.fromDomElement(rpcReply).getOnlyChildElement("data", XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
+ XmlElement dataSrc = XmlElement.fromDomElement(rpcReply).getOnlyChildElement("data",
+ XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
Element dataDst = (Element) result.importNode(dataSrc.getDomElement(), false);
rpcReplyDst.appendChild(dataDst);
addSubtree(filter, dataSrc, XmlElement.fromDomElement(dataDst));
}
}
- private static MatchingResult addSubtree2(XmlElement filter, XmlElement src, XmlElement dstParent) throws DocumentedException {
+ private static MatchingResult addSubtree2(XmlElement filter, XmlElement src,
+ XmlElement dstParent) throws DocumentedException {
Document document = dstParent.getDomElement().getOwnerDocument();
MatchingResult matches = matches(src, filter);
if (matches != MatchingResult.NO_MATCH && matches != MatchingResult.CONTENT_MISMATCH) {
int numberOfTextMatchingChildren = 0;
for (XmlElement srcChild : src.getChildElements()) {
for (XmlElement filterChild : filter.getChildElements()) {
- MatchingResult childMatch = addSubtree2(filterChild, srcChild, XmlElement.fromDomElement(copied));
+ MatchingResult childMatch =
+ addSubtree2(filterChild, srcChild, XmlElement.fromDomElement(copied));
if (childMatch == MatchingResult.CONTENT_MISMATCH) {
return MatchingResult.NO_MATCH;
}
* If filter node has no children and has text content, it also must match.
*/
private static MatchingResult matches(XmlElement src, XmlElement filter) throws DocumentedException {
- boolean tagMatch = src.getName().equals(filter.getName()) &&
- src.getNamespaceOptionally().equals(filter.getNamespaceOptionally());
+ boolean tagMatch = src.getName().equals(filter.getName())
+ && src.getNamespaceOptionally().equals(filter.getNamespaceOptionally());
MatchingResult result = null;
if (tagMatch) {
// match text content
if (result == null) {
for (Attr attr : filter.getAttributes().values()) {
// ignore namespace declarations
- if (XmlUtil.XMLNS_URI.equals(attr.getNamespaceURI()) == false ) {
+ if (XmlUtil.XMLNS_URI.equals(attr.getNamespaceURI()) == false) {
// find attr with matching localName(), namespaceURI(), == value() in src
String found = src.getAttribute(attr.getLocalName(), attr.getNamespaceURI());
if (attr.getValue().equals(found) && result != MatchingResult.NO_MATCH) {
return result;
}
- private static boolean prefixedContentMatches(final XmlElement filter, final XmlElement src) throws DocumentedException {
+ private static boolean prefixedContentMatches(final XmlElement filter,
+ final XmlElement src) throws DocumentedException {
final Map.Entry<String, String> prefixToNamespaceOfFilter;
final Map.Entry<String, String> prefixToNamespaceOfSrc;
try {
return false;
}
- final String unprefixedFilterContent = filter.getTextContent().substring(prefixToNamespaceOfFilter.getKey().length() + 1);
- final String unprefixedSrcContnet = src.getTextContent().substring(prefixToNamespaceOfSrc.getKey().length() + 1);
+ final String unprefixedFilterContent =
+ filter.getTextContent().substring(prefixToNamespaceOfFilter.getKey().length() + 1);
+ final String unprefixedSrcContnet =
+ src.getTextContent().substring(prefixToNamespaceOfSrc.getKey().length() + 1);
// Finally compare unprefixed content
return unprefixedFilterContent.equals(unprefixedSrcContnet);
}
package org.opendaylight.netconf.util.osgi;
import java.util.Collection;
-import java.util.Optional;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
final Collection<ServiceReference<ManagedService>> serviceReferences
= bundleContext.getServiceReferences(ManagedService.class, null);
for (final ServiceReference<ManagedService> serviceReference : serviceReferences) {
- ManagedService service = bundleContext.getService(serviceReference);
- if (service instanceof NetconfConfiguration){
- LOG.debug("Netconf configuration service found");
- return (NetconfConfiguration) service;
- }
+ ManagedService service = bundleContext.getService(serviceReference);
+ if (service instanceof NetconfConfiguration) {
+ LOG.debug("Netconf configuration service found");
+ return (NetconfConfiguration) service;
+ }
}
throw new IllegalStateException("Netconf configuration service not found");
LOG.debug("CSS netconf server configuration cannot be updated as passed dictionary is null");
return;
}
- final InetSocketAddress sshServerAddress = new InetSocketAddress((String) dictionaryConfig.get(SSH_ADDRESS_PROP),
- Integer.parseInt((String) dictionaryConfig.get(SSH_PORT_PROP)));
- final InetSocketAddress tcpServerAddress = new InetSocketAddress((String) dictionaryConfig.get(TCP_ADDRESS_PROP),
+ final InetSocketAddress sshServerAddress =
+ new InetSocketAddress((String) dictionaryConfig.get(SSH_ADDRESS_PROP),
+ Integer.parseInt((String) dictionaryConfig.get(SSH_PORT_PROP)));
+ final InetSocketAddress tcpServerAddress =
+ new InetSocketAddress((String) dictionaryConfig.get(TCP_ADDRESS_PROP),
Integer.parseInt((String) dictionaryConfig.get(TCP_PORT_PROP)));
netconfConfiguration = new NetconfConfigurationHolder(tcpServerAddress,
LOG.debug("CSS netconf server configuration was updated: {}", dictionaryConfig.toString());
}
- public InetSocketAddress getSshServerAddress(){
+ public InetSocketAddress getSshServerAddress() {
return netconfConfiguration.getSshServerAddress();
}
- public InetSocketAddress getTcpServerAddress(){
+ public InetSocketAddress getTcpServerAddress() {
return netconfConfiguration.getTcpServerAddress();
}
}
/**
- * This method returns the uri for all prefixes needed. Wherever possible it
- * uses XMLConstants.
+ * Returns the URI for all prefixes needed. Wherever possible it
+ * uses {@code XMLConstants}.
*
- * @param prefix
- * @return uri
+ * @param prefix prefix
+ * @return uri uniform resource identifier
*/
@Override
public String getNamespaceURI(String prefix) {
throw new UnsupportedOperationException("Utility class");
}
- public static XPathExpression compileXPath(final String xPath) {
- final XPath xpath = FACTORY.newXPath();
- xpath.setNamespaceContext(NS_CONTEXT);
+ public static XPathExpression compileXPath(final String xpath) {
+ final XPath newXPath = FACTORY.newXPath();
+ newXPath.setNamespaceContext(NS_CONTEXT);
try {
- return xpath.compile(xPath);
+ return newXPath.compile(xpath);
} catch (final XPathExpressionException e) {
- throw new IllegalStateException("Error while compiling xpath expression " + xPath, e);
+ throw new IllegalStateException("Error while compiling xpath expression " + xpath, e);
}
}
public class CloseableUtilTest {
+ @SuppressWarnings("checkstyle:IllegalCatch")
@Test
public void testCloseAllFail() throws Exception {
final AutoCloseable failingCloseable = new AutoCloseable() {
@Test
public void testConflictingVersionDetection() throws Exception {
- final Document document = XmlUtil.readXmlToDocument(getClass().getResourceAsStream("/netconfMessages/conflictingversion/conflictingVersionResponse.xml"));
- try{
+ final Document document = XmlUtil.readXmlToDocument(getClass()
+ .getResourceAsStream("/netconfMessages/conflictingversion/conflictingVersionResponse.xml"));
+ try {
NetconfUtil.checkIsMessageOk(document);
fail();
} catch (final IllegalStateException e) {
.withValue("admin")
.build();
final MapEntryNode session1 = Builders.mapEntryBuilder()
- .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifierWithPredicates(Session.QNAME, QName.create(Session.QNAME, "session-id"), 1L))
+ .withNodeIdentifier(new YangInstanceIdentifier
+ .NodeIdentifierWithPredicates(Session.QNAME, QName.create(Session.QNAME, "session-id"), 1L))
.withChild(username)
.build();
final MapNode sessionList = Builders.mapBuilder()
}
@Override
- protected Element handleWithNoSubsequentOperations(Document document, XmlElement operationElement) throws DocumentedException{
+ protected Element handleWithNoSubsequentOperations(Document document,
+ XmlElement operationElement) throws DocumentedException {
handleWithNoSubsequentOperationsRun = true;
return null;
}
}
@Override
- protected Element handle(Document document, XmlElement message, NetconfOperationChainedExecution subsequentOperation) throws DocumentedException{
+ protected Element handle(Document document, XmlElement message,
+ NetconfOperationChainedExecution subsequentOperation) throws DocumentedException {
this.handleRun = true;
try {
return XmlUtil.readXmlToElement("<element/>");
}
@Override
- protected Element handleWithNoSubsequentOperations(Document document, XmlElement operationElement) throws DocumentedException{
+ protected Element handleWithNoSubsequentOperations(Document document,
+ XmlElement operationElement) throws DocumentedException {
return null;
}
assertTrue(NetconfMessageUtil.isOKMessage(new NetconfMessage(okMessage)));
assertFalse(NetconfMessageUtil.isErrorMessage(new NetconfMessage(okMessage)));
- Document errorMessage = XmlFileLoader.xmlFileToDocument("netconfMessages/communicationError/testClientSendsRpcReply_expectedResponse.xml");
+ Document errorMessage = XmlFileLoader
+ .xmlFileToDocument("netconfMessages/communicationError/testClientSendsRpcReply_expectedResponse.xml");
assertTrue(NetconfMessageUtil.isErrorMessage(new NetconfMessage(errorMessage)));
assertFalse(NetconfMessageUtil.isOKMessage(new NetconfMessage(errorMessage)));
Document helloMessage = XmlFileLoader.xmlFileToDocument("netconfMessages/client_hello.xml");
- Collection<String> caps = NetconfMessageUtil.extractCapabilitiesFromHello(new NetconfMessage(helloMessage).getDocument());
+ Collection<String> caps =
+ NetconfMessageUtil.extractCapabilitiesFromHello(new NetconfMessage(helloMessage).getDocument());
assertTrue(caps.contains("urn:ietf:params:netconf:base:1.0"));
assertTrue(caps.contains("urn:ietf:params:netconf:base:1.1"));
}
}
@Before
- public void setUp(){
+ public void setUp() {
XMLUnit.setIgnoreWhitespace(true);
}
XmlElement filter = XmlElement.fromDomDocument(getDocument("filter.xml"));
Document preFilterDocument = getDocument("pre-filter.xml");
Document postFilterDocument = getDocument("post-filter.xml");
- Optional<Document> actualPostFilterDocumentOpt = SubtreeFilter.applySubtreeNotificationFilter(filter, preFilterDocument);
- if(actualPostFilterDocumentOpt.isPresent()) {
+ Optional<Document> actualPostFilterDocumentOpt =
+ SubtreeFilter.applySubtreeNotificationFilter(filter, preFilterDocument);
+ if (actualPostFilterDocumentOpt.isPresent()) {
Document actualPostFilterDocument = actualPostFilterDocumentOpt.get();
LOG.info("Actual document: {}", XmlUtil.toString(actualPostFilterDocument));
Diff diff = XMLUnit.compareXML(postFilterDocument, actualPostFilterDocument);
}
public Document getDocument(String fileName) throws SAXException, IOException {
- return XmlUtil.readXmlToDocument(getClass().getResourceAsStream("/subtree/notification/" + directoryIndex + "/" +
- fileName));
+ return XmlUtil.readXmlToDocument(getClass().getResourceAsStream(
+ "/subtree/notification/" + directoryIndex + "/" + fileName));
}
}
}
@Before
- public void setUp(){
+ public void setUp() {
XMLUnit.setIgnoreWhitespace(true);
}
}
public Document getDocument(String fileName) throws SAXException, IOException {
- return XmlUtil.readXmlToDocument(getClass().getResourceAsStream("/subtree/rpc/" + directoryIndex + "/" +
- fileName));
+ return XmlUtil.readXmlToDocument(
+ getClass().getResourceAsStream("/subtree/rpc/" + directoryIndex + "/" + fileName));
}
}
package org.opendaylight.netconf.util.osgi;
+import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
NetconfConfigUtil.getNetconfConfigurationService(context);
Assert.fail(IllegalStateException.class + "exception expected");
} catch (IllegalStateException e) {
-
+ assertTrue(e.getMessage().startsWith("Netconf configuration service not found"));
}
}
/**
* Custom xmlunit qualifier that doesn't care about order when deeper in the recursion
- * defaults to comparing element name and text content
+ * defaults to comparing element name and text content.
*/
public class NetconfXmlUnitRecursiveQualifier implements ElementQualifier {
return compareNodes(currentControl, currentTest);
}
+ @SuppressWarnings("checkstyle:IllegalCatch")
private boolean compareNodes(Node currentControl, Node currentTest) {
try {
return !(currentControl.hasChildNodes() || currentTest.hasChildNodes());
}
- return (countNodesWithoutConsecutiveTextNodes(controlNodes) == countNodesWithoutConsecutiveTextNodes(testNodes))
- && checkChildren(controlNodes, testNodes);
+ return (countNodesWithoutConsecutiveTextNodes(controlNodes)
+ == countNodesWithoutConsecutiveTextNodes(testNodes)) && checkChildren(controlNodes, testNodes);
} catch (Exception e) {
return false;
return builder.toString();
}
- private static int countNodesWithoutConsecutiveTextNodes(NodeList l) {
+ private static int countNodesWithoutConsecutiveTextNodes(NodeList nodeList) {
int count = 0;
boolean lastNodeWasText = false;
- final int length = l.getLength();
+ final int length = nodeList.getLength();
for (int i = 0; i < length; i++) {
- Node n = l.item(i);
- if (!lastNodeWasText || n.getNodeType() != Node.TEXT_NODE) {
+ Node node = nodeList.item(i);
+ if (!lastNodeWasText || node.getNodeType() != Node.TEXT_NODE) {
count++;
}
- lastNodeWasText = n.getNodeType() == Node.TEXT_NODE;
+ lastNodeWasText = node.getNodeType() == Node.TEXT_NODE;
}
return count;
}
private XmlUnitUtil() {}
- public static void assertContainsElementWithText(final Document doc, final String textToFind) throws NodeTestException {
+ public static void assertContainsElementWithText(final Document doc,
+ final String textToFind) throws NodeTestException {
NodeTest nt = new NodeTest(doc);
NodeTester tester = new AbstractNodeTester() {
@Override
public void testText(Text text) throws NodeTestException {
- if(!textFound) {
+ if (!textFound) {
if (text.getData().equalsIgnoreCase(textToFind)) {
textFound = true;
}
@Override
public void testElement(Element element) throws NodeTestException {
if (!elementFound) {
- if(element.isEqualNode(testElement)) {
+ if (element.isEqualNode(testElement)) {
elementFound = true;
}
}
assertNodeTestPasses(nt, tester, new short[]{Node.ELEMENT_NODE}, true);
}
- public static void assertContainsElementWithName(final Document doc, final String elementName) throws NodeTestException {
+ public static void assertContainsElementWithName(final Document doc,
+ final String elementName) throws NodeTestException {
NodeTest nt = new NodeTest(doc);
NodeTester tester = new AbstractNodeTester() {
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.junit.Test;
@Test
public void testResolver() throws Exception {
- final HardcodedNamespaceResolver hardcodedNamespaceResolver = new HardcodedNamespaceResolver("prefix", "namespace");
+ final HardcodedNamespaceResolver hardcodedNamespaceResolver =
+ new HardcodedNamespaceResolver("prefix", "namespace");
assertEquals("namespace", hardcodedNamespaceResolver.getNamespaceURI("prefix"));
- try{
+ try {
hardcodedNamespaceResolver.getNamespaceURI("unknown");
fail("Unknown namespace lookup should fail");
- } catch(IllegalStateException e) {}
+ } catch (IllegalStateException e) {
+ assertTrue(e.getMessage().startsWith("Prefix mapping not found for "));
+ }
assertNull(hardcodedNamespaceResolver.getPrefix("any"));
assertNull(hardcodedNamespaceResolver.getPrefixes("any"));
package org.opendaylight.netconf.util.xml;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import javax.xml.xpath.XPathConstants;
try {
XMLNetconfUtil.compileXPath("!@(*&$!");
fail("Incorrect xpath should fail");
- } catch (IllegalStateException e) {}
- final Object value = XmlUtil.evaluateXPath(correctXPath, XmlUtil.readXmlToDocument("<top><innerText>value</innerText></top>"), XPathConstants.NODE);
+ } catch (IllegalStateException e) {
+ assertTrue(e.getMessage().startsWith("Error while compiling xpath expression "));
+ }
+ final Object value = XmlUtil.evaluateXPath(correctXPath,
+ XmlUtil.readXmlToDocument("<top><innerText>value</innerText></top>"), XPathConstants.NODE);
assertEquals("value", ((Element) value).getTextContent());
}
<groupId>${project.groupId}</groupId>
<artifactId>features-restconf</artifactId>
<version>${project.version}</version>
+ <type>xml</type>
<classifier>features</classifier>
+ </dependency>
+
+ <!-- restconf features -->
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>features4-restconf</artifactId>
+ <version>${project.version}</version>
<type>xml</type>
- <scope>runtime</scope>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-mdsal-apidocs</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>features</classifier>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>odl-restconf</artifactId>
<version>${project.version}</version>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-restconf-all</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
<classifier>features</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-restconf-noauth</artifactId>
+ <version>${project.version}</version>
<type>xml</type>
- <scope>runtime</scope>
+ <classifier>features</classifier>
</dependency>
</dependencies>
</dependencyManagement>