Cleanup: remove unused and commented out methods
[lispflowmapping.git] / mappingservice / mapcache / src / main / java / org / opendaylight / lispflowmapping / mapcache / MultiTableMapCache.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 package org.opendaylight.lispflowmapping.mapcache;
9
10 import java.util.Date;
11 import java.util.Map;
12 import org.opendaylight.lispflowmapping.interfaces.dao.ILispDAO;
13 import org.opendaylight.lispflowmapping.interfaces.dao.IRowVisitor;
14 import org.opendaylight.lispflowmapping.interfaces.dao.MappingEntry;
15 import org.opendaylight.lispflowmapping.interfaces.dao.SubKeys;
16 import org.opendaylight.lispflowmapping.interfaces.mapcache.IMapCache;
17 import org.opendaylight.lispflowmapping.lisp.util.MaskUtil;
18 import org.opendaylight.lispflowmapping.lisp.util.SourceDestKeyHelper;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.SourceDestKey;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.authkey.container.MappingAuthkey;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24
25 /**
26  * Multi table map-cache that works with 'simple' and SourceDest LCAF addresses (see lisp-proto.yang). It can do longest
27  * prefix matching for IP and SourceDest LCAF addresses. In case of the latter, it uses two tables, one for dst and
28  * another for source, queried and populated in this exact order.
29  *
30  * @author Florin Coras
31  */
32 public class MultiTableMapCache implements IMapCache {
33     private static final Logger LOG = LoggerFactory.getLogger(MultiTableMapCache.class);
34
35     private ILispDAO dao;
36
37     public MultiTableMapCache(ILispDAO dao) {
38         this.dao = dao;
39     }
40
41     private ILispDAO getVniTable(Eid eid) {
42         long vni = 0;
43         if (eid.getVirtualNetworkId() == null) {
44             vni = 0;
45         } else {
46             vni = eid.getVirtualNetworkId().getValue();
47         }
48         return (ILispDAO) dao.getSpecific(vni, SubKeys.VNI);
49     }
50
51     private ILispDAO getOrInstantiateVniTable(Eid eid) {
52         long vni = 0;
53         if (eid.getVirtualNetworkId() == null) {
54             vni = 0;
55         } else {
56             vni = eid.getVirtualNetworkId().getValue();
57         }
58         ILispDAO table = (ILispDAO) dao.getSpecific(vni, SubKeys.VNI);
59         if (table == null) {
60             table = dao.putNestedTable(vni, SubKeys.VNI);
61         }
62         return table;
63     }
64
65     public void addMapping(Eid key, Object value, boolean shouldOverwrite, boolean shouldMerge) {
66         Eid eid = MaskUtil.normalize(key);
67         ILispDAO table = getOrInstantiateVniTable(key);
68
69         if (eid.getAddress() instanceof SourceDestKey) {
70             Eid srcKey = SourceDestKeyHelper.getSrcBinary(eid);
71             ILispDAO srcDstDao = getOrInstantiateSDInnerDao(eid, table);
72             srcDstDao.put(srcKey, new MappingEntry<>(SubKeys.REGDATE, new Date(System.currentTimeMillis())));
73             srcDstDao.put(srcKey, new MappingEntry<>(SubKeys.RECORD, value));
74         } else {
75             table.put(eid, new MappingEntry<>(SubKeys.REGDATE, new Date(System.currentTimeMillis())));
76             table.put(eid, new MappingEntry<>(SubKeys.RECORD, value));
77         }
78     }
79
80     // Returns the mapping corresponding to the longest prefix match for eid.
81     // eid must be a simple (maskable or not) address
82     private Object getMappingLpmEid(Eid eid, ILispDAO mappingsDb) {
83         if (eid == null) {
84             return null;
85         }
86         Map<String, ?> daoEntry = mappingsDb.getBest(MaskUtil.normalize(eid));
87         if (daoEntry != null) {
88             return daoEntry.get(SubKeys.RECORD);
89         } else {
90             return null;
91         }
92     }
93
94     // Returns a mapping corresponding to either the longest prefix match for both dstEid and srcEid,
95     // if a SourceDest mapping exists, or to dstEid
96     private Object getMappingLpmSD(Eid srcEid, Eid dstEid, ILispDAO mappingsDb) {
97         Map<String, ?> daoEntry = mappingsDb.getBest(MaskUtil.normalize(dstEid));
98         if (daoEntry != null) {
99             // try SrcDst eid lookup
100             ILispDAO srcDstDao = (ILispDAO) daoEntry.get(SubKeys.LCAF_SRCDST);
101             if (srcDstDao != null) {
102                 Object mapping = getMappingLpmEid(srcEid, srcDstDao);
103                 if (mapping !=  null) {
104                     return mapping;
105                 }
106             }
107
108             // if lookup fails, return whatever is found for dst eid
109             return daoEntry.get(SubKeys.RECORD);
110         }
111         return null;
112     }
113
114     public Object getMapping(Eid srcEid, Eid dstEid) {
115         if (dstEid == null) {
116             return null;
117         }
118
119         ILispDAO table = getVniTable(dstEid);
120         if (table == null) {
121             return null;
122         }
123
124         // a map-request for an actual SrcDst LCAF, ignore src eid
125         if (dstEid.getAddress() instanceof SourceDestKey) {
126             Eid srcAddr = SourceDestKeyHelper.getSrcBinary(dstEid);
127             Eid dstAddr = SourceDestKeyHelper.getDstBinary(dstEid);
128             return getMappingLpmSD(srcAddr, dstAddr, table);
129         }
130
131         // potential map-request for SrcDst LCAF from non SrcDst capable devices
132         return getMappingLpmSD(srcEid, dstEid, table);
133     }
134
135     @Override
136     public Eid getWidestNegativeMapping(Eid key) {
137         return dao.getWidestNegativePrefix(key);
138     }
139
140     public void removeMapping(Eid eid, boolean overwrite) {
141         Eid key = MaskUtil.normalize(eid);
142         ILispDAO table = getVniTable(key);
143         if (table == null) {
144             return;
145         }
146
147         if (key.getAddress() instanceof SourceDestKey) {
148             ILispDAO db = getSDInnerDao(key, table);
149             if (db != null) {
150                 db.removeSpecific(SourceDestKeyHelper.getSrcBinary(key),
151                         SubKeys.RECORD);
152             }
153         } else {
154             table.removeSpecific(key, SubKeys.RECORD);
155         }
156     }
157
158     public void addAuthenticationKey(Eid eid, MappingAuthkey authKey) {
159         Eid key = MaskUtil.normalize(eid);
160         ILispDAO table = getOrInstantiateVniTable(key);
161
162         if (key.getAddress() instanceof SourceDestKey) {
163             ILispDAO srcDstDao = getOrInstantiateSDInnerDao(key, table);
164             srcDstDao.put(SourceDestKeyHelper.getSrcBinary(key), new MappingEntry<>(SubKeys.AUTH_KEY, authKey));
165         } else {
166             table.put(key, new MappingEntry<>(SubKeys.AUTH_KEY, authKey));
167         }
168     }
169
170     private MappingAuthkey getAuthKeyLpm(Eid prefix, ILispDAO db) {
171         short maskLength = MaskUtil.getMaskForAddress(prefix.getAddress());
172         while (maskLength >= 0) {
173             Eid key = MaskUtil.normalize(prefix, maskLength);
174             Object password = db.getSpecific(key, SubKeys.AUTH_KEY);
175             if (password != null && password instanceof MappingAuthkey) {
176                 return (MappingAuthkey) password;
177             }
178             maskLength -= 1;
179         }
180         return null;
181     }
182
183     public MappingAuthkey getAuthenticationKey(Eid eid) {
184         ILispDAO table = getVniTable(eid);
185         if (table == null) {
186             return null;
187         }
188
189         if (MaskUtil.isMaskable(eid.getAddress())) {
190             if (eid.getAddress() instanceof SourceDestKey) {
191                 // NOTE: this is an exact match, not a longest prefix match
192                 ILispDAO srcDstDao = getSDInnerDao(eid, table);
193                 if (srcDstDao != null) {
194                     return getAuthKeyLpm(SourceDestKeyHelper.getSrcBinary(eid), srcDstDao);
195                 }
196                 return null;
197             } else {
198                 return getAuthKeyLpm(eid, table);
199             }
200         } else {
201             Eid key = MaskUtil.normalize(eid);
202             Object password = table.getSpecific(key, SubKeys.AUTH_KEY);
203             if (password != null && password instanceof MappingAuthkey) {
204                 return (MappingAuthkey) password;
205             } else {
206                 LOG.warn("Failed to find password!");
207                 return null;
208             }
209         }
210     }
211
212     public void removeAuthenticationKey(Eid eid) {
213         Eid key = MaskUtil.normalize(eid);
214         ILispDAO table = getVniTable(key);
215         if (table == null) {
216             return;
217         }
218
219         if (key.getAddress() instanceof SourceDestKey) {
220             ILispDAO srcDstDao = getSDInnerDao(key, table);
221             if (srcDstDao != null) {
222                 srcDstDao.removeSpecific(key, SubKeys.AUTH_KEY);
223             }
224         } else {
225             table.removeSpecific(key, SubKeys.AUTH_KEY);
226         }
227     }
228
229     // SrcDst LCAFs are stored in a 2-tier DAO with dst having priority over src.
230     // This method returns the DAO associated to a dst or creates it if it doesn't exist.
231     private ILispDAO getOrInstantiateSDInnerDao(Eid address, ILispDAO mappingsDb) {
232         Eid dstKey = SourceDestKeyHelper.getDstBinary(address);
233         ILispDAO srcDstDao = (ILispDAO) mappingsDb.getSpecific(dstKey, SubKeys.LCAF_SRCDST);
234         if (srcDstDao == null) {
235             // inserts nested table for source
236             srcDstDao = mappingsDb.putNestedTable(dstKey, SubKeys.LCAF_SRCDST);
237         }
238         return srcDstDao;
239     }
240
241     // SrcDst LCAFs are stored in a 2-tier DAO with dst having priority over src.
242     // This method returns the DAO associated to dst or null if it doesn't exist.
243     private ILispDAO getSDInnerDao(Eid address, ILispDAO mappingsDb) {
244         return (ILispDAO) mappingsDb.getSpecific(SourceDestKeyHelper.getDstBinary(address), SubKeys.LCAF_SRCDST);
245     }
246
247     public String printMappings() {
248         final StringBuffer sb = new StringBuffer();
249         sb.append("Keys\tValues\n");
250         final IRowVisitor innerVisitor = (new IRowVisitor() {
251             String lastKey = "";
252
253             public void visitRow(Object keyId, String valueKey, Object value) {
254                 String key = keyId.getClass().getSimpleName() + "#" + keyId;
255                 if (!lastKey.equals(key)) {
256                     sb.append("\n" + key + "\t");
257                 }
258                 sb.append(valueKey + "=" + value + "\t");
259                 lastKey = key;
260             }
261         });
262         final IRowVisitor vniVisitor = (new IRowVisitor() {
263             String lastKey = "";
264
265             public void visitRow(Object keyId, String valueKey, Object value) {
266                 String key = keyId.getClass().getSimpleName() + "#" + keyId;
267                 if (!lastKey.equals(key)) {
268                     sb.append(key + "\t");
269                 }
270                 if ((valueKey.equals(SubKeys.LCAF_SRCDST))) {
271                     sb.append(valueKey + "= { ");
272                     ((ILispDAO)value).getAll(innerVisitor);
273                     sb.append("}\t");
274                 } else {
275                     sb.append(valueKey + "=" + value + "\t");
276                 }
277                 lastKey = key;
278             }
279         });
280         dao.getAll(new IRowVisitor() {
281             String lastKey = "";
282
283             public void visitRow(Object keyId, String valueKey, Object value) {
284                 String key = keyId.getClass().getSimpleName() + "#" + keyId;
285                 if (!lastKey.equals(key)) {
286                     sb.append("\n" + key + "\t");
287                 }
288                 if (valueKey.equals(SubKeys.VNI)) {
289                     sb.append(valueKey + "= { ");
290                     ((ILispDAO)value).getAll(vniVisitor);
291                     sb.append("}\t");
292                 } else {
293                     sb.append(valueKey + "=" + value + "\t");
294                 }
295                 lastKey = key;
296             }
297         });
298         sb.append("\n");
299         return sb.toString();
300     }
301
302     @Override
303     public void updateMappingRegistration(Eid key, Long timestamp) {
304
305     }
306
307     @Override
308     public void addData(Eid eid, String subKey, Object data) {
309         Eid key = MaskUtil.normalize(eid);
310         ILispDAO table = getOrInstantiateVniTable(key);
311
312         if (key.getAddress() instanceof SourceDestKey) {
313             ILispDAO srcDstDao = getOrInstantiateSDInnerDao(key, table);
314             srcDstDao.put(SourceDestKeyHelper.getSrcBinary(key), new MappingEntry<>(subKey, data));
315         } else {
316             table.put(key, new MappingEntry<>(subKey, data));
317         }
318     }
319
320     @Override
321     public Object getData(Eid eid, String subKey) {
322         Eid key = MaskUtil.normalize(eid);
323         ILispDAO table = getVniTable(key);
324         if (table == null) {
325             return null;
326         }
327
328         if (key.getAddress() instanceof SourceDestKey) {
329             ILispDAO srcDstDao = getSDInnerDao(key, table);
330             return srcDstDao.getSpecific(SourceDestKeyHelper.getSrcBinary(key), subKey);
331         } else {
332             return table.getSpecific(key, subKey);
333         }
334     }
335
336     @Override
337     public void removeData(Eid eid, String subKey) {
338         Eid key = MaskUtil.normalize(eid);
339         ILispDAO table = getVniTable(key);
340         if (table == null) {
341             return;
342         }
343         if (key.getAddress() instanceof SourceDestKey) {
344             ILispDAO db = getSDInnerDao(key, table);
345             if (db != null) {
346                 db.removeSpecific(SourceDestKeyHelper.getSrcBinary(key), subKey);
347             }
348         } else {
349             table.removeSpecific(key, subKey);
350         }
351     }
352 }