<configuration>
<instructions>
<Private-Package></Private-Package>
- <Import-Package>javax.management,
- javax.xml.parsers,
- org.opendaylight.controller.config.api,
- org.opendaylight.controller.config.api.jmx,
- org.opendaylight.protocol.framework,
- io.netty.channel,
- io.netty.util.concurrent,
- org.w3c.dom,
- org.slf4j,
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924,
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924,
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state,
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.sessions,
- com.google.common.base,</Import-Package>
<Export-Package>org.opendaylight.controller.netconf.api,
org.opendaylight.controller.netconf.api.jmx,
org.opendaylight.controller.netconf.api.xml,
package org.opendaylight.controller.netconf.api;
+import java.io.StringWriter;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
/**
* implementing ProtocolMessage interface.
*/
public class NetconfMessage {
+ private static final Transformer TRANSFORMER;
+
+ static {
+ final Transformer t;
+ try {
+ t = TransformerFactory.newInstance().newTransformer();
+ } catch (TransformerConfigurationException | TransformerFactoryConfigurationError e) {
+ throw new ExceptionInInitializerError(e);
+ }
+ t.setOutputProperty(OutputKeys.INDENT, "yes");
+ t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+
+ TRANSFORMER = t;
+ }
+
private final Document doc;
public NetconfMessage(final Document doc) {
public Document getDocument() {
return this.doc;
}
+
+ @Override
+ public String toString() {
+ final StreamResult result = new StreamResult(new StringWriter());
+ final DOMSource source = new DOMSource(doc.getDocumentElement());
+
+ try {
+ // Slight critical section is a tradeoff. This should be reasonably fast.
+ synchronized (TRANSFORMER) {
+ TRANSFORMER.transform(source, result);
+ }
+ } catch (TransformerException e) {
+ throw new IllegalStateException("Failed to encode document", e);
+ }
+
+ return result.getWriter().toString();
+ }
}
} else if(NetconfMessageUtil.isErrorMessage(netconfMessage)) {
LOG.warn(
"Error response to start-exi message {}, Communication will continue without exi on session {}",
- XmlUtil.toString(netconfMessage.getDocument()), 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 {}, ",XmlUtil.toString(netconfMessage.getDocument()),
- "Communication will continue without exi and response message will be thrown away on session {}",
- 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);
private final NetconfOperationRouter operationRouter;
private final AutoCloseable onSessionDownCloseable;
- public NetconfServerSessionListener(NetconfOperationRouter operationRouter, SessionMonitoringService monitoringService,
- AutoCloseable onSessionDownCloseable) {
+ public NetconfServerSessionListener(final NetconfOperationRouter operationRouter, final SessionMonitoringService monitoringService,
+ final AutoCloseable onSessionDownCloseable) {
this.operationRouter = operationRouter;
this.monitoringService = monitoringService;
this.onSessionDownCloseable = onSessionDownCloseable;
}
@Override
- public void onSessionUp(NetconfServerSession netconfNetconfServerSession) {
+ public void onSessionUp(final NetconfServerSession netconfNetconfServerSession) {
monitoringService.onSessionUp(netconfNetconfServerSession);
}
@Override
- public void onSessionDown(NetconfServerSession netconfNetconfServerSession, Exception cause) {
+ public void onSessionDown(final NetconfServerSession netconfNetconfServerSession, final Exception cause) {
LOG.debug("Session {} down, reason: {}", netconfNetconfServerSession, cause.getMessage());
onDown(netconfNetconfServerSession);
}
- public void onDown(NetconfServerSession netconfNetconfServerSession) {
+ public void onDown(final NetconfServerSession netconfNetconfServerSession) {
monitoringService.onSessionDown(netconfNetconfServerSession);
try {
}
@Override
- public void onSessionTerminated(NetconfServerSession netconfNetconfServerSession,
- NetconfTerminationReason netconfTerminationReason) {
+ public void onSessionTerminated(final NetconfServerSession netconfNetconfServerSession,
+ final NetconfTerminationReason netconfTerminationReason) {
LOG.debug("Session {} terminated, reason: {}", netconfNetconfServerSession,
netconfTerminationReason.getErrorMessage());
onDown(netconfNetconfServerSession);
}
@Override
- public void onMessage(NetconfServerSession session, NetconfMessage netconfMessage) {
+ public void onMessage(final NetconfServerSession session, final NetconfMessage netconfMessage) {
try {
Preconditions.checkState(operationRouter != null, "Cannot handle message, session up was not yet received");
// schemas
final NetconfMessage message = processDocument(netconfMessage,
session);
- LOG.debug("Responding with message {}", XmlUtil.toString(message.getDocument()));
+ LOG.debug("Responding with message {}", message);
session.sendMessage(message);
if (isCloseSession(netconfMessage)) {
}
}
- private void closeNetconfSession(NetconfServerSession session) {
+ private void closeNetconfSession(final NetconfServerSession session) {
// destroy NetconfOperationService
session.close();
LOG.info("Session {} closed successfully", session.getSessionId());
- private NetconfMessage processDocument(final NetconfMessage netconfMessage, NetconfServerSession session)
+ private NetconfMessage processDocument(final NetconfMessage netconfMessage, final NetconfServerSession session)
throws NetconfDocumentedException {
final Document incomingDocument = netconfMessage.getDocument();
}
}
- private void checkMessageId(Node rootNode) throws NetconfDocumentedException {
+ private void checkMessageId(final Node rootNode) throws NetconfDocumentedException {
NamedNodeMap attributes = rootNode.getAttributes();
private static final Logger LOG = LoggerFactory.getLogger(DefaultStartExi.class);
private NetconfServerSession netconfSession;
- public DefaultStartExi(String netconfSessionIdForReporting) {
+ public DefaultStartExi(final String netconfSessionIdForReporting) {
super(netconfSessionIdForReporting);
}
@Override
- public Document handle(Document message,
- NetconfOperationChainedExecution subsequentOperation) throws NetconfDocumentedException {
- LOG.debug("Received start-exi message {} ", XmlUtil.toString(message));
+ public Document handle(final Document message,
+ final NetconfOperationChainedExecution subsequentOperation) throws NetconfDocumentedException {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Received start-exi message {} ", XmlUtil.toString(message));
+ }
try {
netconfSession.startExiCommunication(new NetconfMessage(message));
}
@Override
- protected Element handleWithNoSubsequentOperations(Document document, XmlElement operationElement) throws NetconfDocumentedException {
+ protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws NetconfDocumentedException {
Element getSchemaResult = document.createElementNS( XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0, XmlNetconfConstants.OK);
LOG.trace("{} operation successful", START_EXI);
return getSchemaResult;
}
@Override
- public void setNetconfSession(NetconfServerSession s) {
+ public void setNetconfSession(final NetconfServerSession s) {
netconfSession = s;
}
}
private final NetconfOperationServiceSnapshot netconfOperationServiceSnapshot;
private Set<NetconfOperation> allNetconfOperations;
- private NetconfOperationRouterImpl(NetconfOperationServiceSnapshot netconfOperationServiceSnapshot) {
+ private NetconfOperationRouterImpl(final NetconfOperationServiceSnapshot netconfOperationServiceSnapshot) {
this.netconfOperationServiceSnapshot = netconfOperationServiceSnapshot;
}
- private synchronized void initNetconfOperations(Set<NetconfOperation> allOperations) {
+ private synchronized void initNetconfOperations(final Set<NetconfOperation> allOperations) {
allNetconfOperations = allOperations;
}
/**
* Factory method to produce instance of NetconfOperationRouter
*/
- public static NetconfOperationRouter createOperationRouter(NetconfOperationServiceSnapshot netconfOperationServiceSnapshot,
- CapabilityProvider capabilityProvider, DefaultCommitNotificationProducer commitNotifier) {
+ public static NetconfOperationRouter createOperationRouter(final NetconfOperationServiceSnapshot netconfOperationServiceSnapshot,
+ final CapabilityProvider capabilityProvider, final DefaultCommitNotificationProducer commitNotifier) {
NetconfOperationRouterImpl router = new NetconfOperationRouterImpl(netconfOperationServiceSnapshot);
Preconditions.checkNotNull(netconfOperationServiceSnapshot);
return router;
}
- private static Set<NetconfOperation> getAllNetconfOperations(Set<NetconfOperation> defaultNetconfOperations,
- NetconfOperationServiceSnapshot netconfOperationServiceSnapshot) {
+ private static Set<NetconfOperation> getAllNetconfOperations(final Set<NetconfOperation> defaultNetconfOperations,
+ final NetconfOperationServiceSnapshot netconfOperationServiceSnapshot) {
Set<NetconfOperation> result = new HashSet<>();
result.addAll(defaultNetconfOperations);
}
@Override
- public synchronized Document onNetconfMessage(Document message,
- NetconfServerSession session) throws NetconfDocumentedException {
+ public synchronized Document onNetconfMessage(final Document message,
+ final NetconfServerSession session) throws NetconfDocumentedException {
Preconditions.checkNotNull(allNetconfOperations, "Operation router was not initialized properly");
NetconfOperationExecution netconfOperationExecution;
netconfOperationServiceSnapshot.close();
}
- private NetconfDocumentedException handleUnexpectedEx(String s, Exception e) throws NetconfDocumentedException {
+ private NetconfDocumentedException handleUnexpectedEx(final String s, final Exception e) throws NetconfDocumentedException {
LOG.error(s, e);
Map<String, String> info = Maps.newHashMap();
NetconfDocumentedException.ErrorSeverity.error, info);
}
- private Document executeOperationWithHighestPriority(Document message,
- NetconfOperationExecution netconfOperationExecution, String messageAsString)
+ private Document executeOperationWithHighestPriority(final Document message,
+ final NetconfOperationExecution netconfOperationExecution, final String messageAsString)
throws NetconfDocumentedException {
LOG.debug("Forwarding netconf message {} to {}", messageAsString, netconfOperationExecution.netconfOperation);
return netconfOperationExecution.execute(message);
}
private NetconfOperationExecution getNetconfOperationWithHighestPriority(
- Document message, NetconfServerSession session) throws NetconfDocumentedException {
+ final Document message, final NetconfServerSession session) throws NetconfDocumentedException {
NavigableMap<HandlingPriority, NetconfOperation> sortedByPriority = getSortedNetconfOperationsWithCanHandle(
message, session);
- Preconditions.checkArgument(sortedByPriority.isEmpty() == false,
- "No %s available to handle message %s", NetconfOperation.class.getName(),
- XmlUtil.toString(message));
+ if (sortedByPriority.isEmpty()) {
+ throw new IllegalArgumentException(String.format("No %s available to handle message %s",
+ NetconfOperation.class.getName(), XmlUtil.toString(message)));
+ }
return NetconfOperationExecution.createExecutionChain(sortedByPriority, sortedByPriority.lastKey());
}
- private TreeMap<HandlingPriority, NetconfOperation> getSortedNetconfOperationsWithCanHandle(Document message,
- NetconfServerSession session) throws NetconfDocumentedException {
+ private TreeMap<HandlingPriority, NetconfOperation> getSortedNetconfOperationsWithCanHandle(final Document message,
+ final NetconfServerSession session) throws NetconfDocumentedException {
TreeMap<HandlingPriority, NetconfOperation> sortedPriority = Maps.newTreeMap();
for (NetconfOperation netconfOperation : allNetconfOperations) {
}
@Override
- public Document execute(Document requestMessage) throws NetconfDocumentedException {
+ public Document execute(final Document requestMessage) throws NetconfDocumentedException {
throw new NetconfDocumentedException("This execution represents the termination point in operation execution and cannot be executed itself",
NetconfDocumentedException.ErrorType.application,
NetconfDocumentedException.ErrorTag.operation_failed,
private static class NetconfOperationExecution implements NetconfOperationChainedExecution {
private final NetconfOperation netconfOperation;
- private NetconfOperationChainedExecution subsequentExecution;
+ private final NetconfOperationChainedExecution subsequentExecution;
- private NetconfOperationExecution(NetconfOperation netconfOperation, NetconfOperationChainedExecution subsequentExecution) {
+ private NetconfOperationExecution(final NetconfOperation netconfOperation, final NetconfOperationChainedExecution subsequentExecution) {
this.netconfOperation = netconfOperation;
this.subsequentExecution = subsequentExecution;
}
}
@Override
- public Document execute(Document message) throws NetconfDocumentedException {
+ public Document execute(final Document message) throws NetconfDocumentedException {
return netconfOperation.handle(message, subsequentExecution);
}
public static NetconfOperationExecution createExecutionChain(
- NavigableMap<HandlingPriority, NetconfOperation> sortedByPriority, HandlingPriority handlingPriority) {
+ final NavigableMap<HandlingPriority, NetconfOperation> sortedByPriority, final HandlingPriority handlingPriority) {
NetconfOperation netconfOperation = sortedByPriority.get(handlingPriority);
HandlingPriority subsequentHandlingPriority = sortedByPriority.lowerKey(handlingPriority);
import org.opendaylight.controller.netconf.nettyutil.handler.NetconfEXICodec;
import org.opendaylight.controller.netconf.nettyutil.handler.exi.EXIParameters;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
import org.opendaylight.protocol.framework.AbstractProtocolSession;
import org.openexi.proc.common.EXIOptionsException;
import org.slf4j.Logger;
try {
exiParams = EXIParameters.fromXmlElement(XmlElement.fromDomDocument(startExiMessage.getDocument()));
} catch (final EXIOptionsException e) {
- LOG.warn("Unable to parse EXI parameters from {} om session {}", XmlUtil.toString(startExiMessage.getDocument()), this, e);
- throw new IllegalArgumentException(e);
+ LOG.warn("Unable to parse EXI parameters from {} on session {}", startExiMessage, this, e);
+ throw new IllegalArgumentException("Cannot parse options", e);
}
final NetconfEXICodec exiCodec = new NetconfEXICodec(exiParams.getOptions());
addExiHandlers(exiCodec);
import org.opendaylight.controller.netconf.nettyutil.handler.NetconfXMLToMessageDecoder;
import org.opendaylight.controller.netconf.util.messages.FramingMechanism;
import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
import org.opendaylight.protocol.framework.AbstractSessionNegotiator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private final long connectionTimeoutMillis;
// TODO shrink constructor
- protected AbstractNetconfSessionNegotiator(P sessionPreferences, Promise<S> promise, Channel channel, Timer timer,
- L sessionListener, 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;
Future<Channel> future = sslHandler.get().handshakeFuture();
future.addListener(new GenericFutureListener<Future<? super Channel>>() {
@Override
- public void operationComplete(Future<? super Channel> future) {
+ public void operationComplete(final Future<? super Channel> future) {
Preconditions.checkState(future.isSuccess(), "Ssl handshake was not successful");
LOG.debug("Ssl handshake complete");
start();
}
}
- private static Optional<SslHandler> getSslHandler(Channel channel) {
+ 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);
}
private void start() {
final NetconfMessage helloMessage = this.sessionPreferences.getHelloMessage();
- LOG.debug("Session negotiation started with hello message {} on channel {}", XmlUtil.toString(helloMessage.getDocument()), channel);
+ LOG.debug("Session negotiation started with hello message {} on channel {}", helloMessage, channel);
channel.pipeline().addLast(NAME_OF_EXCEPTION_HANDLER, new ExceptionHandlingInboundChannelHandler());
channel.closeFuture().addListener(new GenericFutureListener<ChannelFuture>() {
@Override
- public void operationComplete(ChannelFuture future) throws Exception {
+ public void operationComplete(final ChannelFuture future) throws Exception {
if(future.isSuccess()) {
LOG.debug("Channel {} closed: success", future.channel());
} else {
}
}
- protected final S getSessionForHelloMessage(NetconfHelloMessage netconfMessage) throws NetconfDocumentedException {
+ protected final S getSessionForHelloMessage(final NetconfHelloMessage netconfMessage) throws NetconfDocumentedException {
Preconditions.checkNotNull(netconfMessage, "netconfMessage");
final Document doc = netconfMessage.getDocument();
new NetconfChunkAggregator());
}
- private boolean shouldUseChunkFraming(Document doc) {
+ private boolean shouldUseChunkFraming(final Document doc) {
return containsBase11Capability(doc)
&& containsBase11Capability(sessionPreferences.getHelloMessage().getDocument());
}
replaceChannelHandler(channel, AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER, new NetconfMessageToXMLEncoder());
}
- private static ChannelHandler replaceChannelHandler(Channel channel, String handlerKey, ChannelHandler decoder) {
+ private static ChannelHandler replaceChannelHandler(final Channel channel, final String handlerKey, final ChannelHandler decoder) {
return channel.pipeline().replace(handlerKey, handlerKey, decoder);
}
return false;
}
- private static boolean isStateChangePermitted(State state, State newState) {
+ private static boolean isStateChangePermitted(final State state, final State newState) {
if (state == State.IDLE && newState == State.OPEN_WAIT) {
return true;
}
*/
private final class ExceptionHandlingInboundChannelHandler extends ChannelInboundHandlerAdapter {
@Override
- public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
+ public void exceptionCaught(final ChannelHandlerContext ctx, final Throwable cause) {
LOG.warn("An exception occurred during negotiation with {}", channel.remoteAddress(), cause);
cancelTimeout();
negotiationFailed(cause);
import io.netty.buffer.ByteBufUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
+import java.io.IOException;
import java.io.InputStream;
import java.util.List;
+import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.openexi.proc.common.EXIOptionsException;
import org.openexi.sax.EXIReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
public final class NetconfEXIToMessageDecoder extends ByteToMessageDecoder {
}
@Override
- protected void decode(final ChannelHandlerContext ctx, final ByteBuf in, final List<Object> out) throws Exception {
+ 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
*/
// If empty Byte buffer is passed to r.parse, EOFException is thrown
- if (in.isReadable() == false) {
+ if (!in.isReadable()) {
LOG.debug("No more content in incoming buffer.");
return;
}
- LOG.trace("Received to decode: {}", ByteBufUtil.hexDump(in));
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Received to decode: {}", ByteBufUtil.hexDump(in));
+ }
final EXIReader r = codec.getReader();
import io.netty.buffer.ByteBufOutputStream;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
+import java.io.IOException;
import java.io.OutputStream;
import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXTransformerFactory;
import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
+import org.openexi.proc.common.EXIOptionsException;
import org.openexi.sax.Transmogrifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
}
@Override
- protected void encode(final ChannelHandlerContext ctx, final NetconfMessage msg, final ByteBuf out) throws Exception {
- LOG.trace("Sent to encode : {}", XmlUtil.toString(msg.getDocument()));
+ protected void encode(final ChannelHandlerContext ctx, final NetconfMessage msg, final ByteBuf out) throws EXIOptionsException, IOException, TransformerException {
+ LOG.trace("Sent to encode : {}", msg);
try (final OutputStream os = new ByteBufOutputStream(out)) {
final Transmogrifier transmogrifier = codec.getTransmogrifier();
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Comment;
@Override
@VisibleForTesting
public void encode(ChannelHandlerContext ctx, NetconfMessage msg, ByteBuf out) throws IOException, TransformerException {
- LOG.trace("Sent to encode : {}", XmlUtil.toString(msg.getDocument()));
+ LOG.trace("Sent to encode : {}", msg);
if (clientId.isPresent()) {
Comment comment = msg.getDocument().createComment("clientId:" + clientId.get());
// State variables do not have to by synchronized
// Netty uses always the same (1) thread per pipeline
// We use instance of this per pipeline
- private List<NetconfMessage> nonHelloMessages = Lists.newArrayList();
+ private final List<NetconfMessage> nonHelloMessages = Lists.newArrayList();
private boolean helloReceived = false;
@Override
@VisibleForTesting
- public void decode(ChannelHandlerContext ctx, ByteBuf in, 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;
in.markReaderIndex();
try {
- LOG.trace("Received to decode: {}", ByteBufUtil.hexDump(in));
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Received to decode: {}", ByteBufUtil.hexDump(in));
+ }
+
byte[] bytes = new byte[in.readableBytes()];
in.readBytes(bytes);
final NetconfMessage message = getNetconfMessage(additionalHeader, doc);
if (message instanceof NetconfHelloMessage) {
Preconditions.checkState(helloReceived == false,
- "Multiple hello messages received, unexpected hello: %s",
- XmlUtil.toString(message.getDocument()));
+ "Multiple hello messages received, unexpected hello: %s", message);
out.add(message);
helloReceived = true;
// Non hello message, suspend the message and insert into cache
} else {
- Preconditions.checkState(helloReceived, "Hello message not received, instead received: %s",
- XmlUtil.toString(message.getDocument()));
- LOG.debug("Netconf message received during negotiation, caching {}",
- XmlUtil.toString(message.getDocument()));
+ Preconditions.checkState(helloReceived, "Hello message not received, instead received: %s", message);
+ LOG.debug("Netconf message received during negotiation, caching {}", message);
nonHelloMessages.add(message);
}
} finally {
return msg;
}
- private int getAdditionalHeaderEndIndex(byte[] bytes) {
+ private int getAdditionalHeaderEndIndex(final byte[] bytes) {
for (byte[] possibleEnd : POSSIBLE_ENDS) {
int idx = findByteSequence(bytes, possibleEnd);
}
- private void logMessage(byte[] bytes) {
+ private void logMessage(final byte[] bytes) {
String s = Charsets.UTF_8.decode(ByteBuffer.wrap(bytes)).toString();
LOG.debug("Parsing message \n{}", s);
}
- private boolean startsWithAdditionalHeader(byte[] bytes) {
+ private boolean startsWithAdditionalHeader(final byte[] bytes) {
for (byte[] possibleStart : POSSIBLE_STARTS) {
int i = 0;
for (byte b : possibleStart) {
return false;
}
- private String additionalHeaderToString(byte[] bytes) {
+ private String additionalHeaderToString(final byte[] bytes) {
return Charsets.UTF_8.decode(ByteBuffer.wrap(bytes)).toString();
}
import io.netty.buffer.ByteBufUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
+import java.io.IOException;
import java.util.List;
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.util.xml.XmlUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.xml.sax.SAXException;
public final class NetconfXMLToMessageDecoder extends ByteToMessageDecoder {
private static final Logger LOG = LoggerFactory.getLogger(NetconfXMLToMessageDecoder.class);
@Override
- public void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
+ 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));
+ }
- if (in.readableBytes() != 0) {
- LOG.trace("Received to decode: {}", ByteBufUtil.hexDump(in));
out.add(new NetconfMessage(XmlUtil.readXmlToDocument(new ByteBufInputStream(in))));
} else {
LOG.debug("No more content in incoming buffer.");
f.addListener(new SendErrorVerifyingListener(sendErrorException));
}
- public static void sendErrorMessage(Channel channel, NetconfDocumentedException sendErrorException) {
+ public static void sendErrorMessage(final Channel channel, final NetconfDocumentedException 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));
}
- public static void sendErrorMessage(NetconfSession session, NetconfDocumentedException sendErrorException,
- NetconfMessage incommingMessage) {
+ public static void sendErrorMessage(final NetconfSession session, final NetconfDocumentedException sendErrorException,
+ final NetconfMessage incommingMessage) {
final Document errorDocument = createDocument(sendErrorException);
- LOG.trace("Sending error {}", XmlUtil.toString(errorDocument));
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Sending error {}", XmlUtil.toString(errorDocument));
+ }
+
tryToCopyAttributes(incommingMessage.getDocument(), errorDocument, sendErrorException);
ChannelFuture f = session.sendMessage(new NetconfMessage(errorDocument));
f.addListener(new SendErrorVerifyingListener(sendErrorException));