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