Migrate implementation/neutron/southbound to IETF YANG model
[lispflowmapping.git] / mappingservice / implementation / src / main / java / org / opendaylight / lispflowmapping / implementation / MappingService.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 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 static final ConfigIni configIni = new ConfigIni();
95     private boolean overwritePolicy = configIni.mappingOverwriteIsSet();
96     private boolean notificationPolicy = configIni.smrIsSet();
97     private boolean iterateMask = true;
98
99     public MappingService() {
100         LOG.debug("MappingService created!");
101     }
102
103     public void setDataBroker(DataBroker dataBroker) {
104         this.dataBroker = dataBroker;
105     }
106
107     public void setRpcProviderRegistry(RpcProviderRegistry rpc) {
108         this.rpcRegistry = rpc;
109     }
110
111     public void setBindingAwareBroker(BindingAwareBroker broker) {
112         this.bindingAwareBroker = broker;
113     }
114
115     public void setNotificationPublishService(NotificationPublishService nps) {
116         this.notificationPublishService = nps;
117     }
118
119     public void setDaoService(ILispDAO dao) {
120         this.dao = dao;
121     }
122
123     @Override
124     public void setMappingOverwrite(boolean overwrite) {
125         this.overwritePolicy = overwrite;
126         if (mappingSystem != null) {
127             mappingSystem.setOverwritePolicy(overwrite);
128         }
129     }
130
131     public void initialize() {
132         bindingAwareBroker.registerProvider(this);
133
134         mappingServiceRpc = rpcRegistry.addRpcImplementation(OdlMappingserviceService.class, this);
135         dsbe = new DataStoreBackEnd(dataBroker);
136
137         mappingSystem = new MappingSystem(dao, iterateMask, notificationPolicy, overwritePolicy);
138         mappingSystem.setDataStoreBackEnd(dsbe);
139         mappingSystem.initialize();
140
141         keyListener = new AuthenticationKeyDataListener(dataBroker, mappingSystem);
142         mappingListener = new MappingDataListener(dataBroker, mappingSystem, notificationPublishService);
143     }
144
145     @Override
146     public Future<RpcResult<Void>> addKey(AddKeyInput input) {
147         Preconditions.checkNotNull(input, "add-key RPC input must be not null!");
148         LOG.trace("RPC received to add the following key: " + input.toString());
149
150         RpcResultBuilder<Void> rpcResultBuilder;
151
152         MappingAuthkey key = mappingSystem.getAuthenticationKey(input.getEid());
153
154         if (key != null) {
155             String message = "Key already exists! Please use update-key if you want to change it.";
156             rpcResultBuilder = RpcResultBuilder.<Void>failed()
157                     .withError(RpcError.ErrorType.PROTOCOL, DATA_EXISTS_TAG, message);
158             return Futures.immediateFuture(rpcResultBuilder.build());
159         }
160
161         dsbe.addAuthenticationKey(RPCInputConvertorUtil.toAuthenticationKey(input));
162         rpcResultBuilder = RpcResultBuilder.success();
163
164         return Futures.immediateFuture(rpcResultBuilder.build());
165     }
166
167     @Override
168     public Future<RpcResult<Void>> addMapping(AddMappingInput input) {
169         Preconditions.checkNotNull(input, "add-mapping RPC input must be not null!");
170         LOG.trace("RPC received to add the following mapping: " + input.toString());
171
172         dsbe.addMapping(RPCInputConvertorUtil.toMapping(input));
173
174         RpcResultBuilder<Void> rpcResultBuilder;
175
176         rpcResultBuilder = RpcResultBuilder.success();
177
178         return Futures.immediateFuture(rpcResultBuilder.build());
179     }
180
181     @Override
182     public Future<RpcResult<GetKeyOutput>> getKey(GetKeyInput input) {
183         Preconditions.checkNotNull(input, "get-key RPC input must be not null!");
184         LOG.trace("RPC received to get the following key: " + input.toString());
185
186         RpcResultBuilder<GetKeyOutput> rpcResultBuilder;
187
188         MappingAuthkey key = mappingSystem.getAuthenticationKey(input.getEid());
189
190         if (key == null) {
191             String message = "Key was not found in the mapping database";
192             rpcResultBuilder = RpcResultBuilder.<GetKeyOutput>failed()
193                     .withError(RpcError.ErrorType.APPLICATION, NOT_FOUND_TAG, message);
194         } else {
195             rpcResultBuilder = RpcResultBuilder.success(new GetKeyOutputBuilder().setMappingAuthkey(key));
196         }
197
198         return Futures.immediateFuture(rpcResultBuilder.build());
199     }
200
201     @Override
202     public Future<RpcResult<GetMappingOutput>> getMapping(GetMappingInput input) {
203         Preconditions.checkNotNull(input, "get-mapping RPC input must be not null!");
204         LOG.trace("RPC received to get the following mapping: " + input.toString());
205
206         RpcResultBuilder<GetMappingOutput> rpcResultBuilder;
207
208         MappingRecord reply = (MappingRecord) mappingSystem.getMapping(input.getEid());
209
210         if (reply == null) {
211             String message = "No mapping was found in the mapping database";
212             rpcResultBuilder = RpcResultBuilder.<GetMappingOutput>failed()
213                     .withError(RpcError.ErrorType.APPLICATION, NOT_FOUND_TAG, message);
214         } else {
215             rpcResultBuilder = RpcResultBuilder.success(new GetMappingOutputBuilder().setMappingRecord(reply));
216         }
217
218         return Futures.immediateFuture(rpcResultBuilder.build());
219     }
220
221     @Override
222     public Future<RpcResult<Void>> removeKey(RemoveKeyInput input) {
223         Preconditions.checkNotNull(input, "remove-key RPC input must be not null!");
224         LOG.trace("RPC received to remove the following key: " + input.toString());
225
226         RpcResultBuilder<Void> rpcResultBuilder;
227
228         dsbe.removeAuthenticationKey(RPCInputConvertorUtil.toAuthenticationKey(input));
229
230         rpcResultBuilder = RpcResultBuilder.success();
231
232         return Futures.immediateFuture(rpcResultBuilder.build());
233     }
234
235     @Override
236     public Future<RpcResult<Void>> removeMapping(RemoveMappingInput input) {
237         Preconditions.checkNotNull(input, "remove-mapping RPC input must be not null!");
238         LOG.trace("RPC received to remove the following mapping: " + input.toString());
239
240         RpcResultBuilder<Void> rpcResultBuilder;
241
242         dsbe.removeMapping(RPCInputConvertorUtil.toMapping(input));
243
244         rpcResultBuilder = RpcResultBuilder.success();
245
246         return Futures.immediateFuture(rpcResultBuilder.build());
247     }
248
249     @Override
250     public Future<RpcResult<Void>> updateKey(UpdateKeyInput input) {
251         Preconditions.checkNotNull(input, "update-key RPC input must be not null!");
252         LOG.trace("RPC received to update the following key: " + input.toString());
253
254         RpcResultBuilder<Void> rpcResultBuilder;
255
256         MappingAuthkey key = mappingSystem.getAuthenticationKey(input.getEid());
257
258         if (key == null) {
259             String message = "Key doesn't exist! Please use add-key if you want to create a new authentication key.";
260             rpcResultBuilder = RpcResultBuilder.<Void>failed()
261                     .withError(RpcError.ErrorType.PROTOCOL, NOT_FOUND_TAG, message);
262             return Futures.immediateFuture(rpcResultBuilder.build());
263         }
264
265         dsbe.updateAuthenticationKey(RPCInputConvertorUtil.toAuthenticationKey(input));
266         rpcResultBuilder = RpcResultBuilder.success();
267
268         return Futures.immediateFuture(rpcResultBuilder.build());
269     }
270
271     @Override
272     public Future<RpcResult<Void>> updateMapping(UpdateMappingInput input) {
273         LOG.trace("RPC received to update the following mapping: " + input.toString());
274         Preconditions.checkNotNull(input, "update-mapping RPC input must be not null!");
275
276         RpcResultBuilder<Void> rpcResultBuilder;
277
278         dsbe.updateMapping(RPCInputConvertorUtil.toMapping(input));
279
280         rpcResultBuilder = RpcResultBuilder.success();
281
282         return Futures.immediateFuture(rpcResultBuilder.build());
283     }
284
285     @Override
286     public Future<RpcResult<Void>> removeKeys(RemoveKeysInput input) {
287         // TODO Auto-generated method stub
288         return null;
289     }
290
291     @Override
292     public Future<RpcResult<Void>> removeMappings(RemoveMappingsInput input) {
293         // TODO Auto-generated method stub
294         return null;
295     }
296
297     @Override
298     public Future<RpcResult<GetKeysOutput>> getKeys(GetKeysInput input) {
299         // TODO Auto-generated method stub
300         return null;
301     }
302
303     @Override
304     public Future<RpcResult<Void>> addMappings(AddMappingsInput input) {
305         // TODO Auto-generated method stub
306         return null;
307     }
308
309     @Override
310     public Future<RpcResult<Void>> updateKeys(UpdateKeysInput input) {
311         // TODO Auto-generated method stub
312         return null;
313     }
314
315     @Override
316     public Future<RpcResult<Void>> removeAllMappings() {
317         // TODO Auto-generated method stub
318         return null;
319     }
320
321     @Override
322     public Future<RpcResult<Void>> removeAllKeys() {
323         // TODO Auto-generated method stub
324         return null;
325     }
326
327     @Override
328     public Future<RpcResult<GetAllKeysOutput>> getAllKeys() {
329         // TODO Auto-generated method stub
330         return null;
331     }
332
333     @Override
334     public Future<RpcResult<Void>> updateMappings(UpdateMappingsInput input) {
335         // TODO Auto-generated method stub
336         return null;
337     }
338
339     @Override
340     public Future<RpcResult<Void>> addKeys(AddKeysInput input) {
341         // TODO Auto-generated method stub
342         return null;
343     }
344
345     @Override
346     public Future<RpcResult<GetAllMappingsOutput>> getAllMappings() {
347         // TODO Auto-generated method stub
348         return null;
349     }
350
351     @Override
352     public Future<RpcResult<GetMappingsOutput>> getMappings(
353             GetMappingsInput input) {
354         // TODO Auto-generated method stub
355         return null;
356     }
357
358     @Override
359     public void addMapping(MappingOrigin origin, Eid key, SiteId siteId, Object data) {
360         dsbe.addMapping(DSBEInputUtil.toMapping(origin, key, siteId, (MappingRecord) data));
361         mappingSystem.updateMappingRegistration(origin, key);
362     }
363
364     @Override
365     public Object getMapping(MappingOrigin origin, Eid key) {
366         return mappingSystem.getMapping(origin, key);
367     }
368
369     @Override
370     public Object getMapping(Eid key) {
371         return mappingSystem.getMapping(key);
372     }
373
374     @Override
375     public Object getMapping(Eid srcKey, Eid dstKey) {
376         return mappingSystem.getMapping(srcKey, dstKey);
377     }
378
379     @Override
380     public void removeMapping(MappingOrigin origin, Eid key) {
381         dsbe.removeMapping(DSBEInputUtil.toMapping(origin, key));
382     }
383
384     @Override
385     public void addAuthenticationKey(Eid key, MappingAuthkey authKey) {
386         dsbe.addAuthenticationKey(DSBEInputUtil.toAuthenticationKey(key, authKey));
387     }
388
389     @Override
390     public MappingAuthkey getAuthenticationKey(Eid key) {
391         return mappingSystem.getAuthenticationKey(key);
392     }
393
394     @Override
395     public void removeAuthenticationKey(Eid key) {
396         dsbe.removeAuthenticationKey(DSBEInputUtil.toAuthenticationKey(key, null));
397     }
398
399     @Override
400     public void addData(MappingOrigin origin, Eid key, String subKey, Object data) {
401         mappingSystem.addData(origin, key, subKey, data);
402     }
403
404     @Override
405     public Object getData(MappingOrigin origin, Eid key, String subKey) {
406         return mappingSystem.getData(origin, key, subKey);
407     }
408
409     @Override
410     public void removeData(MappingOrigin origin, Eid key, String subKey) {
411         mappingSystem.removeData(origin, key, subKey);
412     }
413
414     @Override
415     public String printMappings() {
416         return mappingSystem.printMappings();
417     }
418
419     @Override
420     public void onSessionInitiated(ProviderContext session) {
421         LOG.info("Mapping Service provider session initializing!");
422     }
423
424     @Override
425     public void close() throws Exception {
426         LOG.info("Mapping Service is being destroyed!");
427         mappingServiceRpc.close();
428         keyListener.closeDataChangeListener();
429         mappingListener.closeDataChangeListener();
430     }
431
432     @Override
433     public void cleanCachedMappings() {
434         mappingSystem.cleanCaches();
435         dsbe.removeAllMappings();
436     }
437 }