2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.protocol.bmp.impl.app;
10 import static com.google.common.base.Preconditions.checkState;
11 import static java.util.Objects.requireNonNull;
12 import static org.opendaylight.protocol.bmp.impl.app.TablesUtil.BMP_ATTRIBUTES_QNAME;
13 import static org.opendaylight.protocol.bmp.impl.app.TablesUtil.BMP_ROUTES_QNAME;
16 import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTree;
17 import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTreeNode;
18 import org.opendaylight.mdsal.binding.dom.codec.api.BindingDataObjectCodecTreeNode;
19 import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeCachingCodec;
20 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
21 import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
22 import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.Update;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.path.attributes.Attributes;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.path.attributes.AttributesBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.AttributesReach;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.AttributesUnreach;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.attributes.reach.MpReachNlri;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.attributes.unreach.MpUnreachNlri;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.tables.Routes;
31 import org.opendaylight.yangtools.yang.common.QName;
32 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
33 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
34 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
35 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
36 import org.opendaylight.yangtools.yang.data.spi.node.ImmutableNodes;
38 // This class is NOT thread-safe
39 final class TableContext {
41 private static final ContainerNode EMPTY_TABLE_ATTRIBUTES = ImmutableNodes.newContainerBuilder()
42 .withNodeIdentifier(NodeIdentifier.create(BMP_ATTRIBUTES_QNAME))
44 private static final NodeIdentifier BGP_ROUTES_NODE_ID = new NodeIdentifier(BMP_ROUTES_QNAME);
46 private final YangInstanceIdentifier tableId;
47 private final RIBSupport<?, ?> tableSupport;
48 private final BindingNormalizedNodeCachingCodec<Attributes> attributesCodec;
49 private final BindingNormalizedNodeCachingCodec<MpReachNlri> reachNlriCodec;
50 private final BindingNormalizedNodeCachingCodec<MpUnreachNlri> unreachNlriCodec;
52 @SuppressWarnings({ "unchecked", "rawtypes" })
53 TableContext(final RIBSupport tableSupport, final YangInstanceIdentifier tableId, final BindingCodecTree tree) {
54 this.tableSupport = requireNonNull(tableSupport);
55 this.tableId = requireNonNull(tableId);
56 final BindingCodecTreeNode tableCodecContext = tree.getSubtreeCodec(tableId);
58 checkState(tableCodecContext instanceof BindingDataObjectCodecTreeNode);
59 final BindingDataObjectCodecTreeNode<?> routeListCodec = ((BindingDataObjectCodecTreeNode)tableCodecContext)
60 .getStreamChild(Routes.class)
61 .getStreamChild(this.tableSupport.routesCaseClass())
62 .getStreamChild(this.tableSupport.routesContainerClass())
63 .getStreamDataObject(this.tableSupport.routesListClass());
65 attributesCodec = routeListCodec.getStreamDataObject(Attributes.class)
66 .createCachingCodec(this.tableSupport.cacheableAttributeObjects());
68 final var updateAttributesCodec = tree.getStreamChild(Update.class)
69 .getStreamDataObject(Attributes.class);
70 reachNlriCodec = updateAttributesCodec.getStreamChild(AttributesReach.class)
71 .getStreamDataObject(MpReachNlri.class)
72 .createCachingCodec(this.tableSupport.cacheableNlriObjects());
73 unreachNlriCodec = updateAttributesCodec.getStreamChild(AttributesUnreach.class)
74 .getStreamDataObject(MpUnreachNlri.class)
75 .createCachingCodec(this.tableSupport.cacheableNlriObjects());
78 YangInstanceIdentifier getTableId() {
82 void createTable(final DOMDataTreeWriteTransaction tx) {
83 final var tb = ImmutableNodes.newMapEntryBuilder()
84 .withNodeIdentifier((NodeIdentifierWithPredicates) tableId.getLastPathArgument())
85 .withChild(EMPTY_TABLE_ATTRIBUTES);
87 // tableId is keyed, but that fact is not directly visible from YangInstanceIdentifier, see BUG-2796
88 final var tableKey = (NodeIdentifierWithPredicates) tableId.getLastPathArgument();
89 for (final Map.Entry<QName, Object> e : tableKey.entrySet()) {
90 tb.withChild(ImmutableNodes.leafNode(e.getKey(), e.getValue()));
93 tx.put(LogicalDatastoreType.OPERATIONAL, tableId,
94 tb.withChild(ImmutableNodes.newChoiceBuilder()
95 .withNodeIdentifier(new NodeIdentifier(TablesUtil.BMP_ROUTES_QNAME))
100 void writeRoutes(final DOMDataTreeWriteTransaction tx, final MpReachNlri nlri, final Attributes attributes) {
101 final ContainerNode domNlri = serializeReachNlri(nlri);
102 final ContainerNode routeAttributes = serializeAttributes(attributes);
103 tableSupport.putRoutes(tx, tableId, domNlri, routeAttributes, BGP_ROUTES_NODE_ID);
106 void removeRoutes(final DOMDataTreeWriteTransaction tx, final MpUnreachNlri nlri) {
107 tableSupport.deleteRoutes(tx, tableId, serializeUnreachNlri(nlri), BGP_ROUTES_NODE_ID);
110 private ContainerNode serializeUnreachNlri(final MpUnreachNlri nlri) {
111 checkState(unreachNlriCodec != null, "MpUnReachNlri codec not available");
112 return (ContainerNode) unreachNlriCodec.serialize(nlri);
115 private ContainerNode serializeReachNlri(final MpReachNlri nlri) {
116 checkState(reachNlriCodec != null, "MpReachNlri codec not available");
117 return (ContainerNode) reachNlriCodec.serialize(nlri);
120 private ContainerNode serializeAttributes(final Attributes pathAttr) {
121 checkState(attributesCodec != null, "Attributes codec not available");
122 final AttributesBuilder a = new AttributesBuilder(pathAttr);
123 a.removeAugmentation(AttributesReach.class);
124 a.removeAugmentation(AttributesUnreach.class);
125 return (ContainerNode) attributesCodec.serialize(a.build());