Migrate lisp-proto implementation to IETF YANG model
[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 java.util.List;
11
12 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.LispAddress;
13 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.SimpleAddress;
14 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.Address;
15 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.AfiList;
16 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.ApplicationData;
17 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.AsNumber;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.DistinguishedName;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.ExplicitLocatorPath;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.InstanceId;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv4;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv4Prefix;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv6;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv6Prefix;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.KeyValueAddress;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Mac;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.NoAddress;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.SourceDestKey;
29 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;
30 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;
31
32 import com.google.common.base.Preconditions;
33
34 /**
35  * Utility class with static methods returning string representations of
36  * supported LISP address types, both for use in URLs and for user friendly
37  * output.
38  *
39  * @author Lorand Jakab
40  *
41  */
42 public class LispAddressStringifier {
43
44     private static final String PREFIX_SEPARATOR = ":";
45     /*
46      * In the unlikely event that a AFI 0 address is used a key, we use a
47      * sequence number to ensure uniqueness
48      */
49     protected static int noAddrSeq = 0;
50     /*
51      * There are three possible destinations for rendering an address as a
52      * string:
53      *
54      *   * General user interaction, like log and CLI output, GUI
55      *     representation, etc.
56      *   * As a URI string that is the entry key in the MD-SAL datastore
57      *   * As a URL string that is the same as the URI string, except for
58      *     characters not accepted in URLs are percent encoded (e.g. '/' is
59      *     encoded as '%2f'
60      */
61     protected enum Destination {
62         USER,
63         URI,
64         URL;
65     }
66
67     public static String getString(LispAddress lispAddress) {
68         return getAddrString(Destination.USER, lispAddress);
69     }
70
71     public static String getURIString(LispAddress lispAddress) {
72         return getAddrString(Destination.URI, lispAddress);
73     }
74
75     public static String getURLString(LispAddress lispAddress) {
76         return getAddrString(Destination.URL, lispAddress);
77     }
78
79     private static String getAddrString(Destination dst, LispAddress lispAddress) {
80         Preconditions.checkNotNull(lispAddress, "lispAddress should not be null");
81         Address addr = lispAddress.getAddress();
82         String prefix = null;
83         String address = null;
84
85         if (addr instanceof Ipv4) {
86             prefix = "ipv4" + PREFIX_SEPARATOR;
87             address = getStringFromIpv4(dst, (Ipv4) addr);
88         } else if (addr instanceof Ipv4Prefix) {
89             prefix = "ipv4" + PREFIX_SEPARATOR;
90             address = getStringFromIpv4Prefix(dst, (Ipv4Prefix) addr);
91         } else if (addr instanceof Ipv6) {
92             prefix = "ipv6" + PREFIX_SEPARATOR;
93             address = getStringFromIpv6(dst, (Ipv6) addr);
94         } else if (addr instanceof Ipv6Prefix) {
95             prefix = "ipv6" + PREFIX_SEPARATOR;
96             address = getStringFromIpv6Prefix(dst, (Ipv6Prefix) addr);
97         } else if (addr instanceof Mac) {
98             prefix = "mac" + PREFIX_SEPARATOR;
99             address = getStringFromMac(dst, (Mac) addr);
100         } else if (addr instanceof InstanceId) {
101             SimpleAddress pa = ((InstanceId)addr).getInstanceId().getAddress();
102             // Instance ID is a separate parent hierarchy, so we use the simple address prefix
103             prefix = LispSimpleAddressStringifier.getURLPrefix(pa) + PREFIX_SEPARATOR;
104             address = getStringFromInstanceId(dst, (InstanceId) addr);
105         } else if (addr instanceof NoAddress) {
106             prefix = "no" + PREFIX_SEPARATOR;
107             address = getStringFromNoAddress(dst, (NoAddress) addr);
108         } else if (addr instanceof DistinguishedName) {
109             prefix = "dn" + PREFIX_SEPARATOR;
110             address = getStringFromDistinguishedName(dst, (DistinguishedName) addr);
111         } else if (addr instanceof AsNumber) {
112             prefix = "as" + PREFIX_SEPARATOR;
113             address = getStringFromAsNumber(dst, (AsNumber) addr);
114         } else if (addr instanceof AfiList) {
115             prefix = "list" + PREFIX_SEPARATOR;
116             address = getStringFromAfiList(dst, (AfiList) addr);
117         } else if (addr instanceof ApplicationData) {
118             prefix = "appdata" + PREFIX_SEPARATOR;
119             address = getStringFromApplicationData(dst, (ApplicationData) addr);
120         } else if (addr instanceof ExplicitLocatorPath) {
121             prefix = "elp" + PREFIX_SEPARATOR;
122             address = getStringFromExplicitLocatorPath(dst, (ExplicitLocatorPath) addr);
123         } else if (addr instanceof SourceDestKey) {
124             prefix = "srcdst" + PREFIX_SEPARATOR;
125             address = getStringFromSourceDestKey(dst, (SourceDestKey) addr);
126         } else if (addr instanceof KeyValueAddress) {
127             prefix = "kv" + PREFIX_SEPARATOR;
128             address = getStringFromKeyValueAddress(dst, (KeyValueAddress) addr);
129         }
130
131         if (dst == Destination.USER) {
132             return address;
133         } else {
134             return prefix + address;
135         }
136
137     }
138
139     private static String getPrefixString(Destination dst, String prefix) {
140         if (dst == Destination.URL) {
141             return prefix.replace("/", "%2f");
142         } else {
143             return prefix;
144         }
145     }
146
147     protected static String getStringFromNoAddress(Destination dst, NoAddress addr) {
148         // AFI = 0
149         if (dst == Destination.USER) {
150             return "No Address Present";
151         } else {
152             return "" + noAddrSeq++;
153         }
154     }
155
156     protected static String getStringFromIpv4(Destination dst, Ipv4 addr) {
157         // AFI = 1; IPv4
158         return addr.getIpv4().getValue();
159     }
160
161     protected static String getStringFromIpv4Prefix(Destination dst, Ipv4Prefix addr) {
162         // AFI = 1; IPv4
163         String prefix = addr.getIpv4Prefix().getValue();
164         return getPrefixString(dst, prefix);
165     }
166
167     protected static String getStringFromIpv6(Destination dst, Ipv6 addr) {
168         // AFI = 2; IPv6
169         return addr.getIpv6().getValue();
170     }
171
172     protected static String getStringFromIpv6Prefix(Destination dst, Ipv6Prefix addr) {
173         // AFI = 2; IPv6
174         return addr.getIpv6Prefix().getValue();
175     }
176
177     protected static String getStringFromDistinguishedName(Destination dst, DistinguishedName addr) {
178         // AFI = 17; Distinguished Name
179         return addr.getDistinguishedName().getValue();
180     }
181
182     protected static String getStringFromAsNumber(Destination dst, AsNumber addr) {
183         // AFI = 18; Autonomous System Number
184         return "AS" + addr.getAsNumber().getValue();
185     }
186     protected static String getStringFromAfiList(Destination dst, AfiList addr) {
187         // AFI 16387, LCAF Type 1; Address List
188         // Example rendering:
189         //    {192.0.2.1,192.0.2.2,2001:db8::1}
190         List<SimpleAddress> addresses = addr.getAfiList().getAddressList();
191         StringBuilder sb = new StringBuilder("{");
192         boolean needComma = false;
193         for (SimpleAddress a : addresses) {
194             if (needComma) {
195                 sb.append(",");
196             }
197             sb.append(a.getValue());
198             needComma = true;
199         }
200         sb.append("}");
201         return sb.toString();
202     }
203
204     protected static String getStringFromInstanceId(Destination dst, InstanceId addr) {
205         // AFI = 16387, LCAF Type 2; Instance ID
206         // Example rendering:
207         //    [223] 192.0.2.0/24
208         SimpleAddress pa = addr.getInstanceId().getAddress();
209         if (dst == Destination.USER) {
210             return "[" + addr.getInstanceId().getIid().getValue() + "] "
211                     + LispSimpleAddressStringifier.getString(dst, pa);
212         } else {
213             return LispSimpleAddressStringifier.getString(dst, pa);
214         }
215     }
216
217     protected static String getStringFromApplicationData(Destination dst, ApplicationData addr) {
218         // AFI = 16387, LCAF Type 4; Application Data
219         // Example rendering:
220         //    192.0.2.1!128!17!80-81!6667-7000
221         return LispSimpleAddressStringifier.getString(dst, addr.getApplicationData().getAddress())
222                 + "!" + addr.getApplicationData().getIpTos()
223                 + "!" + addr.getApplicationData().getProtocol()
224                 + "!" + addr.getApplicationData().getLocalPortLow()
225                 + "-" + addr.getApplicationData().getLocalPortHigh()
226                 + "!" + addr.getApplicationData().getRemotePortLow()
227                 + "-" + addr.getApplicationData().getRemotePortHigh();
228     }
229
230     protected static String getStringFromExplicitLocatorPath(Destination dst, ExplicitLocatorPath addr) {
231         // AFI = 16387, LCAF Type 10, Explicit Locator Path
232         // Example rendering:
233         //    {192.0.2.1->192.0.2.2|lps->192.0.2.3}
234         List<Hop> hops = addr.getExplicitLocatorPath().getHop();
235         StringBuilder sb = new StringBuilder();
236         sb.append("{");
237         boolean needArrow = false;
238         for (Hop hop : hops) {
239             if (needArrow) {
240                 sb.append("->");
241             }
242             sb.append(LispSimpleAddressStringifier.getString(dst, hop.getAddress()));
243             LrsBits lrs = hop.getLrsBits();
244             if (lrs.isLookup() || lrs.isRlocProbe() || lrs.isStrict()) {
245                 sb.append("|");
246             }
247             if (lrs.isLookup()) {
248                 sb.append("l");
249             }
250             if (lrs.isRlocProbe()) {
251                 sb.append("p");
252             }
253             if (lrs.isStrict()) {
254                 sb.append("s");
255             }
256             needArrow = true;
257         }
258         sb.append("}");
259         return sb.toString();
260     }
261
262     protected static String getStringFromSourceDestKey(Destination dst, SourceDestKey addr) {
263         // AFI = 16387, LCAF Type 12, Source/Destination Key
264         // Example rendering:
265         //    192.0.2.1/32|192.0.2.2/32
266         return getPrefixString(dst, (new String(addr.getSourceDestKey().getSource().getValue()))
267                 + "|" + getPrefixString(dst, new String(addr.getSourceDestKey().getDest().getValue())));
268     }
269
270     protected static String getStringFromKeyValueAddress(Destination dst, KeyValueAddress addr) {
271         // AFI = 16387, LCAF Type 15, Key/Value Address Pair
272         // Example rendering:
273         //    192.0.2.1=>192.0.2.2
274         return getPrefixString(dst, new String(addr.getKeyValueAddress().getKey().getValue())
275                 + "=>" + getPrefixString(dst, new String(addr.getKeyValueAddress().getValue().getValue())));
276     }
277
278     protected static String getStringFromMac(Destination dst, Mac addr) {
279         // AFI = 16389; MAC
280         return addr.getMac().getValue();
281     }
282
283 }