d51d623c49b4fed4e0dd66751ff40363bf076ced
[lispflowmapping.git] / mappingservice / implementation / src / main / java / org / opendaylight / lispflowmapping / implementation / MappingSystem.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc.  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;
10
11 import java.util.EnumMap;
12 import java.util.List;
13
14 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
15 import org.opendaylight.lispflowmapping.implementation.mapcache.FlatMapCache;
16 import org.opendaylight.lispflowmapping.implementation.mapcache.MultiTableMapCache;
17 import org.opendaylight.lispflowmapping.implementation.mapcache.SimpleMapCache;
18 import org.opendaylight.lispflowmapping.implementation.mdsal.DataStoreBackEnd;
19 import org.opendaylight.lispflowmapping.interfaces.dao.ILispDAO;
20 import org.opendaylight.lispflowmapping.interfaces.mapcache.IMapCache;
21 import org.opendaylight.lispflowmapping.interfaces.mapcache.IMappingSystem;
22 import org.opendaylight.lispflowmapping.lisp.util.LispAddressStringifier;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eidtolocatorrecords.EidToLocatorRecordBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.lispaddress.LispAddressContainer;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.MappingOrigin;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.db.instance.AuthenticationKey;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.db.instance.Mapping;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 /**
32  * The Mapping System coordinates caching of md-sal stored mappings and if so configured enables longest prefix match
33  * mapping lookups
34  *
35  * @author Florin Coras
36  *
37  */
38 public class MappingSystem implements IMappingSystem {
39     private final static Logger LOG = LoggerFactory.getLogger(MappingSystem.class);
40     private boolean iterateMask;
41     private boolean notificationService;
42     private boolean overwrite;
43     private ILispDAO dao;
44     private IMapCache smc;
45     private IMapCache pmc;
46     private final EnumMap<MappingOrigin, IMapCache> tableMap = new EnumMap<>(MappingOrigin.class);
47     private DataStoreBackEnd dsbe;
48     private BindingAwareBroker bindingAwareBroker;
49
50     public MappingSystem(ILispDAO dao, boolean iterateMask, boolean notifications, boolean overwrite) {
51         this.dao = dao;
52         this.iterateMask = iterateMask;
53         this.notificationService = notifications;
54         this.overwrite = overwrite;
55         buildMapCaches();
56     }
57
58     public void setDataStoreBackEnd(DataStoreBackEnd dsbe) {
59         this.dsbe = dsbe;
60     }
61
62     @Override
63     public void setOverwritePolicy(boolean overwrite) {
64         this.overwrite = overwrite;
65     }
66
67     @Override
68     public void setIterateMask(boolean iterate) {
69         this.iterateMask = iterate;
70         if (smc != null || pmc != null) {
71             buildMapCaches();
72         }
73     }
74
75     public void initialize() {
76         restoreDaoFromDatastore();
77     }
78
79     private void buildMapCaches() {
80         /*
81          * There exists a direct relationship between MappingOrigins and the tables that are part of the MappingSystem.
82          * Therefore, if a new origin is added, probably a new table should be instantiate here as well.
83          */
84         if (iterateMask) {
85             smc = new SimpleMapCache(dao.putTable(MappingOrigin.Southbound.toString()));
86             pmc = new MultiTableMapCache(dao.putTable(MappingOrigin.Northbound.toString()));
87         } else {
88             smc = new FlatMapCache(dao.putTable(MappingOrigin.Southbound.toString()));
89             pmc = new FlatMapCache(dao.putTable(MappingOrigin.Northbound.toString()));
90         }
91         tableMap.put(MappingOrigin.Northbound, pmc);
92         tableMap.put(MappingOrigin.Southbound, smc);
93     }
94
95     public void addMapping(MappingOrigin origin, LispAddressContainer key, Object value) {
96         tableMap.get(origin).addMapping(key, value, overwrite);
97     }
98
99     public void updateMappingRegistration(MappingOrigin origin, LispAddressContainer key) {
100         tableMap.get(origin).updateMappingRegistration(key);
101     }
102
103     @Override
104     public Object getMapping(LispAddressContainer src, LispAddressContainer dst) {
105         // NOTE: what follows is just a simple implementation of a lookup logic, it SHOULD be subject to future
106         // improvements
107
108         // first lookup src/dst in policy table
109         Object mapping = pmc.getMapping(src, dst);
110
111         // if nothing is found, lookup src/dst in sb table
112         if (mapping == null) {
113             return smc.getMapping(src, dst);
114         }
115
116         return mapping;
117     }
118
119     @Override
120     public Object getMapping(LispAddressContainer dst) {
121         return getMapping((LispAddressContainer)null, dst);
122     }
123
124     @Override
125     public Object getMapping(MappingOrigin origin, LispAddressContainer key) {
126         return tableMap.get(origin).getMapping(null, key);
127     }
128
129     @Override
130     public void removeMapping(MappingOrigin origin, LispAddressContainer key) {
131         tableMap.get(origin).removeMapping(key, overwrite);
132         if (notificationService) {
133             // TODO
134         }
135     }
136
137     @Override
138     public void addAuthenticationKey(LispAddressContainer key, String authKey) {
139         LOG.debug("Adding authentication key '{}' for {}", key,
140                 LispAddressStringifier.getString(key));
141         smc.addAuthenticationKey(key, authKey);
142     }
143
144     @Override
145     public String getAuthenticationKey(LispAddressContainer key) {
146         LOG.debug("Retrieving authentication key for {}", LispAddressStringifier.getString(key));
147         return smc.getAuthenticationKey(key);
148     }
149
150     @Override
151     public void removeAuthenticationKey(LispAddressContainer key) {
152         LOG.debug("Removing authentication key for {}", LispAddressStringifier.getString(key));
153         smc.removeAuthenticationKey(key);
154     }
155
156     @Override
157     public void addData(MappingOrigin origin, LispAddressContainer key, String subKey, Object data) {
158         LOG.debug("Add data of class {} for key {} and subkey {}", data.getClass(),
159                 LispAddressStringifier.getString(key), subKey);
160         tableMap.get(origin).addData(key, subKey, data);
161     }
162
163     @Override
164     public Object getData(MappingOrigin origin, LispAddressContainer key, String subKey) {
165         LOG.debug("Retrieving data for key {} and subkey {}", LispAddressStringifier.getString(key), subKey);
166         return tableMap.get(origin).getData(key, subKey);
167     }
168
169     @Override
170     public void removeData(MappingOrigin origin, LispAddressContainer key, String subKey) {
171         LOG.debug("Removing data for key {} and subkey {}", LispAddressStringifier.getString(key), subKey);
172         tableMap.get(origin).removeData(key, subKey);
173     }
174
175
176     /**
177      * Restore all mappings and keys from mdsal datastore
178      */
179     private void restoreDaoFromDatastore() {
180         List<Mapping> mappings = dsbe.getAllMappings();
181         List<AuthenticationKey> authKeys = dsbe.getAllAuthenticationKeys();
182
183         LOG.info("Restoring {} mappings and {} keys from datastore into DAO", mappings.size(), authKeys.size());
184
185         for (Mapping mapping : mappings) {
186             addMapping(mapping.getOrigin(), mapping.getLispAddressContainer(),
187                     new EidToLocatorRecordBuilder(mapping).build());
188         }
189
190         for (AuthenticationKey authKey : authKeys) {
191             addAuthenticationKey(authKey.getLispAddressContainer(), authKey.getAuthkey());
192         }
193     }
194
195     public void destroy() {
196         LOG.info("Mapping System is being destroyed!");
197     }
198
199     @Override
200     public String printMappings() {
201         final StringBuffer sb = new StringBuffer();
202         sb.append("PolicyMapCache\n--------------\n");
203         sb.append(pmc.printMappings());
204         sb.append("SbMapCache\n----------\n");
205         sb.append(smc.printMappings());
206         return sb.toString();
207     }
208
209     public void cleanCaches() {
210         dao.removeAll();
211         buildMapCaches();
212     }
213 }