Bump mdsal to 5.0.2
[bgpcep.git] / bgp / parser-spi / src / main / java / org / opendaylight / protocol / bgp / parser / spi / PathIdUtil.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
9 package org.opendaylight.protocol.bgp.parser.spi;
10
11 import com.google.common.base.Preconditions;
12 import io.netty.buffer.ByteBuf;
13 import java.util.Optional;
14 import org.opendaylight.protocol.util.ByteBufWriteUtil;
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.PathId;
16 import org.opendaylight.yangtools.util.ImmutableOffsetMapTemplate;
17 import org.opendaylight.yangtools.yang.common.QName;
18 import org.opendaylight.yangtools.yang.common.Uint32;
19 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
20 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
21 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
22 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
23 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
24 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
25 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
26
27 public final class PathIdUtil {
28     public static final Uint32 NON_PATH_ID_VALUE = Uint32.ZERO;
29     public static final PathId NON_PATH_ID = new PathId(NON_PATH_ID_VALUE);
30
31     private PathIdUtil() {
32         throw new UnsupportedOperationException();
33     }
34
35     /**
36      * Writes path-id value into the buffer when
37      * the path-id is not null or does not equal to zero.
38      *
39      * @param pathId The NLRI Path Identifier.
40      * @param buffer The ByteBuf where path-id value can be written.
41      */
42     public static void writePathId(final PathId pathId, final ByteBuf buffer) {
43         if (pathId != null) {
44             final Uint32 value = pathId.getValue();
45             if (value.toJava() != 0) {
46                 ByteBufWriteUtil.writeUnsignedInt(value, buffer);
47             }
48         }
49     }
50
51     /**
52      * Reads Path Identifier (4 bytes) from buffer.
53      *
54      * @param buffer Input buffer.
55      * @return Decoded PathId.
56      */
57     public static PathId readPathId(final ByteBuf buffer) {
58         Preconditions.checkArgument(buffer != null && buffer.isReadable(ByteBufWriteUtil.INT_BYTES_LENGTH));
59         return new PathId(buffer.readUnsignedInt());
60     }
61
62     /**
63      * Extract PathId from route change received.
64      *
65      * @param data    Data containing the path Id
66      * @param pathNii Path Id NodeIdentifier specific per each Rib support
67      * @return The path identifier from data change
68      */
69     public static Uint32 extractPathId(final NormalizedNode<?, ?> data, final NodeIdentifier pathNii) {
70         return (Uint32) NormalizedNodes.findNode(data, pathNii).map(NormalizedNode::getValue).orElse(null);
71     }
72
73     /**
74      * Build Path Id.
75      *
76      * @param routesCont route container
77      * @param pathIdNii  path Id node Identifier
78      * @return PathId or null in case is not the container
79      */
80     public static PathId buildPathId(final DataContainerNode<? extends PathArgument> routesCont,
81             final NodeIdentifier pathIdNii) {
82         final Uint32 pathIdVal = PathIdUtil.extractPathId(routesCont, pathIdNii);
83         return pathIdVal == null ? null : new PathId(pathIdVal);
84     }
85
86     /**
87      * Build Route Key for supporting mp.
88      * Key is composed by 2 elements (route-key + path Id).
89      *
90      * @param routeQName       route QName
91      * @param routeKeyTemplate route key template
92      * @param routeKeyValue    route key value
93      * @param maybePathIdLeaf  path id container, it might me supported or not, in that case default 0 value will
94      *                         be assigned
95      * @return Route Key Nid
96      */
97     public static NodeIdentifierWithPredicates createNidKey(final QName routeQName,
98             final ImmutableOffsetMapTemplate<QName> routeKeyTemplate, final Object routeKeyValue,
99             final Optional<DataContainerChild<? extends PathArgument, ?>> maybePathIdLeaf) {
100         // FIXME: a cache here would mean we instantiate the same identifier for each route making comparison quicker.
101         final Object pathId = maybePathIdLeaf.isPresent() ? maybePathIdLeaf.get().getValue() : NON_PATH_ID_VALUE;
102         return NodeIdentifierWithPredicates.of(routeQName,
103             routeKeyTemplate.instantiateWithValues(pathId, routeKeyValue));
104     }
105 }