Remove SimpleMapCache#getXtrIdTable()
[lispflowmapping.git] / mappingservice / mapcache / src / main / java / org / opendaylight / lispflowmapping / mapcache / SimpleMapCache.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, 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.mapcache;
10
11 import java.util.AbstractMap.SimpleImmutableEntry;
12 import java.util.ArrayList;
13 import java.util.List;
14 import java.util.Map;
15 import java.util.Set;
16 import org.opendaylight.lispflowmapping.interfaces.dao.ILispDAO;
17 import org.opendaylight.lispflowmapping.interfaces.dao.IRowVisitor;
18 import org.opendaylight.lispflowmapping.interfaces.dao.MappingEntry;
19 import org.opendaylight.lispflowmapping.interfaces.dao.SubKeys;
20 import org.opendaylight.lispflowmapping.interfaces.mapcache.ILispMapCache;
21 import org.opendaylight.lispflowmapping.lisp.util.MaskUtil;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.SourceDestKey;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.inet.binary.types.rev160303.IpAddressBinary;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.XtrId;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.authkey.container.MappingAuthkey;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 /**
31  * Simple map-cache that works with 'simple' addresses (see lisp-proto.yang). It can do longest prefix matching for IP
32  * addresses.
33  *
34  * @author Florin Coras
35  * @author Lorand Jakab
36  *
37  */
38 public class SimpleMapCache implements ILispMapCache {
39     private static final Logger LOG = LoggerFactory.getLogger(SimpleMapCache.class);
40     private ILispDAO dao;
41
42     public SimpleMapCache(ILispDAO dao) {
43         this.dao = dao;
44     }
45
46     private ILispDAO getVniTable(Eid eid) {
47         long vni = 0;
48         if (eid.getVirtualNetworkId() == null) {
49             vni = 0;
50         } else {
51             vni = eid.getVirtualNetworkId().getValue();
52         }
53         return (ILispDAO) dao.getSpecific(vni, SubKeys.VNI);
54     }
55
56     private ILispDAO getOrInstantiateVniTable(Eid eid) {
57         long vni = 0;
58         if (eid.getVirtualNetworkId() == null) {
59             vni = 0;
60         } else {
61             vni = eid.getVirtualNetworkId().getValue();
62         }
63         ILispDAO table = (ILispDAO) dao.getSpecific(vni, SubKeys.VNI);
64         if (table == null) {
65             table = dao.putNestedTable(vni, SubKeys.VNI);
66         }
67         return table;
68     }
69
70     private ILispDAO getOrInstantiateXtrIdTable(Eid eid, ILispDAO dao) {
71         ILispDAO table = (ILispDAO) dao.getSpecific(eid, SubKeys.XTRID_RECORDS);
72         if (table == null) {
73             table = dao.putNestedTable(eid, SubKeys.XTRID_RECORDS);
74         }
75         return table;
76     }
77
78     @Override
79     public void addMapping(Eid key, Object value) {
80         addMapping(key, value, null);
81     }
82
83     @Override
84     public void addMapping(Eid key, Object value, Set<IpAddressBinary> sourceRlocs) {
85         Eid eid = MaskUtil.normalize(key);
86         ILispDAO table = getOrInstantiateVniTable(key);
87         table.put(eid, new MappingEntry<>(SubKeys.RECORD, value));
88         if (sourceRlocs != null) {
89             table.put(eid, new MappingEntry<>(SubKeys.SRC_RLOCS, sourceRlocs));
90         }
91     }
92
93     @Override
94     public void addMapping(Eid key, XtrId xtrId, Object value) {
95         Eid eid = MaskUtil.normalize(key);
96         ILispDAO table = getOrInstantiateVniTable(key);
97         ILispDAO xtrIdDao = getOrInstantiateXtrIdTable(eid, table);
98         xtrIdDao.put(xtrId, new MappingEntry<>(SubKeys.RECORD, value));
99     }
100
101     // Returns the mapping corresponding to the longest prefix match for eid. eid must be a simple (maskable or not)
102     // address
103     private Object getMappingLpmEid(Eid eid, XtrId xtrId, ILispDAO dao) {
104         SimpleImmutableEntry<Eid, Map<String, ?>> daoEntry = dao.getBestPair(MaskUtil.normalize(eid));
105         if (daoEntry != null) {
106             if (xtrId != null) {
107                 ILispDAO xtrIdTable = (ILispDAO) daoEntry.getValue().get(SubKeys.XTRID_RECORDS);
108                 if (xtrIdTable != null) {
109                     return xtrIdTable.getSpecific(xtrId, SubKeys.RECORD);
110                 }
111             } else {
112                 return daoEntry.getValue().get(SubKeys.RECORD);
113             }
114         }
115         return null;
116     }
117
118     @Override
119     public Object getMapping(Eid srcEid, Eid dstEid) {
120         final XtrId xtrId = null;
121         return getMapping(dstEid, xtrId);
122     }
123
124     @Override
125     public Object getMapping(Eid eid, XtrId xtrId) {
126         if (eid == null) {
127             return null;
128         }
129
130         ILispDAO table = getVniTable(eid);
131         if (table == null) {
132             return null;
133         }
134         return getMappingLpmEid(eid, xtrId, table);
135     }
136
137     // Returns the list of mappings stored in an xTR-ID DAO
138     private List<Object> getXtrIdMappingList(ILispDAO dao) {
139         if (dao != null) {
140             final List<Object> records = new ArrayList<>();
141             dao.getAll(new IRowVisitor() {
142                 public void visitRow(Object keyId, String valueKey, Object value) {
143                     if (valueKey.equals(SubKeys.RECORD)) {
144                         records.add(value);
145                     }
146                 }
147             });
148             return records;
149         }
150         return null;
151     }
152
153     @Override
154     public List<Object> getAllXtrIdMappings(Eid eid) {
155         ILispDAO table = getVniTable(eid);
156         if (table == null) {
157             return null;
158         }
159         Map<String, ?> daoEntry = table.getBest(MaskUtil.normalize(eid));
160         if (daoEntry != null) {
161             ILispDAO xtrIdTable = (ILispDAO) daoEntry.get(SubKeys.XTRID_RECORDS);
162             if (xtrIdTable != null) {
163                 return getXtrIdMappingList(xtrIdTable);
164             }
165         }
166         return null;
167     }
168
169     public Eid getWidestNegativeMapping(Eid eid) {
170         ILispDAO table = getVniTable(eid);
171         if (table == null) {
172             return null;
173         }
174         return table.getWidestNegativePrefix(MaskUtil.normalize(eid));
175     }
176
177     @Override
178     public void removeMapping(Eid eid) {
179         Eid key = MaskUtil.normalize(eid);
180         ILispDAO table = getVniTable(key);
181         if (table == null) {
182             return;
183         }
184
185         // We intentionally don't remove subscribers, so in case a mapping is re-added, they get notified
186         table.removeSpecific(key, SubKeys.RECORD);
187         table.removeSpecific(key, SubKeys.SRC_RLOCS);
188         table.removeSpecific(key, SubKeys.XTRID_RECORDS);
189     }
190
191     @Override
192     public void removeMapping(Eid eid, XtrId xtrId) {
193         Eid key = MaskUtil.normalize(eid);
194         ILispDAO table = getVniTable(key);
195         if (table == null) {
196             return;
197         }
198         ILispDAO xtrIdTable = (ILispDAO) table.getSpecific(key, SubKeys.XTRID_RECORDS);
199         if (xtrIdTable == null) {
200             return;
201         }
202         xtrIdTable.removeSpecific(xtrId, SubKeys.RECORD);
203     }
204
205     @Override
206     public void removeXtrIdMappings(Eid eid, List<XtrId> xtrIds) {
207         Eid key = MaskUtil.normalize(eid);
208         ILispDAO table = getVniTable(key);
209         if (table == null) {
210             return;
211         }
212         ILispDAO xtrIdTable = (ILispDAO) table.getSpecific(key, SubKeys.XTRID_RECORDS);
213         if (xtrIdTable == null) {
214             return;
215         }
216         for (XtrId xtrId : xtrIds) {
217             xtrIdTable.removeSpecific(xtrId, SubKeys.RECORD);
218         }
219     }
220
221     @Override
222     public void addAuthenticationKey(Eid eid, MappingAuthkey authKey) {
223         Eid key = MaskUtil.normalize(eid);
224         ILispDAO table = getOrInstantiateVniTable(key);
225         table.put(key, new MappingEntry<>(SubKeys.AUTH_KEY, authKey));
226     }
227
228     private MappingAuthkey getAuthKeyLpm(Eid prefix, ILispDAO db) {
229         short maskLength = MaskUtil.getMaskForAddress(prefix.getAddress());
230         while (maskLength >= 0) {
231             Eid key = MaskUtil.normalize(prefix, maskLength);
232             Object password = db.getSpecific(key, SubKeys.AUTH_KEY);
233             if (password != null && password instanceof MappingAuthkey) {
234                 return (MappingAuthkey) password;
235             }
236             maskLength -= 1;
237         }
238         return null;
239     }
240
241     @Override
242     public MappingAuthkey getAuthenticationKey(Eid eid) {
243         ILispDAO table = getVniTable(eid);
244         if (table == null) {
245             return null;
246         }
247         if (MaskUtil.isMaskable(eid.getAddress()) && !(eid.getAddress() instanceof SourceDestKey)) {
248             return getAuthKeyLpm(eid, table);
249         } else {
250             Eid key = MaskUtil.normalize(eid);
251             Object password = table.getSpecific(key, SubKeys.AUTH_KEY);
252             if (password != null && password instanceof MappingAuthkey) {
253                 return (MappingAuthkey) password;
254             } else {
255                 LOG.warn("Failed to find password!");
256                 return null;
257             }
258         }
259     }
260
261     @Override
262     public void removeAuthenticationKey(Eid eid) {
263         Eid key = MaskUtil.normalize(eid);
264         ILispDAO table = getVniTable(key);
265         if (table == null) {
266             return;
267         }
268         table.removeSpecific(key, SubKeys.AUTH_KEY);
269     }
270
271     @Override
272     public void addData(Eid eid, String subKey, Object data) {
273         Eid key = MaskUtil.normalize(eid);
274         ILispDAO table = getOrInstantiateVniTable(key);
275         table.put(key, new MappingEntry<>(subKey, data));
276     }
277
278     @Override
279     public Object getData(Eid eid, String subKey) {
280         ILispDAO table = getOrInstantiateVniTable(eid);
281         if (table == null) {
282             return null;
283         }
284         Eid key = MaskUtil.normalize(eid);
285         return table.getSpecific(key, subKey);
286     }
287
288     @Override
289     public void removeData(Eid eid, String subKey) {
290         ILispDAO table = getOrInstantiateVniTable(eid);
291         if (table == null) {
292             return;
293         }
294         Eid key = MaskUtil.normalize(eid);
295         table.removeSpecific(key, subKey);
296     }
297
298     @Override
299     public String printMappings() {
300         final StringBuffer sb = new StringBuffer();
301         sb.append("Keys\tValues\n");
302
303         final IRowVisitor innerVisitor = (new IRowVisitor() {
304             String lastKey = "";
305
306             public void visitRow(Object keyId, String valueKey, Object value) {
307                 String key = keyId.getClass().getSimpleName() + "#" + keyId;
308                 if (!lastKey.equals(key)) {
309                     sb.append("\n" + key + "\t");
310                 }
311                 sb.append(valueKey + "=" + value + "\t");
312                 lastKey = key;
313             }
314         });
315
316         dao.getAll(new IRowVisitor() {
317             String lastKey = "";
318
319             public void visitRow(Object keyId, String valueKey, Object value) {
320                 String key = keyId.getClass().getSimpleName() + "#" + keyId;
321                 if (!lastKey.equals(key)) {
322                     sb.append("\n" + key + "\t");
323                 }
324                 if (valueKey.equals(SubKeys.VNI)) {
325                     sb.append(valueKey + "= { ");
326                     ((ILispDAO)value).getAll(innerVisitor);
327                     sb.append("}\t");
328                 } else {
329                     sb.append(valueKey + "=" + value + "\t");
330                 }
331                 lastKey = key;
332             }
333         });
334         sb.append("\n");
335         return sb.toString();
336     }
337 }