e7a5753d018a416c4cc5d1913178814ee00a6a28
[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();
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         final XtrId xtrId = null;
120         return getMapping(dstEid, xtrId);
121     }
122
123     @Override
124     public Object getMapping(Eid eid, XtrId xtrId) {
125         if (eid == null) {
126             return null;
127         }
128
129         ILispDAO table = getVniTable(eid);
130         if (table == null) {
131             return null;
132         }
133         return getMappingLpmEid(eid, xtrId, table);
134     }
135
136     // Returns the list of mappings stored in an xTR-ID DAO
137     private List<Object> getXtrIdMappingList(ILispDAO lispDAO) {
138         if (lispDAO != null) {
139             final List<Object> records = new ArrayList<>();
140             lispDAO.getAll(new IRowVisitor() {
141                 public void visitRow(Object keyId, String valueKey, Object value) {
142                     if (valueKey.equals(SubKeys.RECORD)) {
143                         records.add(value);
144                     }
145                 }
146             });
147             return records;
148         }
149         return null;
150     }
151
152     @Override
153     public List<Object> getAllXtrIdMappings(Eid eid) {
154         ILispDAO table = getVniTable(eid);
155         if (table == null) {
156             return null;
157         }
158         Map<String, ?> daoEntry = table.getBest(MaskUtil.normalize(eid));
159         if (daoEntry != null) {
160             ILispDAO xtrIdTable = (ILispDAO) daoEntry.get(SubKeys.XTRID_RECORDS);
161             if (xtrIdTable != null) {
162                 return getXtrIdMappingList(xtrIdTable);
163             }
164         }
165         return null;
166     }
167
168     // Returns null for positive mappings, and 0/0 for empty cache.
169     @Override
170     public Eid getWidestNegativeMapping(Eid eid) {
171         ILispDAO table = getVniTable(eid);
172         if (table == null) {
173             return MaskUtil.normalize(eid, (short) 0);
174         }
175         return table.getWidestNegativePrefix(MaskUtil.normalize(eid));
176     }
177
178     @Override
179     public Eid getParentPrefix(Eid eid) {
180         ILispDAO table = getVniTable(eid);
181         if (table == null) {
182             return null;
183         }
184         return table.getParentPrefix(MaskUtil.normalize(eid));
185     }
186
187     @Override
188     public Eid getSiblingPrefix(Eid eid) {
189         ILispDAO table = getVniTable(eid);
190         if (table == null) {
191             return null;
192         }
193         return table.getSiblingPrefix(MaskUtil.normalize(eid));
194     }
195
196     @Override
197     public Eid getVirtualParentSiblingPrefix(Eid eid) {
198         ILispDAO table = getVniTable(eid);
199         if (table == null) {
200             return null;
201         }
202         return table.getVirtualParentSiblingPrefix(MaskUtil.normalize(eid));
203     }
204
205     @Override
206     public Set<Eid> getSubtree(Eid eid) {
207         ILispDAO table = getVniTable(eid);
208         if (table == null) {
209             return Collections.emptySet();
210         }
211         return table.getSubtree(eid);
212     }
213
214     @Override
215     public void removeMapping(Eid eid) {
216         ILispDAO table = getVniTable(eid);
217         if (table == null) {
218             return;
219         }
220
221         Eid key = MaskUtil.normalize(eid);
222         table.remove(key);
223         if (table.isEmpty()) {
224             removeVniTable(eid);
225         }
226     }
227
228     @Override
229     public void removeMapping(Eid eid, XtrId xtrId) {
230         List<XtrId> xtrIds = Arrays.asList(xtrId);
231         removeXtrIdMappings(eid, xtrIds);
232     }
233
234     @Override
235     public void removeXtrIdMappings(Eid eid, List<XtrId> xtrIds) {
236         ILispDAO table = getVniTable(eid);
237         if (table == null) {
238             return;
239         }
240         Eid key = MaskUtil.normalize(eid);
241         ILispDAO xtrIdTable = (ILispDAO) table.getSpecific(key, SubKeys.XTRID_RECORDS);
242         if (xtrIdTable == null) {
243             return;
244         }
245         for (XtrId xtrId : xtrIds) {
246             xtrIdTable.removeSpecific(xtrId, SubKeys.RECORD);
247         }
248         if (xtrIdTable.isEmpty()) {
249             table.removeSpecific(key, SubKeys.XTRID_RECORDS);
250             if (table.isEmpty()) {
251                 removeVniTable(eid);
252             }
253         }
254     }
255
256     @Override
257     public void addData(Eid eid, String subKey, Object data) {
258         ILispDAO table = getOrInstantiateVniTable(eid);
259         Eid key = MaskUtil.normalize(eid);
260         table.put(key, new MappingEntry<>(subKey, data));
261     }
262
263     @Override
264     public Object getData(Eid eid, String subKey) {
265         ILispDAO table = getVniTable(eid);
266         if (table == null) {
267             return null;
268         }
269         Eid key = MaskUtil.normalize(eid);
270         return table.getSpecific(key, subKey);
271     }
272
273     @Override
274     public void removeData(Eid eid, String subKey) {
275         ILispDAO table = getVniTable(eid);
276         if (table == null) {
277             return;
278         }
279         Eid key = MaskUtil.normalize(eid);
280         table.removeSpecific(key, subKey);
281         if (table.isEmpty()) {
282             removeVniTable(eid);
283         }
284     }
285
286     @Override
287     public String printMappings() {
288         return LispMapCacheStringifier.printSMCMappings(dao);
289     }
290
291     @Override
292     public String prettyPrintMappings() {
293         return LispMapCacheStringifier.prettyPrintSMCMappings(dao);
294     }
295 }