Netconf message related constants moved to one place.
[controller.git] / opendaylight / netconf / netconf-util / src / main / java / org / opendaylight / controller / netconf / util / messages / NetconfMessageFactory.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.controller.netconf.util.messages;
10
11 import com.google.common.base.Charsets;
12 import com.google.common.base.Optional;
13 import org.opendaylight.controller.netconf.api.NetconfDeserializerException;
14 import org.opendaylight.controller.netconf.api.NetconfMessage;
15 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
16 import org.opendaylight.protocol.framework.DeserializerException;
17 import org.opendaylight.protocol.framework.DocumentedException;
18 import org.opendaylight.protocol.framework.ProtocolMessageFactory;
19 import org.opendaylight.protocol.util.ByteArray;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
22 import org.w3c.dom.Comment;
23 import org.w3c.dom.Document;
24 import org.xml.sax.SAXException;
25
26 import java.io.ByteArrayInputStream;
27 import java.io.IOException;
28 import java.nio.ByteBuffer;
29 import java.util.Arrays;
30
31 /**
32  * NetconfMessageFactory for (de)serializing DOM documents.
33  */
34 public final class NetconfMessageFactory implements ProtocolMessageFactory<NetconfMessage> {
35
36     private static final Logger logger = LoggerFactory.getLogger(NetconfMessageFactory.class);
37
38     private final Optional<String> clientId;
39
40     public NetconfMessageFactory() {
41         clientId = Optional.absent();
42     }
43
44     public NetconfMessageFactory(Optional<String> clientId) {
45         this.clientId = clientId;
46     }
47
48     @Override
49     public NetconfMessage parse(byte[] bytes) throws DeserializerException, DocumentedException {
50         String s = Charsets.UTF_8.decode(ByteBuffer.wrap(bytes)).toString();
51         logger.debug("Parsing message \n{}", s);
52         if (bytes[0] == '[') {
53             // yuma sends auth information in the first line. Ignore until ]\n
54             // is found.
55             int endOfAuthHeader = ByteArray.findByteSequence(bytes, new byte[] { ']', '\n' });
56             if (endOfAuthHeader > -1) {
57                 bytes = Arrays.copyOfRange(bytes, endOfAuthHeader + 2, bytes.length);
58             }
59         }
60         NetconfMessage message = null;
61         try {
62             Document doc = XmlUtil.readXmlToDocument(new ByteArrayInputStream(bytes));
63             message = new NetconfMessage(doc);
64         } catch (final SAXException | IOException | IllegalStateException e) {
65             throw new NetconfDeserializerException("Could not parse message from " + new String(bytes), e);
66         }
67         return message;
68     }
69
70     @Override
71     public byte[] put(NetconfMessage netconfMessage) {
72         if (clientId.isPresent()) {
73             Comment comment = netconfMessage.getDocument().createComment("clientId:" + clientId.get());
74             netconfMessage.getDocument().appendChild(comment);
75         }
76         final ByteBuffer msgBytes = Charsets.UTF_8.encode(xmlToString(netconfMessage.getDocument()));
77         String content = xmlToString(netconfMessage.getDocument());
78
79         logger.trace("Putting message \n{}", content);
80         byte[] b = new byte[msgBytes.limit()];
81         msgBytes.get(b);
82         return b;
83     }
84
85     private String xmlToString(Document doc) {
86         return XmlUtil.toString(doc, false);
87     }
88 }