Bump MDSAL to 4.0.0
[bgpcep.git] / bgp / topology-provider / src / main / java / org / opendaylight / bgpcep / bgp / topology / provider / UriBuilder.java
1 /*
2  * Copyright (c) 2013 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.bgpcep.bgp.topology.provider;
9
10 import com.google.common.io.BaseEncoding;
11 import com.google.common.primitives.UnsignedBytes;
12 import java.util.Arrays;
13 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.IsisAreaIdentifier;
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.NodeIdentifier;
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.linkstate.object.type.LinkCase;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.linkstate.object.type.link._case.LinkDescriptors;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.linkstate.routes.linkstate.routes.LinkstateRoute;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.node.identifier.CRouterIdentifier;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.node.identifier.c.router.identifier.IsisNodeCase;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.node.identifier.c.router.identifier.IsisPseudonodeCase;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.node.identifier.c.router.identifier.OspfNodeCase;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.node.identifier.c.router.identifier.OspfPseudonodeCase;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.node.identifier.c.router.identifier.isis.pseudonode._case.IsisPseudonode;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.node.identifier.c.router.identifier.ospf.pseudonode._case.OspfPseudonode;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.IsoSystemIdentifier;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 final class UriBuilder {
30     private static final Logger LOG = LoggerFactory.getLogger(UriBuilder.class);
31     private static final char HEX_SEPARATOR = '.';
32     private static final int AREA_ID_MAX_SIZE = 7;
33     private final StringBuilder sb;
34
35     UriBuilder(final UriBuilder base, final String type) {
36         this.sb = new StringBuilder(base.sb);
37         this.sb.append("type=").append(type);
38     }
39
40     UriBuilder(final LinkstateRoute route) {
41         this.sb = new StringBuilder("bgpls://");
42
43         if (route.getRouteDistinguisher() != null) {
44             String rd;
45             if (route.getRouteDistinguisher().getRdAs() != null) {
46                 rd = route.getRouteDistinguisher().getRdAs().getValue();
47             } else if (route.getRouteDistinguisher().getRdIpv4() != null) {
48                 rd = route.getRouteDistinguisher().getRdIpv4().getValue();
49             } else  {
50                 rd = route.getRouteDistinguisher().getRdTwoOctetAs().getValue();
51             }
52             this.sb.append(rd).append(':');
53         }
54
55         this.sb.append(route.getProtocolId().toString()).append(':')
56                 .append(route.getIdentifier().getValue().toString()).append('/');
57     }
58
59     UriBuilder add(final String name, final Object value) {
60         if (value != null) {
61             this.sb.append('&').append(name).append('=').append(value.toString());
62         }
63         return this;
64     }
65
66     UriBuilder add(final LinkCase link) {
67         addPrefix("local-", link.getLocalNodeDescriptors());
68         addPrefix("remote-", link.getRemoteNodeDescriptors());
69
70         final LinkDescriptors ld = link.getLinkDescriptors();
71         if (ld.getIpv4InterfaceAddress() != null) {
72             add("ipv4-iface", ld.getIpv4InterfaceAddress().getValue());
73         }
74         if (ld.getIpv4NeighborAddress() != null) {
75             add("ipv4-neigh", ld.getIpv4NeighborAddress().getValue());
76         }
77         if (ld.getIpv6InterfaceAddress() != null) {
78             add("ipv6-iface", ld.getIpv6InterfaceAddress().getValue());
79         }
80         if (ld.getIpv6NeighborAddress() != null) {
81             add("ipv6-neigh", ld.getIpv6NeighborAddress().getValue());
82         }
83         if (ld.getMultiTopologyId() != null) {
84             add("mt", ld.getMultiTopologyId().getValue());
85         }
86         add("local-id", ld.getLinkLocalIdentifier());
87         add("remote-id", ld.getLinkRemoteIdentifier());
88         return this;
89     }
90
91     private static String isoId(final byte[] bytes) {
92         final StringBuilder sBuilder = new StringBuilder();
93         int id = 0;
94         while (id < bytes.length) {
95             sBuilder.append(BaseEncoding.base16().encode(new byte[] { bytes[id++], bytes[id++] }));
96             if (id != bytes.length) {
97                 sBuilder.append(HEX_SEPARATOR);
98             }
99         }
100         return sBuilder.toString();
101     }
102
103     /**
104      * Creates a String representation of ISO system identifier
105      * in format XX.XX.XX where X is one byte.
106      *
107      * @param systemId IsoSystemIdentifier object
108      * @return String representation of ISO Identifier
109      */
110     public static String isoId(final IsoSystemIdentifier systemId) {
111         return isoId(systemId.getValue());
112     }
113
114     private static String formatRouterIdentifier(final CRouterIdentifier routerIdentifier) {
115         if (routerIdentifier == null) {
116             return null;
117         }
118         if (routerIdentifier instanceof IsisNodeCase) {
119             return isoId(((IsisNodeCase) routerIdentifier).getIsisNode().getIsoSystemId());
120         }
121         if (routerIdentifier instanceof IsisPseudonodeCase) {
122             final IsisPseudonode r = ((IsisPseudonodeCase) routerIdentifier).getIsisPseudonode();
123             return isoId(r.getIsIsRouterIdentifier().getIsoSystemId().getValue()) + '.'
124                     + BaseEncoding.base16().encode(new byte[] { UnsignedBytes.checkedCast(r.getPsn()) });
125         }
126         if (routerIdentifier instanceof OspfNodeCase) {
127             return ((OspfNodeCase) routerIdentifier).getOspfNode().getOspfRouterId().toString();
128         }
129         if (routerIdentifier instanceof OspfPseudonodeCase) {
130             final OspfPseudonode r = ((OspfPseudonodeCase) routerIdentifier).getOspfPseudonode();
131             return r.getOspfRouterId().toString() + ':' + r.getLanInterface().getValue();
132         }
133         LOG.warn("Unhandled router identifier type {}, fallback to toString()",
134                 routerIdentifier.implementedInterface());
135         return routerIdentifier.toString();
136     }
137
138     UriBuilder addPrefix(final String prefix, final NodeIdentifier node) {
139         if (node.getAsNumber() != null) {
140             add(prefix + "as", node.getAsNumber().getValue());
141         }
142         if (node.getDomainId() != null) {
143             add(prefix + "domain", node.getDomainId().getValue());
144         }
145         if (node.getAreaId() != null) {
146             add(prefix + "area", node.getAreaId().getValue());
147         }
148         add(prefix + "router", formatRouterIdentifier(node.getCRouterIdentifier()));
149         return this;
150     }
151
152     @Override
153     public String toString() {
154         final String ret = this.sb.toString();
155         LOG.trace("New URI {}", ret);
156         return ret;
157     }
158
159     /**
160      * Creates string representation of IS-IS Network Entity Title,
161      * based on Area Identifier and System Identifier.
162      *
163      * @param areaId IS-IS Area Identifier
164      * @param systemId string representation of ISO SYSTEM-ID
165      * @return ISO NET ID
166      */
167     public static String toIsoNetId(final IsisAreaIdentifier areaId, final String systemId) {
168         final byte[] value = areaId.getValue();
169         //first byte is AFI
170         //ISIS area identifier might have variable length, but need to fit the IsoNetId pattern
171         return BaseEncoding.base16().encode(value, 0, 1) + HEX_SEPARATOR
172                 + UriBuilder.isoId(Arrays.copyOfRange(value, 1, AREA_ID_MAX_SIZE)) + HEX_SEPARATOR + systemId;
173     }
174 }