f5605406381e43c5ba90b3cd4dffaac5bce0df4a
[lispflowmapping.git] / mappingservice / implementation / src / main / java / org / opendaylight / lispflowmapping / implementation / util / DAOMappingUtil.java
1 /*
2  * Copyright (c) 2014 Contextream, Inc. and others.  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
9 package org.opendaylight.lispflowmapping.implementation.util;
10
11 import java.util.AbstractMap;
12 import java.util.ArrayList;
13 import java.util.List;
14 import java.util.Map;
15 import java.util.Map.Entry;
16
17 import org.opendaylight.lispflowmapping.implementation.dao.MappingServiceKeyUtil;
18 import org.opendaylight.lispflowmapping.interfaces.dao.ILispDAO;
19 import org.opendaylight.lispflowmapping.interfaces.dao.IMappingServiceKey;
20 import org.opendaylight.lispflowmapping.interfaces.dao.MappingServiceRLOCGroup;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.LispAFIAddress;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.eidrecords.EidRecord;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.eidtolocatorrecords.EidToLocatorRecord;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lcafsourcedestaddress.DstAddressBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lcafsourcedestaddress.SrcAddressBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.LcafSourceDest;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.lcafsourcedest.LcafSourceDestAddr;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.lcafsourcedest.LcafSourceDestAddrBuilder;
29 import org.opendaylight.lispflowmapping.implementation.lisp.AbstractLispComponent;
30
31 public class DAOMappingUtil {
32
33     public static List<MappingServiceRLOCGroup> getLocatorsByEidRecord(EidRecord eid, ILispDAO dao, boolean iterateMask) {
34         IMappingServiceKey key = MappingServiceKeyUtil.generateMappingServiceKey(eid.getLispAddressContainer(), eid.getMask());
35         return getLocators(key, dao, iterateMask);
36     }
37
38     public static Object getLocatorsSpecificByEidRecord(EidRecord eid,  ILispDAO dao, String subkey, boolean iterateMask) {
39         IMappingServiceKey key = MappingServiceKeyUtil.generateMappingServiceKey(eid.getLispAddressContainer(), eid.getMask());
40         return getLocatorsSpecific(key, dao, subkey, iterateMask);
41     }
42
43     public static List<MappingServiceRLOCGroup> getLocatorsByEidToLocatorRecord(EidToLocatorRecord eid, ILispDAO dao, boolean iterateMask) {
44         IMappingServiceKey key = MappingServiceKeyUtil.generateMappingServiceKey(eid.getLispAddressContainer(), eid.getMaskLength());
45         return getLocators(key, dao, iterateMask);
46     }
47
48     public static Object getLocatorsSpecificByEidtoLocatorRecord(EidToLocatorRecord eid,  ILispDAO dao, String subkey, boolean iterateMask) {
49         IMappingServiceKey key = MappingServiceKeyUtil.generateMappingServiceKey(eid.getLispAddressContainer(), eid.getMaskLength());
50         return getLocatorsSpecific(key, dao, subkey, iterateMask);
51     }
52
53     public static List<MappingServiceRLOCGroup> getLocators(IMappingServiceKey key, ILispDAO dao, boolean iterateMask) {
54         Map<String, ?> locators = dao.get(key);
55         List<MappingServiceRLOCGroup> result = aggregateLocators(locators);
56         LispAFIAddress eid = LispAFIConvertor.toAFI(key.getEID());
57         if (iterateMask && result.isEmpty() && MaskUtil.isMaskable(eid)) {
58             result = findMaskLocators(dao, key);
59         }
60         return result;
61     }
62
63     private static List<MappingServiceRLOCGroup> aggregateLocators(Map<String, ?> locators) {
64         List<MappingServiceRLOCGroup> result = new ArrayList<MappingServiceRLOCGroup>();
65         if (locators != null) {
66             for (Object value : locators.values()) {
67                 if (value != null && value instanceof MappingServiceRLOCGroup) {
68                     result.add((MappingServiceRLOCGroup) value);
69                 }
70             }
71         }
72         return result;
73     }
74
75     public static Object getLocatorsSpecific(IMappingServiceKey key, ILispDAO dao, String subkey, boolean iterateMask) {
76         Object locators = dao.getSpecific(key, subkey);
77         LispAFIAddress eid = LispAFIConvertor.toAFI(key.getEID());
78         if (iterateMask && locators == null && MaskUtil.isMaskable(eid)) {
79             locators = findMaskLocatorsSpecific(key, dao, subkey);
80         }
81         return locators;
82     }
83
84     private static Object findMaskLocatorsSpecific(IMappingServiceKey key, ILispDAO dao, String subkey) {
85         int mask = key.getMask();
86         while (mask > 0) {
87             LispAFIAddress eid = LispAFIConvertor.toAFI(key.getEID());
88             key = MappingServiceKeyUtil.generateMappingServiceKey(
89                     LispAFIConvertor.toContainer(MaskUtil.normalize(eid, mask)), mask);
90             mask--;
91             Object locators = dao.getSpecific(key, subkey);
92             if (locators != null) {
93                 return locators;
94             }
95         }
96         return null;
97     }
98
99     private static List<MappingServiceRLOCGroup> findMaskLocators(ILispDAO dao, IMappingServiceKey key) {
100         int mask = key.getMask();
101         while (mask > 0) {
102             LispAFIAddress eid = LispAFIConvertor.toAFI(key.getEID());
103             key = MappingServiceKeyUtil.generateMappingServiceKey(
104                     LispAFIConvertor.toContainer(MaskUtil.normalize(eid, mask)), mask);
105             mask--;
106             Map<String, ?> locators = dao.get(key);
107             if (locators != null) {
108                 List<MappingServiceRLOCGroup> result = aggregateLocators(locators);
109                 if (result != null && !result.isEmpty()) {
110                     return result;
111                 }
112             }
113         }
114         return null;
115     }
116
117     public static Entry<IMappingServiceKey, List<MappingServiceRLOCGroup>> getMapping(LispAFIAddress srcEid, EidRecord eid,
118             ILispDAO dao) {
119         // a map-request for an actual SrcDst LCAF, ignore src eid
120         if (eid.getLispAddressContainer().getAddress() instanceof LcafSourceDest) {
121             LcafSourceDestAddr eidAddr = ((LcafSourceDest) eid.getLispAddressContainer().getAddress()).getLcafSourceDestAddr();
122             LispAFIAddress srcAddr = LispAFIConvertor.toAFIfromPrimitive(eidAddr.getSrcAddress().getPrimitiveAddress());
123             LispAFIAddress dstAddr = LispAFIConvertor.toAFIfromPrimitive(eidAddr.getDstAddress().getPrimitiveAddress());
124             return getMapping(srcAddr, dstAddr, eidAddr.getSrcMaskLength(), eidAddr.getDstMaskLength(), dao);
125         }
126
127         // potential map-request for SrcDst LCAF from non SrcDst capable devices
128         Entry<IMappingServiceKey, List<MappingServiceRLOCGroup>> mapping = getMapping(srcEid,
129                 LispAFIConvertor.toAFI(eid.getLispAddressContainer()), (short) MaskUtil.getMaxMask(srcEid), eid.getMask(), dao);
130
131         // if indeed SrcDst LCAF change the key to matched dst eid
132         if (mapping.getKey().getEID().getAddress() instanceof LcafSourceDest) {
133             LcafSourceDestAddr srcDst = ((LcafSourceDest)mapping.getKey().getEID().getAddress()).getLcafSourceDestAddr();
134             IMappingServiceKey newKey = MappingServiceKeyUtil.generateMappingServiceKey(LispAFIConvertor.
135                     toAFIfromPrimitive(srcDst.getDstAddress().getPrimitiveAddress()), srcDst.getDstMaskLength());
136             return new AbstractMap.SimpleImmutableEntry<>(newKey, mapping.getValue());
137         }
138
139         return mapping;
140     }
141
142     public static Entry<IMappingServiceKey, List<MappingServiceRLOCGroup>> getMapping(LispAFIAddress srcEid,
143             LispAFIAddress dstEid, short srcMask, short dstMask, ILispDAO dao) {
144         IMappingServiceKey key = MappingServiceKeyUtil.generateMappingServiceKey(dstEid, dstMask);
145         Entry<IMappingServiceKey, Map<String, ?>> daoEntry = getDaoEntry(key, dao);
146         if (daoEntry != null) {
147             // try SrcDst eid lookup
148             ILispDAO srcDstDao = (ILispDAO) daoEntry.getValue().get(AbstractLispComponent.LCAF_SRCDST_SUBKEY);
149             if (srcDstDao != null) {
150                 Entry<IMappingServiceKey, List<MappingServiceRLOCGroup>> mapping = getMappingForEid(srcEid, srcMask, srcDstDao);
151                 // if lookup fails, return whatever is found for dst eid
152                 if (mapping.getValue() != null) {
153                     LispAFIAddress newDst = LispAFIConvertor.toAFI(daoEntry.getKey().getEID());
154                     LispAFIAddress newSrc = LispAFIConvertor.toAFI(mapping.getKey().getEID());
155
156                     LispAFIAddress newEid = new LcafSourceDestAddrBuilder()
157                             .setDstAddress(new DstAddressBuilder().setPrimitiveAddress(LispAFIConvertor.toPrimitive(newDst)).build())
158                             .setSrcAddress(new SrcAddressBuilder().setPrimitiveAddress(LispAFIConvertor.toPrimitive(newSrc)).build())
159                             .setDstMaskLength((short)daoEntry.getKey().getMask()).setSrcMaskLength((short)mapping.getKey().getMask())
160                             .setAfi((short)16387).setLcafType((short)12).build();
161                     IMappingServiceKey newKey = MappingServiceKeyUtil.generateMappingServiceKey(newEid, dstMask);
162                     return new AbstractMap.SimpleImmutableEntry<>(newKey, mapping.getValue());
163                 }
164             }
165
166             // dst eid lookup
167             return makeMappingEntry(daoEntry.getKey(), daoEntry.getValue());
168         }
169         return new AbstractMap.SimpleImmutableEntry<>(key, null);
170     }
171
172     public static Entry<IMappingServiceKey, List<MappingServiceRLOCGroup>> getMappingExact(LispAFIAddress srcEid,
173             LispAFIAddress dstEid, short srcMask, short dstMask, ILispDAO dao) {
174         IMappingServiceKey dstKey = MappingServiceKeyUtil.generateMappingServiceKey(dstEid, dstMask);
175         Map<String, ?> daoEntry = dao.get(dstKey);
176         if (daoEntry != null) {
177             // try SrcDst eid lookup
178             ILispDAO srcDstDao = (ILispDAO) daoEntry.get(AbstractLispComponent.LCAF_SRCDST_SUBKEY);
179             // if lookup fails, return whatever is found for dst eid
180             if (srcDstDao != null) {
181                 IMappingServiceKey srcKey = MappingServiceKeyUtil.generateMappingServiceKey(srcEid, srcMask);
182                 Map<String, ?> mapping = srcDstDao.get(srcKey);
183                 LispAFIAddress newEid = new LcafSourceDestAddrBuilder()
184                         .setDstAddress(new DstAddressBuilder().setPrimitiveAddress(LispAFIConvertor.toPrimitive(dstEid)).build())
185                         .setSrcAddress(new SrcAddressBuilder().setPrimitiveAddress(LispAFIConvertor.toPrimitive(srcEid)).build())
186                         .setDstMaskLength((short)dstMask).setSrcMaskLength((short)srcMask)
187                         .setAfi((short)16387).setLcafType((short)12).build();
188                 IMappingServiceKey newKey = MappingServiceKeyUtil.generateMappingServiceKey(newEid, dstMask);
189                 return makeMappingEntry(newKey, mapping);
190             }
191
192             // dst eid lookup
193             return makeMappingEntry(dstKey, daoEntry);
194         }
195         return new AbstractMap.SimpleImmutableEntry<>(dstKey, null);
196     }
197
198     public static Entry<IMappingServiceKey, List<MappingServiceRLOCGroup>> getMappingForEidRecord(EidRecord eid, ILispDAO dao) {
199         return getMappingForEid(LispAFIConvertor.toAFI(eid.getLispAddressContainer()), eid.getMask(), dao);
200     }
201
202     private static Entry<IMappingServiceKey, List<MappingServiceRLOCGroup>> makeMappingEntry(IMappingServiceKey key, Map<String, ?> locators) {
203         if (locators != null) {
204             List<MappingServiceRLOCGroup> locatorsList = aggregateLocators(locators);
205             if (locatorsList != null && !locatorsList.isEmpty()) {
206                 return new AbstractMap.SimpleImmutableEntry<>(key, locatorsList);
207             }
208         }
209         return new AbstractMap.SimpleImmutableEntry<>(key, null);
210     }
211
212     public static Entry<IMappingServiceKey, List<MappingServiceRLOCGroup>> getMappingForEid(LispAFIAddress eid,
213             int maskLen, ILispDAO dao) {
214         if (eid instanceof LcafSourceDestAddr) {
215             LispAFIAddress srcAddr = LispAFIConvertor.toAFIfromPrimitive(((LcafSourceDestAddr) eid).getSrcAddress().getPrimitiveAddress());
216             LispAFIAddress dstAddr = LispAFIConvertor.toAFIfromPrimitive(((LcafSourceDestAddr) eid).getDstAddress().getPrimitiveAddress());
217
218             return getMapping(srcAddr, dstAddr, ((LcafSourceDestAddr) eid).getSrcMaskLength(),
219                     ((LcafSourceDestAddr) eid).getDstMaskLength(), dao);
220         }
221         IMappingServiceKey key = MappingServiceKeyUtil.generateMappingServiceKey(eid, maskLen);
222         Entry<IMappingServiceKey, Map<String, ?>> entry = getDaoEntry(key, dao);
223         if (entry == null) {
224             return makeMappingEntry(key, null);
225         } else {
226             return makeMappingEntry(entry.getKey(), entry.getValue());
227         }
228     }
229
230     public static Entry<IMappingServiceKey, Map<String, ?>> getDaoEntry(IMappingServiceKey lookupKey, ILispDAO dao) {
231         LispAFIAddress eidAddress = LispAFIConvertor.toAFI(lookupKey.getEID());
232         if (MaskUtil.isMaskable(eidAddress)) {
233             IMappingServiceKey key;
234             int mask = lookupKey.getMask();
235             while (mask > 0) {
236                 key = MappingServiceKeyUtil.generateMappingServiceKey(eidAddress, mask);
237                 mask--;
238                 Map<String, ?> entry = dao.get(key);
239                 if (entry != null) {
240                     return new AbstractMap.SimpleImmutableEntry<IMappingServiceKey, Map<String, ?>>(key, entry);
241                 }
242             }
243             return null;
244         } else {
245             Map<String, ?> entry = dao.get(lookupKey);
246             if (entry != null) {
247                 return new AbstractMap.SimpleImmutableEntry<IMappingServiceKey, Map<String, ?>>(lookupKey,
248                         dao.get(lookupKey));
249             } else {
250                 return null;
251             }
252         }
253     }
254 }