X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fnetconf%2Fnetconf-util%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fnetconf%2Futil%2Fmessages%2FNetconfMessageFactory.java;h=6f86cc37f92bcb6ba93c352e6475e72935df2730;hb=d67608349eca39dd2b4b77923b1500d25a664e52;hp=029d2ba7595c2a7fabb0f2ec74511fcf8b166184;hpb=e6bcd06e610be274e8f2df901b61789bb17c442a;p=controller.git diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfMessageFactory.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfMessageFactory.java index 029d2ba759..6f86cc37f9 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfMessageFactory.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfMessageFactory.java @@ -8,27 +8,27 @@ package org.opendaylight.controller.netconf.util.messages; -import com.google.common.base.Charsets; -import com.google.common.base.Optional; -import com.google.common.collect.Lists; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.List; + import org.opendaylight.controller.netconf.api.NetconfDeserializerException; import org.opendaylight.controller.netconf.api.NetconfMessage; import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.opendaylight.protocol.framework.DeserializerException; import org.opendaylight.protocol.framework.DocumentedException; import org.opendaylight.protocol.framework.ProtocolMessageFactory; -import org.opendaylight.protocol.util.ByteArray; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Comment; import org.w3c.dom.Document; import org.xml.sax.SAXException; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.List; +import com.google.common.base.Charsets; +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableList; /** * NetconfMessageFactory for (de)serializing DOM documents. @@ -36,12 +36,10 @@ import java.util.List; public final class NetconfMessageFactory implements ProtocolMessageFactory { private static final Logger logger = LoggerFactory.getLogger(NetconfMessageFactory.class); - - public static final byte[] endOfMessage = "]]>]]>".getBytes(Charsets.UTF_8); - - public static final byte[] endOfChunk = "\n##\n".getBytes(Charsets.UTF_8); - - public static final int MAX_CHUNK_SIZE = 1024; // Bytes + private static final List POSSIBLE_STARTS = ImmutableList.of( + "[".getBytes(Charsets.UTF_8), "\r\n[".getBytes(Charsets.UTF_8), "\n[".getBytes(Charsets.UTF_8)); + private static final List POSSIBLE_ENDS = ImmutableList.of( + "]\n".getBytes(Charsets.UTF_8), "]\r\n".getBytes(Charsets.UTF_8)); private final Optional clientId; @@ -54,25 +52,88 @@ public final class NetconfMessageFactory implements ProtocolMessageFactory parse(byte[] bytes) throws DeserializerException, DocumentedException { - String s = Charsets.UTF_8.decode(ByteBuffer.wrap(bytes)).toString(); - logger.debug("Parsing message \n{}", s); - if (bytes[0] == '[') { - // yuma sends auth information in the first line. Ignore until ]\n - // is found. - int endOfAuthHeader = ByteArray.findByteSequence(bytes, new byte[] { ']', '\n' }); + public NetconfMessage parse(byte[] bytes) throws DeserializerException, DocumentedException { + logMessage(bytes); + + String additionalHeader = null; + + if (startsWithAdditionalHeader(bytes)) { + // Auth information containing username, ip address... extracted for monitoring + int endOfAuthHeader = getAdditionalHeaderEndIndex(bytes); if (endOfAuthHeader > -1) { + byte[] additionalHeaderBytes = Arrays.copyOfRange(bytes, 0, endOfAuthHeader + 2); + additionalHeader = additionalHeaderToString(additionalHeaderBytes); bytes = Arrays.copyOfRange(bytes, endOfAuthHeader + 2, bytes.length); } } - List messages = Lists.newArrayList(); + NetconfMessage message; try { Document doc = XmlUtil.readXmlToDocument(new ByteArrayInputStream(bytes)); - messages.add(new NetconfMessage(doc)); + message = new NetconfMessage(doc, additionalHeader); } catch (final SAXException | IOException | IllegalStateException e) { throw new NetconfDeserializerException("Could not parse message from " + new String(bytes), e); } - return messages; + return message; + } + + private static int findByteSequence(final byte[] bytes, final byte[] sequence) { + if (bytes.length < sequence.length) { + throw new IllegalArgumentException("Sequence to be found is longer than the given byte array."); + } + if (bytes.length == sequence.length) { + if (Arrays.equals(bytes, sequence)) { + return 0; + } else { + return -1; + } + } + int j = 0; + for (int i = 0; i < bytes.length; i++) { + if (bytes[i] == sequence[j]) { + j++; + if (j == sequence.length) { + return i - j + 1; + } + } else { + j = 0; + } + } + return -1; + } + + private int getAdditionalHeaderEndIndex(byte[] bytes) { + for (byte[] possibleEnd : POSSIBLE_ENDS) { + int idx = findByteSequence(bytes, possibleEnd); + + if (idx != -1) { + return idx; + } + } + + return -1; + } + + private boolean startsWithAdditionalHeader(byte[] bytes) { + for (byte[] possibleStart : POSSIBLE_STARTS) { + int i = 0; + for (byte b : possibleStart) { + if(bytes[i] != b) + break; + + return true; + } + } + + return false; + }; + + private void logMessage(byte[] bytes) { + String s = Charsets.UTF_8.decode(ByteBuffer.wrap(bytes)).toString(); + logger.debug("Parsing message \n{}", s); + } + + private String additionalHeaderToString(byte[] bytes) { + return Charsets.UTF_8.decode(ByteBuffer.wrap(bytes)).toString(); } @Override @@ -81,11 +142,18 @@ public final class NetconfMessageFactory implements ProtocolMessageFactory