Eliminate use of ByteBufWriteUtil from mvpn
[bgpcep.git] / bgp / extensions / mvpn / src / main / java / org / opendaylight / protocol / bgp / mvpn / impl / attributes / OpaqueUtil.java
1 /*
2  * Copyright (c) 2016 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 package org.opendaylight.protocol.bgp.mvpn.impl.attributes;
9
10 import com.google.common.base.Joiner;
11 import com.google.common.base.Splitter;
12 import io.netty.buffer.ByteBuf;
13 import io.netty.buffer.ByteBufUtil;
14 import java.util.ArrayList;
15 import java.util.List;
16 import javax.xml.bind.DatatypeConverter;
17 import org.opendaylight.protocol.util.ByteArray;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pmsi.tunnel.rev180329.Opaque;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pmsi.tunnel.rev180329.pmsi.tunnel.pmsi.tunnel.tunnel.identifier.mldp.p2mp.lsp.mldp.p2mp.lsp.OpaqueValue;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pmsi.tunnel.rev180329.pmsi.tunnel.pmsi.tunnel.tunnel.identifier.mldp.p2mp.lsp.mldp.p2mp.lsp.OpaqueValueBuilder;
22 import org.opendaylight.yangtools.yang.common.Uint16;
23 import org.opendaylight.yangtools.yang.common.Uint8;
24 import org.opendaylight.yangtools.yang.common.netty.ByteBufUtils;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28 public final class OpaqueUtil {
29     public static final short GENERIC_LSP_IDENTIFIER = 1;
30     public static final short EXTENDED_TYPE = 255;
31     private static final Logger LOG = LoggerFactory.getLogger(OpaqueUtil.class);
32     private static final String SEPARATOR = ":";
33     private static final Joiner SEPARATOR_JOINER = Joiner.on(SEPARATOR);
34     private static final Splitter TWO_CHAR_SPLITTER = Splitter.fixedLength(2);
35
36     private OpaqueUtil() {
37         // Hidden on purpose
38     }
39
40     public static boolean serializeOpaque(final Opaque opaque, final ByteBuf byteBuf) {
41         final Uint8 type = opaque.getOpaqueType();
42         switch (type.toJava()) {
43             case GENERIC_LSP_IDENTIFIER:
44                 ByteBufUtils.write(byteBuf, type);
45                 writeGeneric(opaque.getOpaque(), byteBuf);
46                 break;
47             case EXTENDED_TYPE:
48                 ByteBufUtils.write(byteBuf, type);
49                 writeExtended(opaque.getOpaque(), opaque.getOpaqueExtendedType(), byteBuf);
50                 break;
51             default:
52                 LOG.debug("Skipping serialization of Opaque Value {}", opaque);
53                 return false;
54         }
55         return true;
56     }
57
58     private static void writeExtended(final HexString opaque, final Uint16 opaqueExtendedType, final ByteBuf byteBuf) {
59         final byte[] output = writeOpaqueValue(opaque.getValue());
60         ByteBufUtils.writeOrZero(byteBuf, opaqueExtendedType);
61         byteBuf.writeShort(output.length);
62         byteBuf.writeBytes(output);
63     }
64
65     private static void writeGeneric(final HexString opaque, final ByteBuf byteBuf) {
66         final byte[] output = writeOpaqueValue(opaque.getValue());
67         byteBuf.writeShort(output.length);
68         byteBuf.writeBytes(output);
69     }
70
71     private static byte[] writeOpaqueValue(final String opaque) {
72         return DatatypeConverter.parseHexBinary(opaque.replace(SEPARATOR, ""));
73     }
74
75     public static Opaque parseOpaque(final ByteBuf buffer) {
76         final Uint8 type = ByteBufUtils.readUint8(buffer);
77         final OpaqueValueBuilder builder = new OpaqueValueBuilder();
78         switch (type.toJava()) {
79             case GENERIC_LSP_IDENTIFIER:
80                 builder.setOpaque(buildOpaqueValue(buffer));
81                 break;
82             case EXTENDED_TYPE:
83                 buildExtended(builder, buffer);
84                 break;
85             default:
86                 final int length = buffer.readUnsignedShort();
87                 buffer.skipBytes(length);
88                 LOG.debug("Skipping parsing of Opaque Value {}", buffer);
89                 return null;
90         }
91         return builder.setOpaqueType(type).build();
92     }
93
94     private static void buildExtended(final OpaqueValueBuilder builder, final ByteBuf buffer) {
95         final Uint16 extendedType = ByteBufUtils.readUint16(buffer);
96         final HexString opaqueValue = buildOpaqueValue(buffer);
97         builder.setOpaqueExtendedType(extendedType).setOpaque(opaqueValue);
98     }
99
100     private static HexString buildOpaqueValue(final ByteBuf buffer) {
101         final int length = buffer.readUnsignedShort();
102         final byte[] value = ByteArray.readBytes(buffer, length);
103         return new HexString(SEPARATOR_JOINER.join(TWO_CHAR_SPLITTER.split(ByteBufUtil.hexDump(value))));
104     }
105
106     public static List<OpaqueValue> parseOpaqueList(final ByteBuf byteBuf) {
107         final List<OpaqueValue> opaqueValues = new ArrayList<>();
108         while (byteBuf.isReadable()) {
109             final Opaque opaque = parseOpaque(byteBuf);
110             if (opaque != null) {
111                 opaqueValues.add((OpaqueValue) opaque);
112             }
113         }
114         return opaqueValues;
115     }
116
117     public static boolean serializeOpaqueList(final List<OpaqueValue> mldpP2mpLsp, final ByteBuf buffer) {
118         boolean parsed = false;
119         for (final OpaqueValue opaque : mldpP2mpLsp) {
120             if (serializeOpaque(opaque, buffer)) {
121                 parsed = true;
122             }
123         }
124         return parsed;
125     }
126 }