View Javadoc

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   package org.opendaylight.lispflowmapping.implementation;
9   
10  import java.util.concurrent.Future;
11  
12  import org.opendaylight.controller.md.sal.binding.api.DataBroker;
13  import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
14  import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
15  import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
16  import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
17  import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
18  import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
19  import org.opendaylight.lispflowmapping.implementation.config.ConfigIni;
20  import org.opendaylight.lispflowmapping.implementation.mdsal.AuthenticationKeyDataListener;
21  import org.opendaylight.lispflowmapping.implementation.mdsal.DataStoreBackEnd;
22  import org.opendaylight.lispflowmapping.implementation.mdsal.MappingDataListener;
23  import org.opendaylight.lispflowmapping.implementation.util.DSBEInputUtil;
24  import org.opendaylight.lispflowmapping.implementation.util.RPCInputConvertorUtil;
25  import org.opendaylight.lispflowmapping.interfaces.dao.ILispDAO;
26  import org.opendaylight.lispflowmapping.interfaces.mappingservice.IMappingService;
27  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
28  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecord;
29  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.AddKeyInput;
30  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.AddKeysInput;
31  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.AddMappingInput;
32  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.AddMappingsInput;
33  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetAllKeysOutput;
34  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetAllMappingsOutput;
35  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetKeyInput;
36  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetKeyOutput;
37  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetKeyOutputBuilder;
38  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetKeysInput;
39  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetKeysOutput;
40  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetMappingInput;
41  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetMappingOutput;
42  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetMappingOutputBuilder;
43  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetMappingsInput;
44  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetMappingsOutput;
45  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.MappingOrigin;
46  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.OdlMappingserviceService;
47  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.RemoveKeyInput;
48  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.RemoveKeysInput;
49  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.RemoveMappingInput;
50  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.RemoveMappingsInput;
51  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.SiteId;
52  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.UpdateKeyInput;
53  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.UpdateKeysInput;
54  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.UpdateMappingInput;
55  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.UpdateMappingsInput;
56  import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.mapping.authkey.container.MappingAuthkey;
57  import org.opendaylight.yangtools.yang.common.RpcError;
58  import org.opendaylight.yangtools.yang.common.RpcResult;
59  import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
60  import org.slf4j.Logger;
61  import org.slf4j.LoggerFactory;
62  
63  import com.google.common.base.Preconditions;
64  import com.google.common.util.concurrent.Futures;
65  
66  /**
67   * Dispatcher of API calls that implements the RPC and Java APIs in mappingservice.yang and IMappingService
68   * respectively. It also coordinates and acts as container for all objects in charge of
69   *  - saving and updating md-sal datastore stored mappings
70   *  - monitoring md-sal datastore mapping updates and pushing them to the in memory mapping-system
71   *  - in memory mapping-system
72   *
73   * @author Lorand Jakab
74   * @author Florin Coras
75   *
76   */
77  public class MappingService implements OdlMappingserviceService, IMappingService, BindingAwareProvider, AutoCloseable {
78      protected static final Logger LOG = LoggerFactory.getLogger(MappingService.class);
79      private static final String NOT_FOUND_TAG = "data-missing";
80      private static final String DATA_EXISTS_TAG = "data-exists";
81  
82      private MappingSystem mappingSystem;
83      private DataStoreBackEnd dsbe;
84      private RpcRegistration<OdlMappingserviceService> mappingServiceRpc;
85      private AuthenticationKeyDataListener keyListener;
86      private MappingDataListener mappingListener;
87      private ILispDAO dao;
88  
89      private DataBroker dataBroker;
90      private RpcProviderRegistry rpcRegistry;
91      private BindingAwareBroker bindingAwareBroker;
92      private NotificationPublishService notificationPublishService;
93  
94      private boolean overwritePolicy = ConfigIni.getInstance().mappingOverwriteIsSet();
95      private boolean notificationPolicy = ConfigIni.getInstance().smrIsSet();
96      private boolean iterateMask = true;
97  
98      public MappingService() {
99          LOG.debug("MappingService created!");
100     }
101 
102     public void setDataBroker(DataBroker dataBroker) {
103         this.dataBroker = dataBroker;
104     }
105 
106     public void setRpcProviderRegistry(RpcProviderRegistry rpc) {
107         this.rpcRegistry = rpc;
108     }
109 
110     public void setBindingAwareBroker(BindingAwareBroker broker) {
111         this.bindingAwareBroker = broker;
112     }
113 
114     public void setNotificationPublishService(NotificationPublishService nps) {
115         this.notificationPublishService = nps;
116     }
117 
118     public void setDaoService(ILispDAO dao) {
119         this.dao = dao;
120     }
121 
122     @Override
123     public void setMappingOverwrite(boolean overwrite) {
124         this.overwritePolicy = overwrite;
125         if (mappingSystem != null) {
126             mappingSystem.setOverwritePolicy(overwrite);
127         }
128     }
129 
130     public void initialize() {
131         bindingAwareBroker.registerProvider(this);
132 
133         mappingServiceRpc = rpcRegistry.addRpcImplementation(OdlMappingserviceService.class, this);
134         dsbe = new DataStoreBackEnd(dataBroker);
135 
136         mappingSystem = new MappingSystem(dao, iterateMask, notificationPolicy, overwritePolicy);
137         mappingSystem.setDataStoreBackEnd(dsbe);
138         mappingSystem.initialize();
139 
140         keyListener = new AuthenticationKeyDataListener(dataBroker, mappingSystem);
141         mappingListener = new MappingDataListener(dataBroker, mappingSystem, notificationPublishService);
142     }
143 
144     @Override
145     public Future<RpcResult<Void>> addKey(AddKeyInput input) {
146         Preconditions.checkNotNull(input, "add-key RPC input must be not null!");
147         LOG.trace("RPC received to add the following key: " + input.toString());
148 
149         RpcResultBuilder<Void> rpcResultBuilder;
150 
151         MappingAuthkey key = mappingSystem.getAuthenticationKey(input.getEid());
152 
153         if (key != null) {
154             String message = "Key already exists! Please use update-key if you want to change it.";
155             rpcResultBuilder = RpcResultBuilder.<Void>failed()
156                     .withError(RpcError.ErrorType.PROTOCOL, DATA_EXISTS_TAG, message);
157             return Futures.immediateFuture(rpcResultBuilder.build());
158         }
159 
160         dsbe.addAuthenticationKey(RPCInputConvertorUtil.toAuthenticationKey(input));
161         rpcResultBuilder = RpcResultBuilder.success();
162 
163         return Futures.immediateFuture(rpcResultBuilder.build());
164     }
165 
166     @Override
167     public Future<RpcResult<Void>> addMapping(AddMappingInput input) {
168         Preconditions.checkNotNull(input, "add-mapping RPC input must be not null!");
169         LOG.trace("RPC received to add the following mapping: " + input.toString());
170 
171         dsbe.addMapping(RPCInputConvertorUtil.toMapping(input));
172 
173         RpcResultBuilder<Void> rpcResultBuilder;
174 
175         rpcResultBuilder = RpcResultBuilder.success();
176 
177         return Futures.immediateFuture(rpcResultBuilder.build());
178     }
179 
180     @Override
181     public Future<RpcResult<GetKeyOutput>> getKey(GetKeyInput input) {
182         Preconditions.checkNotNull(input, "get-key RPC input must be not null!");
183         LOG.trace("RPC received to get the following key: " + input.toString());
184 
185         RpcResultBuilder<GetKeyOutput> rpcResultBuilder;
186 
187         MappingAuthkey key = mappingSystem.getAuthenticationKey(input.getEid());
188 
189         if (key == null) {
190             String message = "Key was not found in the mapping database";
191             rpcResultBuilder = RpcResultBuilder.<GetKeyOutput>failed()
192                     .withError(RpcError.ErrorType.APPLICATION, NOT_FOUND_TAG, message);
193         } else {
194             rpcResultBuilder = RpcResultBuilder.success(new GetKeyOutputBuilder().setMappingAuthkey(key));
195         }
196 
197         return Futures.immediateFuture(rpcResultBuilder.build());
198     }
199 
200     @Override
201     public Future<RpcResult<GetMappingOutput>> getMapping(GetMappingInput input) {
202         Preconditions.checkNotNull(input, "get-mapping RPC input must be not null!");
203         LOG.trace("RPC received to get the following mapping: " + input.toString());
204 
205         RpcResultBuilder<GetMappingOutput> rpcResultBuilder;
206 
207         MappingRecord reply = (MappingRecord) mappingSystem.getMapping(input.getEid());
208 
209         if (reply == null) {
210             String message = "No mapping was found in the mapping database";
211             rpcResultBuilder = RpcResultBuilder.<GetMappingOutput>failed()
212                     .withError(RpcError.ErrorType.APPLICATION, NOT_FOUND_TAG, message);
213         } else {
214             rpcResultBuilder = RpcResultBuilder.success(new GetMappingOutputBuilder().setMappingRecord(reply));
215         }
216 
217         return Futures.immediateFuture(rpcResultBuilder.build());
218     }
219 
220     @Override
221     public Future<RpcResult<Void>> removeKey(RemoveKeyInput input) {
222         Preconditions.checkNotNull(input, "remove-key RPC input must be not null!");
223         LOG.trace("RPC received to remove the following key: " + input.toString());
224 
225         RpcResultBuilder<Void> rpcResultBuilder;
226 
227         dsbe.removeAuthenticationKey(RPCInputConvertorUtil.toAuthenticationKey(input));
228 
229         rpcResultBuilder = RpcResultBuilder.success();
230 
231         return Futures.immediateFuture(rpcResultBuilder.build());
232     }
233 
234     @Override
235     public Future<RpcResult<Void>> removeMapping(RemoveMappingInput input) {
236         Preconditions.checkNotNull(input, "remove-mapping RPC input must be not null!");
237         LOG.trace("RPC received to remove the following mapping: " + input.toString());
238 
239         RpcResultBuilder<Void> rpcResultBuilder;
240 
241         dsbe.removeMapping(RPCInputConvertorUtil.toMapping(input));
242 
243         rpcResultBuilder = RpcResultBuilder.success();
244 
245         return Futures.immediateFuture(rpcResultBuilder.build());
246     }
247 
248     @Override
249     public Future<RpcResult<Void>> updateKey(UpdateKeyInput input) {
250         Preconditions.checkNotNull(input, "update-key RPC input must be not null!");
251         LOG.trace("RPC received to update the following key: " + input.toString());
252 
253         RpcResultBuilder<Void> rpcResultBuilder;
254 
255         MappingAuthkey key = mappingSystem.getAuthenticationKey(input.getEid());
256 
257         if (key == null) {
258             String message = "Key doesn't exist! Please use add-key if you want to create a new authentication key.";
259             rpcResultBuilder = RpcResultBuilder.<Void>failed()
260                     .withError(RpcError.ErrorType.PROTOCOL, NOT_FOUND_TAG, message);
261             return Futures.immediateFuture(rpcResultBuilder.build());
262         }
263 
264         dsbe.updateAuthenticationKey(RPCInputConvertorUtil.toAuthenticationKey(input));
265         rpcResultBuilder = RpcResultBuilder.success();
266 
267         return Futures.immediateFuture(rpcResultBuilder.build());
268     }
269 
270     @Override
271     public Future<RpcResult<Void>> updateMapping(UpdateMappingInput input) {
272         LOG.trace("RPC received to update the following mapping: " + input.toString());
273         Preconditions.checkNotNull(input, "update-mapping RPC input must be not null!");
274 
275         RpcResultBuilder<Void> rpcResultBuilder;
276 
277         dsbe.updateMapping(RPCInputConvertorUtil.toMapping(input));
278 
279         rpcResultBuilder = RpcResultBuilder.success();
280 
281         return Futures.immediateFuture(rpcResultBuilder.build());
282     }
283 
284     @Override
285     public Future<RpcResult<Void>> removeKeys(RemoveKeysInput input) {
286         // TODO Auto-generated method stub
287         return null;
288     }
289 
290     @Override
291     public Future<RpcResult<Void>> removeMappings(RemoveMappingsInput input) {
292         // TODO Auto-generated method stub
293         return null;
294     }
295 
296     @Override
297     public Future<RpcResult<GetKeysOutput>> getKeys(GetKeysInput input) {
298         // TODO Auto-generated method stub
299         return null;
300     }
301 
302     @Override
303     public Future<RpcResult<Void>> addMappings(AddMappingsInput input) {
304         // TODO Auto-generated method stub
305         return null;
306     }
307 
308     @Override
309     public Future<RpcResult<Void>> updateKeys(UpdateKeysInput input) {
310         // TODO Auto-generated method stub
311         return null;
312     }
313 
314     @Override
315     public Future<RpcResult<Void>> removeAllMappings() {
316         // TODO Auto-generated method stub
317         return null;
318     }
319 
320     @Override
321     public Future<RpcResult<Void>> removeAllKeys() {
322         // TODO Auto-generated method stub
323         return null;
324     }
325 
326     @Override
327     public Future<RpcResult<GetAllKeysOutput>> getAllKeys() {
328         // TODO Auto-generated method stub
329         return null;
330     }
331 
332     @Override
333     public Future<RpcResult<Void>> updateMappings(UpdateMappingsInput input) {
334         // TODO Auto-generated method stub
335         return null;
336     }
337 
338     @Override
339     public Future<RpcResult<Void>> addKeys(AddKeysInput input) {
340         // TODO Auto-generated method stub
341         return null;
342     }
343 
344     @Override
345     public Future<RpcResult<GetAllMappingsOutput>> getAllMappings() {
346         // TODO Auto-generated method stub
347         return null;
348     }
349 
350     @Override
351     public Future<RpcResult<GetMappingsOutput>> getMappings(
352             GetMappingsInput input) {
353         // TODO Auto-generated method stub
354         return null;
355     }
356 
357     @Override
358     public void addMapping(MappingOrigin origin, Eid key, SiteId siteId, Object data) {
359         // SB registrations are first written to the MappingSystem and only afterwards are persisted to the datastore
360         if (origin.equals(MappingOrigin.Southbound)) {
361             // Store data first in MapCache and only afterwards persist to datastore. This should be used only for SB
362             // registrations
363             mappingSystem.addMapping(origin, key, data);
364             dsbe.addMapping(DSBEInputUtil.toMapping(origin, key, siteId, (MappingRecord) data));
365         } else {
366             dsbe.addMapping(DSBEInputUtil.toMapping(origin, key, siteId, (MappingRecord) data));
367         }
368     }
369 
370     @Override
371     public Object getMapping(MappingOrigin origin, Eid key) {
372         return mappingSystem.getMapping(origin, key);
373     }
374 
375     @Override
376     public Object getMapping(Eid key) {
377         return mappingSystem.getMapping(key);
378     }
379 
380     @Override
381     public Object getMapping(Eid srcKey, Eid dstKey) {
382         return mappingSystem.getMapping(srcKey, dstKey);
383     }
384 
385     @Override
386     public void removeMapping(MappingOrigin origin, Eid key) {
387         dsbe.removeMapping(DSBEInputUtil.toMapping(origin, key));
388     }
389 
390     @Override
391     public void addAuthenticationKey(Eid key, MappingAuthkey authKey) {
392         dsbe.addAuthenticationKey(DSBEInputUtil.toAuthenticationKey(key, authKey));
393     }
394 
395     @Override
396     public MappingAuthkey getAuthenticationKey(Eid key) {
397         return mappingSystem.getAuthenticationKey(key);
398     }
399 
400     @Override
401     public void removeAuthenticationKey(Eid key) {
402         dsbe.removeAuthenticationKey(DSBEInputUtil.toAuthenticationKey(key, null));
403     }
404 
405     @Override
406     public void addData(MappingOrigin origin, Eid key, String subKey, Object data) {
407         mappingSystem.addData(origin, key, subKey, data);
408     }
409 
410     @Override
411     public Object getData(MappingOrigin origin, Eid key, String subKey) {
412         return mappingSystem.getData(origin, key, subKey);
413     }
414 
415     @Override
416     public void removeData(MappingOrigin origin, Eid key, String subKey) {
417         mappingSystem.removeData(origin, key, subKey);
418     }
419 
420     @Override
421     public String printMappings() {
422         return mappingSystem.printMappings();
423     }
424 
425     @Override
426     public void onSessionInitiated(ProviderContext session) {
427         LOG.info("Mapping Service provider session initializing!");
428     }
429 
430     @Override
431     public void close() throws Exception {
432         LOG.info("Mapping Service is being destroyed!");
433         mappingServiceRpc.close();
434         keyListener.closeDataChangeListener();
435         mappingListener.closeDataChangeListener();
436     }
437 
438     @Override
439     public void cleanCachedMappings() {
440         mappingSystem.cleanCaches();
441         dsbe.removeAllMappings();
442     }
443 }