org.opendaylight.protocol.bmp.impl.app.TableContext Maven / Gradle / Ivy
/*
* Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.protocol.bmp.impl.app;
import static com.google.common.base.Preconditions.checkState;
import static java.util.Objects.requireNonNull;
import static org.opendaylight.protocol.bmp.impl.app.TablesUtil.BMP_ATTRIBUTES_QNAME;
import static org.opendaylight.protocol.bmp.impl.app.TablesUtil.BMP_ROUTES_QNAME;
import java.util.Map;
import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.Update;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.path.attributes.Attributes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.path.attributes.AttributesBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.AttributesReach;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.AttributesUnreach;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.attributes.reach.MpReachNlri;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.attributes.unreach.MpUnreachNlri;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.tables.Routes;
import org.opendaylight.yangtools.binding.data.codec.api.BindingCodecTree;
import org.opendaylight.yangtools.binding.data.codec.api.BindingCodecTreeNode;
import org.opendaylight.yangtools.binding.data.codec.api.BindingDataObjectCodecTreeNode;
import org.opendaylight.yangtools.binding.data.codec.api.BindingNormalizedNodeCachingCodec;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
import org.opendaylight.yangtools.yang.data.spi.node.ImmutableNodes;
// This class is NOT thread-safe
final class TableContext {
private static final ContainerNode EMPTY_TABLE_ATTRIBUTES = ImmutableNodes.newContainerBuilder()
.withNodeIdentifier(NodeIdentifier.create(BMP_ATTRIBUTES_QNAME))
.build();
private static final NodeIdentifier BGP_ROUTES_NODE_ID = new NodeIdentifier(BMP_ROUTES_QNAME);
private final YangInstanceIdentifier tableId;
private final RIBSupport, ?> tableSupport;
private final BindingNormalizedNodeCachingCodec attributesCodec;
private final BindingNormalizedNodeCachingCodec reachNlriCodec;
private final BindingNormalizedNodeCachingCodec unreachNlriCodec;
@SuppressWarnings({ "unchecked", "rawtypes" })
TableContext(final RIBSupport tableSupport, final YangInstanceIdentifier tableId, final BindingCodecTree tree) {
this.tableSupport = requireNonNull(tableSupport);
this.tableId = requireNonNull(tableId);
final BindingCodecTreeNode tableCodecContext = tree.getSubtreeCodec(tableId);
checkState(tableCodecContext instanceof BindingDataObjectCodecTreeNode);
final BindingDataObjectCodecTreeNode> routeListCodec = ((BindingDataObjectCodecTreeNode)tableCodecContext)
.getStreamChild(Routes.class)
.getStreamChild(this.tableSupport.routesCaseClass())
.getStreamChild(this.tableSupport.routesContainerClass())
.getStreamDataObject(this.tableSupport.routesListClass());
attributesCodec = routeListCodec.getStreamDataObject(Attributes.class)
.createCachingCodec(this.tableSupport.cacheableAttributeObjects());
final var updateAttributesCodec = tree.getStreamChild(Update.class)
.getStreamDataObject(Attributes.class);
reachNlriCodec = updateAttributesCodec.getStreamChild(AttributesReach.class)
.getStreamDataObject(MpReachNlri.class)
.createCachingCodec(this.tableSupport.cacheableNlriObjects());
unreachNlriCodec = updateAttributesCodec.getStreamChild(AttributesUnreach.class)
.getStreamDataObject(MpUnreachNlri.class)
.createCachingCodec(this.tableSupport.cacheableNlriObjects());
}
YangInstanceIdentifier getTableId() {
return tableId;
}
void createTable(final DOMDataTreeWriteTransaction tx) {
final var tb = ImmutableNodes.newMapEntryBuilder()
.withNodeIdentifier((NodeIdentifierWithPredicates) tableId.getLastPathArgument())
.withChild(EMPTY_TABLE_ATTRIBUTES);
// tableId is keyed, but that fact is not directly visible from YangInstanceIdentifier, see BUG-2796
final var tableKey = (NodeIdentifierWithPredicates) tableId.getLastPathArgument();
for (final Map.Entry e : tableKey.entrySet()) {
tb.withChild(ImmutableNodes.leafNode(e.getKey(), e.getValue()));
}
tx.put(LogicalDatastoreType.OPERATIONAL, tableId,
tb.withChild(ImmutableNodes.newChoiceBuilder()
.withNodeIdentifier(new NodeIdentifier(TablesUtil.BMP_ROUTES_QNAME))
.build())
.build());
}
void writeRoutes(final DOMDataTreeWriteTransaction tx, final MpReachNlri nlri, final Attributes attributes) {
final ContainerNode domNlri = serializeReachNlri(nlri);
final ContainerNode routeAttributes = serializeAttributes(attributes);
tableSupport.putRoutes(tx, tableId, domNlri, routeAttributes, BGP_ROUTES_NODE_ID);
}
void removeRoutes(final DOMDataTreeWriteTransaction tx, final MpUnreachNlri nlri) {
tableSupport.deleteRoutes(tx, tableId, serializeUnreachNlri(nlri), BGP_ROUTES_NODE_ID);
}
private ContainerNode serializeUnreachNlri(final MpUnreachNlri nlri) {
checkState(unreachNlriCodec != null, "MpUnReachNlri codec not available");
return (ContainerNode) unreachNlriCodec.serialize(nlri);
}
private ContainerNode serializeReachNlri(final MpReachNlri nlri) {
checkState(reachNlriCodec != null, "MpReachNlri codec not available");
return (ContainerNode) reachNlriCodec.serialize(nlri);
}
private ContainerNode serializeAttributes(final Attributes pathAttr) {
checkState(attributesCodec != null, "Attributes codec not available");
final AttributesBuilder a = new AttributesBuilder(pathAttr);
a.removeAugmentation(AttributesReach.class);
a.removeAugmentation(AttributesUnreach.class);
return (ContainerNode) attributesCodec.serialize(a.build());
}
}