Checkstyle: fix issues and enforce on lisp-proto
[lispflowmapping.git] / mappingservice / lisp-proto / src / main / java / org / opendaylight / lispflowmapping / lisp / util / LispAddressStringifier.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc.  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.lispflowmapping.lisp.util;
9
10 import com.google.common.base.Preconditions;
11 import com.google.common.io.BaseEncoding;
12 import com.google.common.net.InetAddresses;
13 import java.net.Inet4Address;
14 import java.net.Inet6Address;
15 import java.net.UnknownHostException;
16 import java.util.List;
17 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.LispAddress;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.SimpleAddress;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.Address;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.AfiList;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.ApplicationData;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.AsNumber;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.DistinguishedName;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.ExplicitLocatorPath;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.InstanceId;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv4;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv4Prefix;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv6;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv6Prefix;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.KeyValueAddress;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Mac;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.NoAddress;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.ServicePath;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.SourceDestKey;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.explicit.locator.path.explicit.locator.path.Hop;
36 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.explicit.locator.path.explicit.locator.path.Hop.LrsBits;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.binary.address.types.rev160504.augmented.lisp.address.address.Ipv4Binary;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.binary.address.types.rev160504.augmented.lisp.address.address.Ipv4PrefixBinary;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.binary.address.types.rev160504.augmented.lisp.address.address.Ipv6Binary;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.binary.address.types.rev160504.augmented.lisp.address.address.Ipv6PrefixBinary;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.XtrId;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44
45 /**
46  * Utility class with static methods returning string representations of
47  * supported LISP address types, both for use in URLs and for user friendly
48  * output.
49  *
50  * @author Lorand Jakab
51  *
52  */
53 public class LispAddressStringifier {
54     protected static final Logger LOG = LoggerFactory.getLogger(LispAddressStringifier.class);
55
56     private static final String PREFIX_SEPARATOR = ":";
57
58     /*
59      * In the unlikely event that a AFI 0 address is used a key, we use a
60      * sequence number to ensure uniqueness
61      */
62     protected static int noAddrSeq = 0;
63
64     /*
65      * There are three possible destinations for rendering an address as a
66      * string:
67      *
68      *   * General user interaction, like log and CLI output, GUI
69      *     representation, etc.
70      *   * As a URI string that is the entry key in the MD-SAL datastore
71      *   * As a URL string that is the same as the URI string, except for
72      *     characters not accepted in URLs are percent encoded (e.g. '/' is
73      *     encoded as '%2f'
74      */
75     protected enum Destination {
76         USER,
77         URI,
78         URL;
79     }
80
81     public static String getString(LispAddress lispAddress) {
82         return getAddrString(Destination.USER, lispAddress);
83     }
84
85     public static String getString(XtrId xtrId) {
86         return getXtrIdString(xtrId);
87     }
88
89     public static String getURIString(LispAddress lispAddress) {
90         return getAddrString(Destination.URI, lispAddress);
91     }
92
93     public static String getURIString(XtrId xtrId) {
94         return getXtrIdString(xtrId);
95     }
96
97     public static String getURLString(LispAddress lispAddress) {
98         return getAddrString(Destination.URL, lispAddress);
99     }
100
101     public static String getURLString(XtrId xtrId) {
102         return getXtrIdString(xtrId);
103     }
104
105     private static String getXtrIdString(XtrId xtrId) {
106         return BaseEncoding.base16().encode(xtrId.getValue());
107     }
108
109     private static String getAddrString(Destination dst, LispAddress lispAddress) {
110         Preconditions.checkNotNull(lispAddress, "lispAddress should not be null");
111         Address addr = lispAddress.getAddress();
112         String prefix = "";
113         String vni = "";
114         String address = "";
115
116         if (lispAddress.getVirtualNetworkId() != null) {
117             vni = "[" + lispAddress.getVirtualNetworkId().getValue() + "] ";
118         }
119
120         if (addr instanceof Ipv4) {
121             prefix = "ipv4" + PREFIX_SEPARATOR;
122             address = getStringFromIpv4(dst, (Ipv4) addr);
123         } else if (addr instanceof Ipv4Binary) {
124             prefix = "ipv4" + PREFIX_SEPARATOR;
125             address = getStringFromIpv4Binary(dst, (Ipv4Binary) addr);
126         } else if (addr instanceof Ipv4Prefix) {
127             prefix = "ipv4" + PREFIX_SEPARATOR;
128             address = getStringFromIpv4Prefix(dst, (Ipv4Prefix) addr);
129         } else if (addr instanceof Ipv4PrefixBinary) {
130             prefix = "ipv4" + PREFIX_SEPARATOR;
131             address = getStringFromIpv4PrefixBinary(dst, (Ipv4PrefixBinary) addr);
132         } else if (addr instanceof Ipv6) {
133             prefix = "ipv6" + PREFIX_SEPARATOR;
134             address = getStringFromIpv6(dst, (Ipv6) addr);
135         } else if (addr instanceof Ipv6Binary) {
136             prefix = "ipv6" + PREFIX_SEPARATOR;
137             address = getStringFromIpv6Binary(dst, (Ipv6Binary) addr);
138         } else if (addr instanceof Ipv6Prefix) {
139             prefix = "ipv6" + PREFIX_SEPARATOR;
140             address = getStringFromIpv6Prefix(dst, (Ipv6Prefix) addr);
141         } else if (addr instanceof Ipv6PrefixBinary) {
142             prefix = "ipv6" + PREFIX_SEPARATOR;
143             address = getStringFromIpv6PrefixBinary(dst, (Ipv6PrefixBinary) addr);
144         } else if (addr instanceof Mac) {
145             prefix = "mac" + PREFIX_SEPARATOR;
146             address = getStringFromMac(dst, (Mac) addr);
147         } else if (addr instanceof InstanceId) {
148             SimpleAddress pa = ((InstanceId)addr).getInstanceId().getAddress();
149             // Instance ID is a separate parent hierarchy, so we use the simple address prefix
150             prefix = LispSimpleAddressStringifier.getURLPrefix(pa) + PREFIX_SEPARATOR;
151             address = getStringFromInstanceId(dst, (InstanceId) addr);
152         } else if (addr instanceof NoAddress) {
153             prefix = "no" + PREFIX_SEPARATOR;
154             address = getStringFromNoAddress(dst, (NoAddress) addr);
155         } else if (addr instanceof DistinguishedName) {
156             prefix = "dn" + PREFIX_SEPARATOR;
157             address = getStringFromDistinguishedName(dst, (DistinguishedName) addr);
158         } else if (addr instanceof AsNumber) {
159             prefix = "as" + PREFIX_SEPARATOR;
160             address = getStringFromAsNumber(dst, (AsNumber) addr);
161         } else if (addr instanceof AfiList) {
162             prefix = "list" + PREFIX_SEPARATOR;
163             address = getStringFromAfiList(dst, (AfiList) addr);
164         } else if (addr instanceof ApplicationData) {
165             prefix = "appdata" + PREFIX_SEPARATOR;
166             address = getStringFromApplicationData(dst, (ApplicationData) addr);
167         } else if (addr instanceof ExplicitLocatorPath) {
168             prefix = "elp" + PREFIX_SEPARATOR;
169             address = getStringFromExplicitLocatorPath(dst, (ExplicitLocatorPath) addr);
170         } else if (addr instanceof SourceDestKey) {
171             prefix = "srcdst" + PREFIX_SEPARATOR;
172             address = getStringFromSourceDestKey(dst, (SourceDestKey) addr);
173         } else if (addr instanceof KeyValueAddress) {
174             prefix = "kv" + PREFIX_SEPARATOR;
175             address = getStringFromKeyValueAddress(dst, (KeyValueAddress) addr);
176         } else if (addr instanceof ServicePath) {
177             prefix = "sp" + PREFIX_SEPARATOR;
178             address = getStringFromServicePath(dst, (ServicePath) addr);
179         } else {
180             return null;
181         }
182
183         if (dst == Destination.USER) {
184             return vni + address;
185         } else {
186             return prefix + address;
187         }
188
189     }
190
191     private static String getPrefixString(Destination dst, String prefix) {
192         if (dst == Destination.URL) {
193             return prefix.replace("/", "%2f");
194         } else {
195             return prefix;
196         }
197     }
198
199     protected static String getStringFromNoAddress(Destination dst, NoAddress addr) {
200         // AFI = 0
201         if (dst == Destination.USER) {
202             return "No Address Present";
203         } else {
204             return "" + noAddrSeq++;
205         }
206     }
207
208     protected static String getStringFromIpv4(Destination dst, Ipv4 addr) {
209         // AFI = 1; IPv4
210         return addr.getIpv4().getValue();
211     }
212
213     protected static String getStringFromIpv4Binary(Destination dst, Ipv4Binary addr) {
214         // AFI = 1; IPv4
215         try {
216             return InetAddresses.toAddrString(Inet4Address.getByAddress(addr.getIpv4Binary().getValue()));
217         } catch (UnknownHostException e) {
218             LOG.debug("Cannot convert binary IPv4 to string", e);
219         }
220         return null;
221     }
222
223     protected static String getStringFromIpv4Prefix(Destination dst, Ipv4Prefix addr) {
224         // AFI = 1; IPv4
225         String prefix = addr.getIpv4Prefix().getValue();
226         return getPrefixString(dst, prefix);
227     }
228
229     protected static String getStringFromIpv4PrefixBinary(Destination dst, Ipv4PrefixBinary addr) {
230         // AFI = 1; IPv4
231         try {
232             StringBuilder prefixBuilder = new StringBuilder(InetAddresses.toAddrString(
233                     Inet4Address.getByAddress(addr.getIpv4AddressBinary().getValue())));
234             prefixBuilder.append('/');
235             prefixBuilder.append(addr.getIpv4MaskLength().toString());
236             return getPrefixString(dst, prefixBuilder.toString());
237         } catch (UnknownHostException e) {
238             LOG.debug("Cannot convert binary IPv4 prefix to string", e);
239         }
240         return null;
241     }
242
243     protected static String getStringFromIpv6(Destination dst, Ipv6 addr) {
244         // AFI = 2; IPv6
245         return addr.getIpv6().getValue();
246     }
247
248     protected static String getStringFromIpv6Binary(Destination dst, Ipv6Binary addr) {
249         // AFI = 2; IPv6
250         try {
251             return InetAddresses.toAddrString(Inet6Address.getByAddress(addr.getIpv6Binary().getValue()));
252         } catch (UnknownHostException e) {
253             LOG.debug("Cannot convert binary IPv6 to string", e);
254         }
255         return null;
256     }
257
258     protected static String getStringFromIpv6Prefix(Destination dst, Ipv6Prefix addr) {
259         // AFI = 2; IPv6
260         return addr.getIpv6Prefix().getValue();
261     }
262
263     protected static String getStringFromIpv6PrefixBinary(Destination dst, Ipv6PrefixBinary addr) {
264         // AFI = 2; IPv5
265         try {
266             StringBuilder prefixBuilder = new StringBuilder(InetAddresses.toAddrString(
267                     Inet6Address.getByAddress(addr.getIpv6AddressBinary().getValue())));
268             prefixBuilder.append('/');
269             prefixBuilder.append(addr.getIpv6MaskLength().toString());
270             return getPrefixString(dst, prefixBuilder.toString());
271         } catch (UnknownHostException e) {
272             LOG.debug("Cannot convert binary IPv6 prefix to string", e);
273         }
274         return null;
275     }
276
277     protected static String getStringFromDistinguishedName(Destination dst, DistinguishedName addr) {
278         // AFI = 17; Distinguished Name
279         return addr.getDistinguishedName().getValue();
280     }
281
282     protected static String getStringFromAsNumber(Destination dst, AsNumber addr) {
283         // AFI = 18; Autonomous System Number
284         return "AS" + addr.getAsNumber().getValue();
285     }
286
287     protected static String getStringFromAfiList(Destination dst, AfiList addr) {
288         // AFI 16387, LCAF Type 1; Address List
289         // Example rendering:
290         //    {192.0.2.1,192.0.2.2,2001:db8::1}
291         List<SimpleAddress> addresses = addr.getAfiList().getAddressList();
292         StringBuilder sb = new StringBuilder("{");
293         boolean needComma = false;
294         for (SimpleAddress a : addresses) {
295             if (needComma) {
296                 sb.append(",");
297             }
298             sb.append(a.getValue());
299             needComma = true;
300         }
301         sb.append("}");
302         return sb.toString();
303     }
304
305     protected static String getStringFromInstanceId(Destination dst, InstanceId addr) {
306         // AFI = 16387, LCAF Type 2; Instance ID
307         // Example rendering:
308         //    [223] 192.0.2.0/24
309         SimpleAddress pa = addr.getInstanceId().getAddress();
310         if (dst == Destination.USER) {
311             return "[" + addr.getInstanceId().getIid().getValue() + "] "
312                     + LispSimpleAddressStringifier.getString(dst, pa);
313         } else {
314             return LispSimpleAddressStringifier.getString(dst, pa);
315         }
316     }
317
318     protected static String getStringFromApplicationData(Destination dst, ApplicationData addr) {
319         // AFI = 16387, LCAF Type 4; Application Data
320         // Example rendering:
321         //    192.0.2.1!128!17!80-81!6667-7000
322         return LispSimpleAddressStringifier.getString(dst, addr.getApplicationData().getAddress())
323                 + "!" + addr.getApplicationData().getIpTos()
324                 + "!" + addr.getApplicationData().getProtocol()
325                 + "!" + addr.getApplicationData().getLocalPortLow()
326                 + "-" + addr.getApplicationData().getLocalPortHigh()
327                 + "!" + addr.getApplicationData().getRemotePortLow()
328                 + "-" + addr.getApplicationData().getRemotePortHigh();
329     }
330
331     protected static String getStringFromExplicitLocatorPath(Destination dst, ExplicitLocatorPath addr) {
332         // AFI = 16387, LCAF Type 10, Explicit Locator Path
333         // Example rendering:
334         //    {192.0.2.1->192.0.2.2|lps->192.0.2.3}
335         List<Hop> hops = addr.getExplicitLocatorPath().getHop();
336         StringBuilder sb = new StringBuilder();
337         sb.append("{");
338         boolean needArrow = false;
339         for (Hop hop : hops) {
340             if (needArrow) {
341                 sb.append("->");
342             }
343             sb.append(LispSimpleAddressStringifier.getString(dst, hop.getAddress()));
344             LrsBits lrs = hop.getLrsBits();
345             if (lrs.isLookup() || lrs.isRlocProbe() || lrs.isStrict()) {
346                 sb.append("|");
347             }
348             if (lrs.isLookup()) {
349                 sb.append("l");
350             }
351             if (lrs.isRlocProbe()) {
352                 sb.append("p");
353             }
354             if (lrs.isStrict()) {
355                 sb.append("s");
356             }
357             needArrow = true;
358         }
359         sb.append("}");
360         return sb.toString();
361     }
362
363     protected static String getStringFromSourceDestKey(Destination dst, SourceDestKey addr) {
364         // AFI = 16387, LCAF Type 12, Source/Destination Key
365         // Example rendering:
366         //    192.0.2.1/32|192.0.2.2/32
367         return getPrefixString(dst, (new String(addr.getSourceDestKey().getSource().getValue()))
368                 + "|" + getPrefixString(dst, new String(addr.getSourceDestKey().getDest().getValue())));
369     }
370
371     protected static String getStringFromKeyValueAddress(Destination dst, KeyValueAddress addr) {
372         // AFI = 16387, LCAF Type 15, Key/Value Address Pair
373         // Example rendering:
374         //    192.0.2.1=>192.0.2.2
375         return getPrefixString(dst, new String(addr.getKeyValueAddress().getKey().getValue())
376                 + "=>" + getPrefixString(dst, new String(addr.getKeyValueAddress().getValue().getValue())));
377     }
378
379     protected static String getStringFromMac(Destination dst, Mac addr) {
380         // AFI = 16389; MAC
381         return addr.getMac().getValue();
382     }
383
384     protected static String getStringFromServicePath(Destination dst, ServicePath addr) {
385         // AFI = 16387; LCAF http://tools.ietf.org/html/draft-ermagan-lisp-nsh-00
386         // Example rendering:
387         //     42(3)
388         return getPrefixString(dst, new String(addr.getServicePath().getServicePathId().getValue() + "("
389                 + addr.getServicePath().getServiceIndex() + ")"));
390     }
391
392 }