BUG-2383: wire up AdjRibInWriter
[bgpcep.git] / bgp / rib-impl / src / main / java / org / opendaylight / protocol / bgp / rib / impl / TableContext.java
1 /*
2  * Copyright (c) 2015 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.rib.impl;
9
10 import com.google.common.base.Preconditions;
11 import com.google.common.base.Verify;
12 import com.google.common.collect.ImmutableSet;
13 import com.google.common.collect.ImmutableSet.Builder;
14 import java.util.Map.Entry;
15 import java.util.Set;
16 import javax.annotation.concurrent.NotThreadSafe;
17 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
18 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
19 import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.ClusterId;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.OriginatorId;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.PathAttributes;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.Aggregator;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.AsPath;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.Communities;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.ExtendedCommunities;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.LocalPref;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.MultiExitDisc;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.Origin;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.MpReachNlri;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.MpUnreachNlri;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Attributes;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Routes;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.BgpAggregator;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Community;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.ExtendedCommunity;
37 import org.opendaylight.yangtools.yang.binding.DataObject;
38 import org.opendaylight.yangtools.yang.common.QName;
39 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
40 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
41 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
42 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
43 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
44 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
45 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
46 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
47
48 /**
49  * A context for a single RIB table instance. It is always bound to a particular {@link AdjRibInWriter}.
50  *
51  * FIXME: need a better name once we local-rib and rib-out contexts
52  */
53 @NotThreadSafe
54 final class TableContext {
55     private static final ContainerNode EMPTY_TABLE_ATTRIBUTES = ImmutableNodes.containerNode(Attributes.QNAME);
56     private static final ContainerNode EMPTY_ROUTE_ATTRIBUTES = ImmutableNodes.containerNode(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.route.Attributes.QNAME);
57     private static final Set<Class<? extends DataObject>> ATTRIBUTE_CACHEABLES;
58
59     static {
60         final Builder<Class<? extends DataObject>> acb = ImmutableSet.builder();
61         acb.add(Aggregator.class);
62         acb.add(BgpAggregator.class);
63         acb.add(AsPath.class);
64         acb.add(ClusterId.class);
65         acb.add(Community.class);
66         acb.add(Communities.class);
67         acb.add(ExtendedCommunity.class);
68         acb.add(ExtendedCommunities.class);
69         acb.add(LocalPref.class);
70         acb.add(MultiExitDisc.class);
71         acb.add(Origin.class);
72         acb.add(OriginatorId.class);
73         ATTRIBUTE_CACHEABLES = acb.build();
74     }
75
76     private final YangInstanceIdentifier tableId;
77     private final RIBSupport tableSupport;
78     private final Object attributeCodec;
79     private final Object nlriCodec;
80
81     TableContext(final RIBSupport tableSupport, final YangInstanceIdentifier tableId) {
82         this.tableSupport = Preconditions.checkNotNull(tableSupport);
83         this.tableId = Preconditions.checkNotNull(tableId);
84
85         final Builder<Class<? extends DataObject>> acb = ImmutableSet.builder();
86         acb.addAll(ATTRIBUTE_CACHEABLES);
87         acb.addAll(tableSupport.cacheableAttributeObjects());
88
89         // FIXME: new Codec.create(acb.build(), tableSupport.cacheableNlriObjects());
90         this.attributeCodec = null;
91
92         // FIXME: new Codec.create(tableSupport.cacheableNlriObjects());
93         this.nlriCodec = null;
94     }
95
96     YangInstanceIdentifier getTableId() {
97         return this.tableId;
98     }
99
100     static void clearTable(final DOMDataWriteTransaction tx, final RIBSupport tableSupport, final YangInstanceIdentifier tableId) {
101         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> tb = ImmutableNodes.mapEntryBuilder();
102         tb.withNodeIdentifier((NodeIdentifierWithPredicates)tableId.getLastPathArgument());
103         tb.withChild(EMPTY_TABLE_ATTRIBUTES);
104
105         // tableId is keyed, but that fact is not directly visible from YangInstanceIdentifier, see BUG-2796
106         final NodeIdentifierWithPredicates tableKey = (NodeIdentifierWithPredicates) tableId.getLastPathArgument();
107         for (final Entry<QName, Object> e : tableKey.getKeyValues().entrySet()) {
108             tb.withChild(ImmutableNodes.leafNode(e.getKey(), e.getValue()));
109         }
110
111         final ChoiceNode routes = tableSupport.emptyRoutes();
112         Verify.verifyNotNull(routes, "Null empty routes in %s", tableSupport);
113         Verify.verify(Routes.QNAME.equals(routes.getNodeType()), "Empty routes have unexpected identifier %s, expected %s", routes.getNodeType(), Routes.QNAME);
114
115         tx.put(LogicalDatastoreType.OPERATIONAL, tableId, tb.withChild(routes).build());
116     }
117
118     void clearTable(final DOMDataWriteTransaction tx) {
119         clearTable(tx, this.tableSupport, this.tableId);
120     }
121
122     void removeTable(final DOMDataWriteTransaction tx) {
123         tx.delete(LogicalDatastoreType.OPERATIONAL, this.tableId);
124     }
125
126     void writeRoutes(final Object codecFactory, final DOMDataWriteTransaction tx, final MpReachNlri nlri, final PathAttributes attributes) {
127
128         // FIXME: run the decoder process
129         final ContainerNode domNlri = (ContainerNode) this.nlriCodec;
130
131         // FIXME: run the decoder process
132         final ContainerNode domAttributes = (ContainerNode) this.attributeCodec;
133         final ContainerNode routeAttributes = Builders.containerBuilder(EMPTY_ROUTE_ATTRIBUTES).withValue(domAttributes.getValue()).build();
134
135         this.tableSupport.putRoutes(tx, this.tableId, domNlri, routeAttributes);
136     }
137
138     void removeRoutes(final Object object, final DOMDataWriteTransaction tx, final MpUnreachNlri nlri) {
139         // FIXME: run the decoder process
140         final ContainerNode domNlri = (ContainerNode) this.nlriCodec;
141
142         this.tableSupport.deleteRoutes(tx, this.tableId, domNlri);
143     }
144 }