</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);
}
}
}