From: Robert Varga Date: Tue, 2 Dec 2014 22:26:38 +0000 (+0100) Subject: Implement NetconfMessage.toString() X-Git-Tag: release/lithium~796^2 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=0c95d90e91f5a6a07d744b97dcc226c70a22c366 Implement NetconfMessage.toString() Rather than explicitly converting the internal document intoa string before logging it, teach NetconfMessage how to do toString(). This way we do not have to check Logger configuration and pass NetconfMessages directly. The logger will cann toString() as needed. Change-Id: I07a18f32a1500784b81f52f0412acd73123a161e Signed-off-by: Robert Varga --- diff --git a/opendaylight/netconf/netconf-api/pom.xml b/opendaylight/netconf/netconf-api/pom.xml index c5fd8f1894..11aed2990e 100644 --- a/opendaylight/netconf/netconf-api/pom.xml +++ b/opendaylight/netconf/netconf-api/pom.xml @@ -46,20 +46,6 @@ - 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, org.opendaylight.controller.netconf.api, org.opendaylight.controller.netconf.api.jmx, org.opendaylight.controller.netconf.api.xml, diff --git a/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfMessage.java b/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfMessage.java index 78586a3fec..d8c80e56eb 100644 --- a/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfMessage.java +++ b/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfMessage.java @@ -8,6 +8,15 @@ 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; /** @@ -15,6 +24,21 @@ 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) { @@ -24,4 +48,21 @@ public class NetconfMessage { 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(); + } } diff --git a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiator.java b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiator.java index a8c9a6526d..06c695c25a 100644 --- a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiator.java +++ b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiator.java @@ -169,14 +169,13 @@ public class NetconfClientSessionNegotiator extends } 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); diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java index b2b8c50029..951d0dd98d 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java @@ -35,25 +35,25 @@ public class NetconfServerSessionListener implements NetconfSessionListener promise, Channel channel, Timer timer, - L sessionListener, long connectionTimeoutMillis) { + protected AbstractNetconfSessionNegotiator(final P sessionPreferences, final Promise promise, final Channel channel, final Timer timer, + final L sessionListener, final long connectionTimeoutMillis) { super(promise, channel); this.sessionPreferences = sessionPreferences; this.promise = promise; @@ -83,7 +82,7 @@ public abstract class AbstractNetconfSessionNegotiator

future = sslHandler.get().handshakeFuture(); future.addListener(new GenericFutureListener>() { @Override - public void operationComplete(Future future) { + public void operationComplete(final Future future) { Preconditions.checkState(future.isSuccess(), "Ssl handshake was not successful"); LOG.debug("Ssl handshake complete"); start(); @@ -94,7 +93,7 @@ public abstract class AbstractNetconfSessionNegotiator

getSslHandler(Channel channel) { + private static Optional getSslHandler(final Channel channel) { final SslHandler sslHandler = channel.pipeline().get(SslHandler.class); return sslHandler == null ? Optional. absent() : Optional.of(sslHandler); } @@ -105,7 +104,7 @@ public abstract class AbstractNetconfSessionNegotiator

() { @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 { @@ -159,7 +158,7 @@ public abstract class AbstractNetconfSessionNegotiator

nonHelloMessages = Lists.newArrayList(); + private final List nonHelloMessages = Lists.newArrayList(); private boolean helloReceived = false; @Override @VisibleForTesting - public void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws IOException, SAXException, NetconfDocumentedException { + public void decode(final ChannelHandlerContext ctx, final ByteBuf in, final List out) throws IOException, SAXException, NetconfDocumentedException { if (in.readableBytes() == 0) { LOG.debug("No more content in incoming buffer."); return; @@ -95,16 +95,13 @@ public final class NetconfXMLToHelloMessageDecoder extends ByteToMessageDecoder 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 { @@ -125,7 +122,7 @@ public final class NetconfXMLToHelloMessageDecoder extends ByteToMessageDecoder return msg; } - private int getAdditionalHeaderEndIndex(byte[] bytes) { + private int getAdditionalHeaderEndIndex(final byte[] bytes) { for (byte[] possibleEnd : POSSIBLE_ENDS) { int idx = findByteSequence(bytes, possibleEnd); @@ -163,12 +160,12 @@ public final class NetconfXMLToHelloMessageDecoder extends ByteToMessageDecoder } - 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) { @@ -185,7 +182,7 @@ public final class NetconfXMLToHelloMessageDecoder extends ByteToMessageDecoder return false; } - private String additionalHeaderToString(byte[] bytes) { + private String additionalHeaderToString(final byte[] bytes) { return Charsets.UTF_8.decode(ByteBuffer.wrap(bytes)).toString(); }