Bump MDSAL to 4.0.0
[bgpcep.git] / bgp / extensions / linkstate / src / main / java / org / opendaylight / protocol / bgp / linkstate / spi / pojo / SimpleNlriTypeRegistry.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.linkstate.spi.pojo;
9
10 import static com.google.common.base.Preconditions.checkArgument;
11 import static java.util.Objects.requireNonNull;
12
13 import io.netty.buffer.ByteBuf;
14 import io.netty.buffer.Unpooled;
15 import java.util.HashMap;
16 import java.util.Map;
17 import org.opendaylight.protocol.bgp.linkstate.spi.LinkstateTlvParser;
18 import org.opendaylight.protocol.bgp.linkstate.spi.NlriTypeCaseParser;
19 import org.opendaylight.protocol.bgp.linkstate.spi.NlriTypeCaseSerializer;
20 import org.opendaylight.protocol.bgp.linkstate.spi.TlvUtil;
21 import org.opendaylight.protocol.concepts.HandlerRegistry;
22 import org.opendaylight.protocol.concepts.MultiRegistry;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.linkstate.ObjectType;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.linkstate.destination.CLinkstateDestination;
25 import org.opendaylight.yangtools.concepts.Registration;
26 import org.opendaylight.yangtools.yang.common.QName;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 public final class SimpleNlriTypeRegistry {
31
32     private static final Logger LOG = LoggerFactory.getLogger(SimpleNlriTypeRegistry.class);
33     private static final SimpleNlriTypeRegistry SINGLETON = new SimpleNlriTypeRegistry();
34     private final HandlerRegistry<ObjectType, NlriTypeCaseParser, NlriTypeCaseSerializer> nlriRegistry =
35             new HandlerRegistry<>();
36     private final MultiRegistry<QName, LinkstateTlvParser.LinkstateTlvSerializer<?>> tlvSerializers =
37             new MultiRegistry<>();
38     private final MultiRegistry<Integer, LinkstateTlvParser<?>> tlvParsers = new MultiRegistry<>();
39
40     private SimpleNlriTypeRegistry() {
41     }
42
43     public static SimpleNlriTypeRegistry getInstance() {
44         return SINGLETON;
45     }
46
47     public Registration registerNlriParser(final int type, final NlriTypeCaseParser parser) {
48         return this.nlriRegistry.registerParser(type, parser);
49     }
50
51     public Registration registerNlriSerializer(final Class<? extends ObjectType> clazzType,
52             final NlriTypeCaseSerializer serializer) {
53         return this.nlriRegistry.registerSerializer(clazzType, serializer);
54     }
55
56     public <T> Registration registerTlvParser(final int tlvType, final LinkstateTlvParser<T> parser) {
57         return this.tlvParsers.register(tlvType, parser);
58     }
59
60     public <T> Registration registerTlvSerializer(final QName tlvQName,
61             final LinkstateTlvParser.LinkstateTlvSerializer<T> serializer) {
62         return this.tlvSerializers.register(tlvQName, serializer);
63     }
64
65     public CLinkstateDestination parseNlriType(final ByteBuf buffer) {
66         final int type = buffer.readUnsignedShort();
67         final int length = buffer.readUnsignedShort();
68         final NlriTypeCaseParser parser = this.nlriRegistry.getParser(type);
69         if (parser == null) {
70             LOG.warn("Linkstate NLRI parser for Type: {} was not found.", type);
71             return null;
72         }
73         return parser.parseTypeNlri(buffer.readSlice(length));
74     }
75
76     public void serializeNlriType(final CLinkstateDestination nlri, final ByteBuf byteAggregator) {
77         if (nlri == null) {
78             return;
79         }
80         requireNonNull(byteAggregator);
81         final ObjectType objectType = nlri.getObjectType();
82         final NlriTypeCaseSerializer serializer = this.nlriRegistry
83                 .getSerializer((Class<? extends ObjectType>) objectType.implementedInterface());
84         if (serializer == null) {
85             LOG.warn("Linkstate NLRI serializer for Type: {} was not found.", objectType.implementedInterface());
86             return;
87         }
88         final ByteBuf nlriType = Unpooled.buffer();
89         serializer.serializeTypeNlri(nlri, nlriType);
90         TlvUtil.writeTLV(serializer.getNlriType(), nlriType, byteAggregator);
91     }
92
93     public <T> T parseTlv(final ByteBuf buffer) {
94         return parseTlv(buffer, getParser(buffer));
95     }
96
97     private static <T> T parseTlv(final ByteBuf buffer, final LinkstateTlvParser<T> parser) {
98         if (parser == null) {
99             return null;
100         }
101         checkArgument(buffer != null && buffer.isReadable());
102         final int length = buffer.readUnsignedShort();
103         return parser.parseTlvBody(buffer.readSlice(length));
104     }
105
106     public Map<QName, Object> parseSubTlvs(final ByteBuf buffer) {
107         final Map<QName, Object> tlvs = new HashMap<>();
108         while (buffer.isReadable()) {
109             final LinkstateTlvParser<?> tlvParser = getParser(buffer);
110             final Object tlvBody = parseTlv(buffer, tlvParser);
111             if (tlvBody != null) {
112                 tlvs.put(tlvParser.getTlvQName(), tlvBody);
113             }
114         }
115         return tlvs;
116     }
117
118     private <T> LinkstateTlvParser<T> getParser(final ByteBuf buffer) {
119         checkArgument(buffer != null && buffer.isReadable());
120         final int type = buffer.readUnsignedShort();
121         final LinkstateTlvParser<T> parser = (LinkstateTlvParser<T>) this.tlvParsers.get(type);
122         if (parser == null) {
123             LOG.warn("Linkstate TLV parser for Type: {} was not found.", type);
124         }
125         return parser;
126     }
127
128     public <T> void serializeTlv(final QName tlvQName, final T tlv, final ByteBuf buffer) {
129         if (tlv == null) {
130             return;
131         }
132         requireNonNull(tlvQName);
133         requireNonNull(buffer);
134         final LinkstateTlvParser.LinkstateTlvSerializer<T> tlvSerializer
135                 = (LinkstateTlvParser.LinkstateTlvSerializer<T>) this.tlvSerializers.get(tlvQName);
136         if (tlvSerializer == null) {
137             LOG.warn("Linkstate TLV serializer for QName: {} was not found.", tlvQName);
138             return;
139         }
140         final ByteBuf body = Unpooled.buffer();
141         tlvSerializer.serializeTlvBody(tlv, body);
142         TlvUtil.writeTLV(tlvSerializer.getType(), body, buffer);
143     }
144 }