Magnesium platform upgrade
[lispflowmapping.git] / mappingservice / mapcache / src / main / java / org / opendaylight / lispflowmapping / mapcache / SimpleMapCache.java
1 /*
2  * Copyright (c) 2015, 2017 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.Arrays;
14 import java.util.Collections;
15 import java.util.List;
16 import java.util.Map;
17 import java.util.Set;
18 import org.opendaylight.lispflowmapping.interfaces.dao.ILispDAO;
19 import org.opendaylight.lispflowmapping.interfaces.dao.IRowVisitor;
20 import org.opendaylight.lispflowmapping.interfaces.dao.MappingEntry;
21 import org.opendaylight.lispflowmapping.interfaces.dao.SubKeys;
22 import org.opendaylight.lispflowmapping.interfaces.mapcache.ILispMapCache;
23 import org.opendaylight.lispflowmapping.lisp.util.MaskUtil;
24 import org.opendaylight.lispflowmapping.mapcache.lisp.LispMapCacheStringifier;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.inet.binary.types.rev160303.IpAddressBinary;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.XtrId;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
28
29 /**
30  * Simple map-cache that works with 'simple' addresses (see lisp-proto.yang). It can do longest prefix matching for IP
31  * addresses.
32  *
33  * @author Florin Coras
34  * @author Lorand Jakab
35  *
36  */
37 public class SimpleMapCache implements ILispMapCache {
38     private ILispDAO dao;
39
40     public SimpleMapCache(ILispDAO dao) {
41         this.dao = dao;
42     }
43
44     private long getVni(Eid eid) {
45         if (eid.getVirtualNetworkId() == null) {
46             return 0;
47         } else {
48             return eid.getVirtualNetworkId().getValue().toJava();
49         }
50     }
51
52     private ILispDAO getVniTable(Eid eid) {
53         return (ILispDAO) dao.getSpecific(getVni(eid), SubKeys.VNI);
54     }
55
56     private void removeVniTable(Eid eid) {
57         dao.removeSpecific(getVni(eid), SubKeys.VNI);
58     }
59
60     private ILispDAO getOrInstantiateVniTable(Eid eid) {
61         long vni = getVni(eid);
62         ILispDAO table = (ILispDAO) dao.getSpecific(vni, SubKeys.VNI);
63         if (table == null) {
64             table = dao.putNestedTable(vni, SubKeys.VNI);
65         }
66         return table;
67     }
68
69     private ILispDAO getOrInstantiateXtrIdTable(Eid eid, ILispDAO lispDAO) {
70         ILispDAO table = (ILispDAO) lispDAO.getSpecific(eid, SubKeys.XTRID_RECORDS);
71         if (table == null) {
72             table = lispDAO.putNestedTable(eid, SubKeys.XTRID_RECORDS);
73         }
74         return table;
75     }
76
77     @Override
78     public void addMapping(Eid key, Object value) {
79         addMapping(key, value, null);
80     }
81
82     @Override
83     public void addMapping(Eid key, Object value, Set<IpAddressBinary> sourceRlocs) {
84         Eid eid = MaskUtil.normalize(key);
85         ILispDAO table = getOrInstantiateVniTable(key);
86         table.put(eid, new MappingEntry<>(SubKeys.RECORD, value));
87         if (sourceRlocs != null) {
88             table.put(eid, new MappingEntry<>(SubKeys.SRC_RLOCS, sourceRlocs));
89         }
90     }
91
92     @Override
93     public void addMapping(Eid key, XtrId xtrId, Object value) {
94         Eid eid = MaskUtil.normalize(key);
95         ILispDAO table = getOrInstantiateVniTable(key);
96         ILispDAO xtrIdDao = getOrInstantiateXtrIdTable(eid, table);
97         xtrIdDao.put(xtrId, new MappingEntry<>(SubKeys.RECORD, value));
98     }
99
100     // Returns the mapping corresponding to the longest prefix match for eid. eid must be a simple (maskable or not)
101     // address
102     private Object getMappingLpmEid(Eid eid, XtrId xtrId, ILispDAO lispDAO) {
103         SimpleImmutableEntry<Eid, Map<String, ?>> daoEntry = lispDAO.getBestPair(MaskUtil.normalize(eid));
104         if (daoEntry != null) {
105             if (xtrId != null) {
106                 ILispDAO xtrIdTable = (ILispDAO) daoEntry.getValue().get(SubKeys.XTRID_RECORDS);
107                 if (xtrIdTable != null) {
108                     return xtrIdTable.getSpecific(xtrId, SubKeys.RECORD);
109                 }
110             } else {
111                 return daoEntry.getValue().get(SubKeys.RECORD);
112             }
113         }
114         return null;
115     }
116
117     @Override
118     public Object getMapping(Eid srcEid, Eid dstEid) {
119         return getMapping(dstEid, (XtrId) null);
120     }
121
122     @Override
123     public Object getMapping(Eid eid, XtrId xtrId) {
124         if (eid == null) {
125             return null;
126         }
127
128         ILispDAO table = getVniTable(eid);
129         if (table == null) {
130             return null;
131         }
132         return getMappingLpmEid(eid, xtrId, table);
133     }
134
135     // Returns the list of mappings stored in an xTR-ID DAO
136     private List<Object> getXtrIdMappingList(ILispDAO lispDAO) {
137         if (lispDAO != null) {
138             final List<Object> records = new ArrayList<>();
139             lispDAO.getAll(new IRowVisitor() {
140                 public void visitRow(Object keyId, String valueKey, Object value) {
141                     if (valueKey.equals(SubKeys.RECORD)) {
142                         records.add(value);
143                     }
144                 }
145             });
146             return records;
147         }
148         return null;
149     }
150
151     @Override
152     public List<Object> getAllXtrIdMappings(Eid eid) {
153         ILispDAO table = getVniTable(eid);
154         if (table == null) {
155             return null;
156         }
157         Map<String, ?> daoEntry = table.getBest(MaskUtil.normalize(eid));
158         if (daoEntry != null) {
159             ILispDAO xtrIdTable = (ILispDAO) daoEntry.get(SubKeys.XTRID_RECORDS);
160             if (xtrIdTable != null) {
161                 return getXtrIdMappingList(xtrIdTable);
162             }
163         }
164         return null;
165     }
166
167     // Returns null for positive mappings, and 0/0 for empty cache.
168     @Override
169     public Eid getWidestNegativeMapping(Eid eid) {
170         ILispDAO table = getVniTable(eid);
171         if (table == null) {
172             return MaskUtil.normalize(eid, (short) 0);
173         }
174         return table.getWidestNegativePrefix(MaskUtil.normalize(eid));
175     }
176
177     @Override
178     public Eid getCoveringLessSpecific(Eid eid) {
179         ILispDAO table = getVniTable(eid);
180         if (table == null) {
181             return null;
182         }
183         return table.getCoveringLessSpecific(MaskUtil.normalize(eid));
184     }
185
186     @Override
187     public Eid getParentPrefix(Eid eid) {
188         ILispDAO table = getVniTable(eid);
189         if (table == null) {
190             return null;
191         }
192         return table.getParentPrefix(MaskUtil.normalize(eid));
193     }
194
195     @Override
196     public Eid getSiblingPrefix(Eid eid) {
197         ILispDAO table = getVniTable(eid);
198         if (table == null) {
199             return null;
200         }
201         return table.getSiblingPrefix(MaskUtil.normalize(eid));
202     }
203
204     @Override
205     public Eid getVirtualParentSiblingPrefix(Eid eid) {
206         ILispDAO table = getVniTable(eid);
207         if (table == null) {
208             return null;
209         }
210         return table.getVirtualParentSiblingPrefix(MaskUtil.normalize(eid));
211     }
212
213     @Override
214     public Set<Eid> getSubtree(Eid eid) {
215         ILispDAO table = getVniTable(eid);
216         if (table == null) {
217             return Collections.emptySet();
218         }
219         return table.getSubtree(eid);
220     }
221
222     @Override
223     public void removeMapping(Eid eid) {
224         ILispDAO table = getVniTable(eid);
225         if (table == null) {
226             return;
227         }
228
229         Eid key = MaskUtil.normalize(eid);
230         table.remove(key);
231         if (table.isEmpty()) {
232             removeVniTable(eid);
233         }
234     }
235
236     @Override
237     public void removeMapping(Eid eid, XtrId xtrId) {
238         List<XtrId> xtrIds = Arrays.asList(xtrId);
239         removeXtrIdMappings(eid, xtrIds);
240     }
241
242     @Override
243     public void removeXtrIdMappings(Eid eid, List<XtrId> xtrIds) {
244         ILispDAO table = getVniTable(eid);
245         if (table == null) {
246             return;
247         }
248         Eid key = MaskUtil.normalize(eid);
249         ILispDAO xtrIdTable = (ILispDAO) table.getSpecific(key, SubKeys.XTRID_RECORDS);
250         if (xtrIdTable == null) {
251             return;
252         }
253         for (XtrId xtrId : xtrIds) {
254             xtrIdTable.removeSpecific(xtrId, SubKeys.RECORD);
255         }
256         if (xtrIdTable.isEmpty()) {
257             table.removeSpecific(key, SubKeys.XTRID_RECORDS);
258             if (table.isEmpty()) {
259                 removeVniTable(eid);
260             }
261         }
262     }
263
264     @Override
265     public void addData(Eid eid, String subKey, Object data) {
266         ILispDAO table = getOrInstantiateVniTable(eid);
267         Eid key = MaskUtil.normalize(eid);
268         table.put(key, new MappingEntry<>(subKey, data));
269     }
270
271     @Override
272     public Object getData(Eid eid, String subKey) {
273         ILispDAO table = getVniTable(eid);
274         if (table == null) {
275             return null;
276         }
277         Eid key = MaskUtil.normalize(eid);
278         return table.getSpecific(key, subKey);
279     }
280
281     @Override
282     public void removeData(Eid eid, String subKey) {
283         ILispDAO table = getVniTable(eid);
284         if (table == null) {
285             return;
286         }
287         Eid key = MaskUtil.normalize(eid);
288         table.removeSpecific(key, subKey);
289         if (table.isEmpty()) {
290             removeVniTable(eid);
291         }
292     }
293
294     @Override
295     public String printMappings() {
296         return LispMapCacheStringifier.printSMCMappings(dao);
297     }
298
299     @Override
300     public String prettyPrintMappings() {
301         return LispMapCacheStringifier.prettyPrintSMCMappings(dao);
302     }
303 }