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