Move integration tests to mdsal-it-parent
[lispflowmapping.git] / mappingservice / yangmodel / 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.opendaylight.lfm.control.plane.rev150314.lcaflistaddress.Addresses;
13 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lcaftrafficengineeringaddress.Hops;
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.LispAddressContainer;
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.Address;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.AS;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.DistinguishedName;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.Ipv4;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.Ipv6;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.LcafApplicationData;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.LcafKeyValue;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.LcafList;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.LcafSegment;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.LcafSourceDest;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.LcafTrafficEngineering;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.Mac;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.No;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.lcafapplicationdata.LcafApplicationDataAddr;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.lcafkeyvalue.LcafKeyValueAddressAddr;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.lcafsourcedest.LcafSourceDestAddr;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispsimpleaddress.PrimitiveAddress;
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(LispAddressContainer container) {
69         return getString(Destination.USER, container);
70     }
71
72     public static String getString(LispAddressContainer container, int mask) {
73         return getString(Destination.USER, container, mask);
74     }
75
76     public static String getURIString(LispAddressContainer container, int mask) {
77         return getString(Destination.URI, container, mask);
78     }
79
80     public static String getURLString(LispAddressContainer container, int mask) {
81         return getString(Destination.URL, container, mask);
82     }
83
84     private static String getString(Destination dst, LispAddressContainer container) {
85         Preconditions.checkNotNull(container, "address should not be null");
86         Address addr = container.getAddress();
87         String prefix = null;
88         String address = null;
89
90         if (addr instanceof Ipv4) {
91             prefix = "ipv4" + PREFIX_SEPARATOR;
92             address = getStringFromIpv4(dst, (Ipv4) addr);
93         } else if (addr instanceof Ipv6) {
94             prefix = "ipv6" + PREFIX_SEPARATOR;
95             address = getStringFromIpv6(dst, (Ipv6) addr);
96         } else if (addr instanceof Mac) {
97             prefix = "mac" + PREFIX_SEPARATOR;
98             address = getStringFromMac(dst, (Mac) addr);
99         } else if (addr instanceof LcafSegment) {
100             PrimitiveAddress pa = ((LcafSegment) addr).getLcafSegmentAddr().getAddress().getPrimitiveAddress();
101             // Instance ID is a separate parent hierarchy, so we use the simple address prefix
102             prefix = LispPrimitiveAddressStringifier.getURLPrefix(pa) + PREFIX_SEPARATOR;
103             address = getStringFromLcafSegment(dst, (LcafSegment) addr);
104         } else if (addr instanceof No) {
105             prefix = "no" + PREFIX_SEPARATOR;
106             address = getStringFromNo(dst, (No) addr);
107         } else if (addr instanceof DistinguishedName) {
108             prefix = "dn" + PREFIX_SEPARATOR;
109             address = getStringFromDistinguishedName(dst, (DistinguishedName) addr);
110         } else if (addr instanceof AS) {
111             prefix = "as" + PREFIX_SEPARATOR;
112             address = getStringFromAS(dst, (AS) addr);
113         } else if (addr instanceof LcafList) {
114             prefix = "list" + PREFIX_SEPARATOR;
115             address = getStringFromLcafList(dst, (LcafList) addr);
116         } else if (addr instanceof LcafApplicationData) {
117             prefix = "appdata" + PREFIX_SEPARATOR;
118             address = getStringFromLcafApplicationData(dst, (LcafApplicationData) addr);
119         } else if (addr instanceof LcafTrafficEngineering) {
120             prefix = "elp" + PREFIX_SEPARATOR;
121             address = getStringFromLcafTrafficEngineering(dst, (LcafTrafficEngineering) addr);
122         } else if (addr instanceof LcafSourceDest) {
123             prefix = "srcdst" + PREFIX_SEPARATOR;
124             address = getStringFromLcafSourceDest(dst, (LcafSourceDest) addr);
125         } else if (addr instanceof LcafKeyValue) {
126             prefix = "kv" + PREFIX_SEPARATOR;
127             address = getStringFromLcafKeyValue(dst, (LcafKeyValue) addr);
128         }
129
130         if (dst == Destination.USER) {
131             return address;
132         } else {
133             return prefix + address;
134         }
135
136     }
137
138     private static String getString(Destination dst, LispAddressContainer container, int mask) {
139         Address addr = container.getAddress();
140
141         if (isMaskable(addr)) {
142             return (getString(dst, container) + getMaskSeparator(dst) + mask);
143         } else {
144             return getString(dst, container);
145         }
146     }
147
148     private static boolean isMaskable(Address addr) {
149         if (addr instanceof Ipv4 || addr instanceof Ipv6 || addr instanceof LcafSegment) {
150             return true;
151         }
152         return false;
153     }
154
155     private static String getMaskSeparator(Destination dst) {
156         if (dst == Destination.URL) {
157             return "%2f";
158         } else {
159             return "/";
160         }
161     }
162
163     protected static String getStringFromNo(Destination dst, No addr) {
164         // AFI = 0
165         if (dst == Destination.USER) {
166             return "No Address Present";
167         } else {
168             return "" + noAddrSeq++;
169         }
170     }
171
172     protected static String getStringFromIpv4(Destination dst, Ipv4 addr) {
173         // AFI = 1; IPv4
174         return addr.getIpv4Address().getIpv4Address().getValue();
175     }
176
177     protected static String getStringFromIpv6(Destination dst, Ipv6 addr) {
178         // AFI = 2; IPv6
179         return addr.getIpv6Address().getIpv6Address().getValue();
180     }
181
182     protected static String getStringFromDistinguishedName(Destination dst, DistinguishedName addr) {
183         // AFI = 17; Distinguished Name
184         return addr.getDistinguishedName().getDistinguishedName();
185     }
186
187     protected static String getStringFromAS(Destination dst, AS addr) {
188         // AFI = 18; Autonomous System Number
189         return "AS" + addr.getAS().getAS();
190     }
191     protected static String getStringFromLcafList(Destination dst, LcafList addr) {
192         // AFI 16387, LCAF Type 1; Address List
193         // Example rendering:
194         //    {192.0.2.1,192.0.2.2,2001:db8::1}
195         List<Addresses> addresses = addr.getLcafListAddr().getAddresses();
196         StringBuilder sb = new StringBuilder("{");
197         boolean needComma = false;
198         for (Addresses a : addresses) {
199             if (needComma) {
200                 sb.append(",");
201             }
202             sb.append(LispPrimitiveAddressStringifier.getString(dst, a.getPrimitiveAddress()));
203             needComma = true;
204         }
205         sb.append("}");
206         return sb.toString();
207     }
208
209     protected static String getStringFromLcafSegment(Destination dst, LcafSegment addr) {
210         // AFI = 16387, LCAF Type 2; Instance ID
211         // Example rendering:
212         //    [223] 192.0.2.0/24
213         PrimitiveAddress pa = addr.getLcafSegmentAddr().getAddress().getPrimitiveAddress();
214         if (dst == Destination.USER) {
215             return "[" + addr.getLcafSegmentAddr().getInstanceId() + "] "
216                     + LispPrimitiveAddressStringifier.getString(dst, pa);
217         } else {
218             return LispPrimitiveAddressStringifier.getString(dst, pa);
219         }
220     }
221
222     protected static String getStringFromLcafApplicationData(Destination dst, LcafApplicationData addr) {
223         // AFI = 16387, LCAF Type 4; Application Data
224         // Example rendering:
225         //    192.0.2.1!128!17!80-81!6667-7000
226         LcafApplicationDataAddr a = addr.getLcafApplicationDataAddr();
227         return LispPrimitiveAddressStringifier.getString(dst, a.getAddress().getPrimitiveAddress())
228                 + "!" + a.getIpTos() + "!" + a.getProtocol()
229                 + "!" + a.getLocalPortLow() + "-" + a.getLocalPortHigh()
230                 + "!" + a.getRemotePortLow() + "-" + a.getRemotePortHigh();
231
232     }
233     protected static String getStringFromLcafTrafficEngineering(Destination dst, LcafTrafficEngineering addr) {
234         // AFI = 16387, LCAF Type 10, Explicit Locator Path
235         // Example rendering:
236         //    {192.0.2.1->192.0.2.2|lps->192.0.2.3}
237         List<Hops> hops = addr.getLcafTrafficEngineeringAddr().getHops();
238         StringBuilder sb = new StringBuilder();
239         sb.append("{");
240         boolean needArrow = false;
241         for (Hops hop : hops) {
242             if (needArrow) {
243                 sb.append("->");
244             }
245             sb.append(LispPrimitiveAddressStringifier.getString(dst, hop.getHop().getPrimitiveAddress()));
246             if (hop.isLookup() || hop.isRLOCProbe() || hop.isStrict()) {
247                 sb.append("|");
248             }
249             if (hop.isLookup()) {
250                 sb.append("l");
251             }
252             if (hop.isRLOCProbe()) {
253                 sb.append("p");
254             }
255             if (hop.isStrict()) {
256                 sb.append("s");
257             }
258             needArrow = true;
259         }
260         sb.append("}");
261         return sb.toString();
262     }
263
264     protected static String getStringFromLcafSourceDest(Destination dst, LcafSourceDest addr) {
265         // AFI = 16387, LCAF Type 12, Source/Destination Key
266         // Example rendering:
267         //    192.0.2.1/32|192.0.2.2/32
268         LcafSourceDestAddr a = ((LcafSourceDest) addr).getLcafSourceDestAddr();
269         return LispPrimitiveAddressStringifier.getString(dst, a.getSrcAddress().getPrimitiveAddress())
270                 + getMaskSeparator(dst) + a.getSrcMaskLength() + "|"
271                 + LispPrimitiveAddressStringifier.getString(dst, a.getDstAddress().getPrimitiveAddress())
272                 + getMaskSeparator(dst) + a.getDstMaskLength();
273     }
274
275     protected static String getStringFromLcafKeyValue(Destination dst, LcafKeyValue addr) {
276         // AFI = 16387, LCAF Type 15, Key/Value Address Pair
277         // Example rendering:
278         //    192.0.2.1=>192.0.2.2
279         LcafKeyValueAddressAddr a = addr.getLcafKeyValueAddressAddr();
280         return LispPrimitiveAddressStringifier.getString(dst, a.getKey().getPrimitiveAddress()) + "=>"
281                 + LispPrimitiveAddressStringifier.getString(dst, a.getValue().getPrimitiveAddress());
282     }
283
284     protected static String getStringFromMac(Destination dst, Mac addr) {
285         // AFI = 16389; MAC
286         return addr.getMacAddress().getMacAddress().getValue();
287     }
288
289 }