25f6f13014e9a638d9cc996bd74c656b8ca1ebf2
[lispflowmapping.git] / mappingservice / implementation / src / main / java / org / opendaylight / lispflowmapping / implementation / MappingService.java
1 /*
2  * Copyright (c) 2015, 2017 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 static java.util.Objects.requireNonNull;
11
12 import com.google.common.util.concurrent.ListenableFuture;
13 import java.util.ArrayList;
14 import java.util.List;
15 import java.util.Set;
16 import javax.annotation.PreDestroy;
17 import javax.inject.Singleton;
18 import org.opendaylight.lispflowmapping.config.ConfigIni;
19 import org.opendaylight.lispflowmapping.dsbackend.DataStoreBackEnd;
20 import org.opendaylight.lispflowmapping.implementation.mdsal.AuthenticationKeyDataListener;
21 import org.opendaylight.lispflowmapping.implementation.mdsal.MappingDataListener;
22 import org.opendaylight.lispflowmapping.implementation.util.DSBEInputUtil;
23 import org.opendaylight.lispflowmapping.implementation.util.RPCInputConvertorUtil;
24 import org.opendaylight.lispflowmapping.interfaces.dao.ILispDAO;
25 import org.opendaylight.lispflowmapping.interfaces.dao.Subscriber;
26 import org.opendaylight.lispflowmapping.interfaces.mappingservice.IMappingService;
27 import org.opendaylight.lispflowmapping.lisp.type.MappingData;
28 import org.opendaylight.lispflowmapping.lisp.util.LispAddressUtil;
29 import org.opendaylight.mdsal.binding.api.DataBroker;
30 import org.opendaylight.mdsal.binding.api.NotificationPublishService;
31 import org.opendaylight.mdsal.binding.api.RpcProviderService;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.SiteId;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.XtrId;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecord;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecordBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping._record.container.MappingRecord;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping._record.container.MappingRecordBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.authkey.container.MappingAuthkey;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.AddKeyInput;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.AddKeyOutput;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.AddKeyOutputBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.AddKeysInput;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.AddKeysOutput;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.AddMappingInput;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.AddMappingOutput;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.AddMappingOutputBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.AddMappingsInput;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.AddMappingsOutput;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetAllKeysInput;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetAllKeysOutput;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetAllMappingsInput;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetAllMappingsOutput;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetKeyInput;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetKeyOutput;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetKeyOutputBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetKeysInput;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetKeysOutput;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetMappingInput;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetMappingOutput;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetMappingOutputBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetMappingWithXtrIdInput;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetMappingWithXtrIdOutput;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetMappingWithXtrIdOutputBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetMappingsInput;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetMappingsOutput;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.MappingOrigin;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.OdlMappingserviceService;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.RemoveAllKeysInput;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.RemoveAllKeysOutput;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.RemoveAllMappingsInput;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.RemoveAllMappingsOutput;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.RemoveAllOperationalContentInput;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.RemoveAllOperationalContentOutput;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.RemoveAllOperationalContentOutputBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.RemoveKeyInput;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.RemoveKeyOutput;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.RemoveKeyOutputBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.RemoveKeysInput;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.RemoveKeysOutput;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.RemoveMappingInput;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.RemoveMappingOutput;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.RemoveMappingOutputBuilder;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.RemoveMappingsInput;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.RemoveMappingsOutput;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.UpdateKeyInput;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.UpdateKeyOutput;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.UpdateKeyOutputBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.UpdateKeysInput;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.UpdateKeysOutput;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.UpdateMappingInput;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.UpdateMappingOutput;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.UpdateMappingOutputBuilder;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.UpdateMappingsInput;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.UpdateMappingsOutput;
96 import org.opendaylight.yangtools.concepts.Registration;
97 import org.opendaylight.yangtools.yang.common.ErrorTag;
98 import org.opendaylight.yangtools.yang.common.ErrorType;
99 import org.opendaylight.yangtools.yang.common.RpcResult;
100 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
101 import org.osgi.service.component.annotations.Activate;
102 import org.osgi.service.component.annotations.Component;
103 import org.osgi.service.component.annotations.Deactivate;
104 import org.osgi.service.component.annotations.Reference;
105 import org.slf4j.Logger;
106 import org.slf4j.LoggerFactory;
107
108 /**
109  * Dispatcher of API calls that implements the RPC and Java APIs in mappingservice.yang and IMappingService
110  * respectively. It also coordinates and acts as container for all objects in charge of
111  *  - saving and updating md-sal datastore stored mappings
112  *  - monitoring md-sal datastore mapping updates and pushing them to the in memory mapping-system
113  *  - in memory mapping-system
114  *
115  * @author Lorand Jakab
116  * @author Florin Coras
117  *
118  */
119 @Component(service = IMappingService.class, immediate = true, property = "type=default")
120 @Singleton
121 public class MappingService implements OdlMappingserviceService, IMappingService, AutoCloseable {
122     private static final Logger LOG = LoggerFactory.getLogger(MappingService.class);
123
124     private MappingSystem mappingSystem;
125     private DataStoreBackEnd dsbe;
126     private AuthenticationKeyDataListener keyListener;
127     private MappingDataListener mappingListener;
128
129     @Reference
130     private volatile ILispDAO dao;
131     @Reference
132     private volatile DataBroker dataBroker;
133     @Reference
134     private volatile RpcProviderService rpcProviderService;
135     @Reference
136     private volatile NotificationPublishService notificationPublishService;
137     private Registration rpcRegistration;
138
139     private boolean mappingMergePolicy = ConfigIni.getInstance().mappingMergeIsSet();
140     private final boolean notificationPolicy = ConfigIni.getInstance().smrIsSet();
141     private final boolean iterateMask = true;
142     private boolean isMaster = false;
143
144     @Override
145     public void setMappingMerge(boolean mergeMapping) {
146         this.mappingMergePolicy = mergeMapping;
147         if (mappingSystem != null) {
148             mappingSystem.setMappingMerge(mergeMapping);
149             ConfigIni.getInstance().setMappingMerge(mappingMergePolicy);
150         }
151     }
152
153     @Override
154     public void setLookupPolicy(IMappingService.LookupPolicy policy) {
155         ConfigIni.getInstance().setLookupPolicy(policy);
156     }
157
158     @Activate
159     public void initialize() {
160         LOG.info("Mapping Service initializing...");
161         dsbe = new DataStoreBackEnd(dataBroker);
162
163         rpcRegistration = rpcProviderService.registerRpcImplementation(OdlMappingserviceService.class, this);
164
165         mappingSystem = new MappingSystem(dao, iterateMask, notificationPublishService, mappingMergePolicy);
166         mappingSystem.setDataStoreBackEnd(dsbe);
167         mappingSystem.initialize();
168
169         keyListener = new AuthenticationKeyDataListener(dataBroker, mappingSystem);
170         mappingListener = new MappingDataListener(dataBroker, mappingSystem, notificationPublishService);
171         LOG.info("Mapping Service loaded.");
172     }
173
174     @Override
175     public ListenableFuture<RpcResult<AddKeyOutput>> addKey(AddKeyInput input) {
176         requireNonNull(input, "add-key RPC input must be not null!");
177         LOG.trace("RPC received to add the following key: {}", input);
178
179         RpcResultBuilder<AddKeyOutput> rpcResultBuilder;
180
181         MappingAuthkey key = mappingSystem.getAuthenticationKey(convertToBinaryIfNecessary(input.getEid()));
182
183         if (key != null) {
184             String message = "Key already exists! Please use update-key if you want to change it.";
185             rpcResultBuilder = RpcResultBuilder.<AddKeyOutput>failed()
186                     .withError(ErrorType.PROTOCOL, ErrorTag.DATA_EXISTS, message);
187             return rpcResultBuilder.buildFuture();
188         }
189
190         dsbe.addAuthenticationKey(RPCInputConvertorUtil.toAuthenticationKey(input));
191         rpcResultBuilder = RpcResultBuilder.success(new AddKeyOutputBuilder().build());
192
193         return rpcResultBuilder.buildFuture();
194     }
195
196     @Override
197     public ListenableFuture<RpcResult<AddMappingOutput>> addMapping(AddMappingInput input) {
198         requireNonNull(input, "add-mapping RPC input must be not null!");
199         LOG.trace("RPC received to add the following mapping: {}", input);
200
201         dsbe.addMapping(RPCInputConvertorUtil.toMapping(input));
202
203         RpcResultBuilder<AddMappingOutput> rpcResultBuilder;
204
205         rpcResultBuilder = RpcResultBuilder.success(new AddMappingOutputBuilder().build());
206
207         return rpcResultBuilder.buildFuture();
208     }
209
210     @Override
211     public void addMapping(MappingOrigin origin, Eid key, SiteId siteId, MappingData mappingData) {
212         // SB registrations are first written to the MappingSystem and only afterwards are persisted to the datastore
213         if (origin.equals(MappingOrigin.Southbound)) {
214             // Store data first in MapCache and only afterwards persist to datastore. This should be used only for SB
215             // registrations
216             mappingSystem.addMapping(origin, key, mappingData);
217             dsbe.addMapping(DSBEInputUtil.toMapping(origin, key, siteId, mappingData));
218             if (mappingData.getXtrId() != null) {
219                 dsbe.addXtrIdMapping(DSBEInputUtil.toXtrIdMapping(mappingData));
220             }
221         } else {
222             dsbe.addMapping(DSBEInputUtil.toMapping(origin, key, siteId, mappingData));
223         }
224     }
225
226     @Override
227     public MappingData addNegativeMapping(Eid key) {
228         return mappingSystem.addNegativeMapping(key);
229     }
230
231     @Override
232     public void refreshMappingRegistration(Eid key, XtrId xtrId, Long timestamp) {
233         mappingSystem.refreshMappingRegistration(key, xtrId, timestamp);
234     }
235
236     @Override
237     public ListenableFuture<RpcResult<GetKeyOutput>> getKey(GetKeyInput input) {
238         requireNonNull(input, "get-key RPC input must be not null!");
239         LOG.trace("RPC received to get the following key: {}", input);
240
241         RpcResultBuilder<GetKeyOutput> rpcResultBuilder;
242
243         MappingAuthkey key = mappingSystem.getAuthenticationKey(convertToBinaryIfNecessary(input.getEid()));
244
245         if (key == null) {
246             String message = "Key was not found in the mapping database";
247             rpcResultBuilder = RpcResultBuilder.<GetKeyOutput>failed()
248                     .withError(ErrorType.APPLICATION, ErrorTag.DATA_MISSING, message);
249         } else {
250             rpcResultBuilder = RpcResultBuilder.success(new GetKeyOutputBuilder().setMappingAuthkey(key).build());
251         }
252
253         return rpcResultBuilder.buildFuture();
254     }
255
256     @Override
257     public ListenableFuture<RpcResult<GetMappingOutput>> getMapping(GetMappingInput input) {
258         requireNonNull(input, "get-mapping RPC input must be not null!");
259         LOG.trace("RPC received to get the following mapping: {}", input);
260
261         RpcResultBuilder<GetMappingOutput> rpcResultBuilder;
262
263         MappingData reply = mappingSystem.getMapping(convertToBinaryIfNecessary(input.getEid()));
264
265         if (reply == null) {
266             String message = "No mapping was found in the mapping database";
267             rpcResultBuilder = RpcResultBuilder.<GetMappingOutput>failed()
268                     .withError(ErrorType.APPLICATION, ErrorTag.DATA_MISSING, message);
269         } else {
270             final MappingRecord convertedReply = convertFromBinaryIfNecessary(reply.getRecord());
271             rpcResultBuilder = RpcResultBuilder.success(
272                 new GetMappingOutputBuilder().setMappingRecord(convertedReply).build());
273         }
274
275         return rpcResultBuilder.buildFuture();
276     }
277
278     @Override
279     public MappingData getMapping(MappingOrigin origin, Eid key) {
280         return mappingSystem.getMapping(origin, key);
281     }
282
283     @Override
284     public MappingData getMapping(Eid key) {
285         return mappingSystem.getMapping(key);
286     }
287
288     @Override
289     public MappingData getMapping(Eid srcKey, Eid dstKey) {
290         return mappingSystem.getMapping(srcKey, dstKey);
291     }
292
293     @Override
294     public void subscribe(Subscriber subscriber, Eid subscribedEid) {
295         mappingSystem.subscribe(subscriber, subscribedEid);
296     }
297
298     @Override
299     public Set<Subscriber> getSubscribers(Eid eid) {
300         return mappingSystem.getSubscribers(eid);
301     }
302
303     @Override
304     public ListenableFuture<RpcResult<GetMappingWithXtrIdOutput>> getMappingWithXtrId(GetMappingWithXtrIdInput input) {
305         requireNonNull(input, "get-mapping RPC input must be not null!");
306         LOG.trace("RPC received to get the following mapping: {}", input);
307
308         RpcResultBuilder<GetMappingWithXtrIdOutput> rpcResultBuilder;
309
310         MappingData reply = mappingSystem.getMapping(null, convertToBinaryIfNecessary(input.getEid()),
311                 input.getXtrId());
312
313         if (reply == null) {
314             String message = "No mapping was found in the mapping database";
315             rpcResultBuilder = RpcResultBuilder.<GetMappingWithXtrIdOutput>failed()
316                     .withError(ErrorType.APPLICATION, ErrorTag.DATA_MISSING, message);
317         } else {
318             final MappingRecord convertedReply = convertFromBinaryIfNecessary(reply.getRecord());
319             rpcResultBuilder = RpcResultBuilder.success(new GetMappingWithXtrIdOutputBuilder()
320                     .setMappingRecord(convertedReply).build());
321         }
322
323         return rpcResultBuilder.buildFuture();
324     }
325
326     @Override
327     public ListenableFuture<RpcResult<RemoveKeyOutput>> removeKey(RemoveKeyInput input) {
328         requireNonNull(input, "remove-key RPC input must be not null!");
329         LOG.trace("RPC received to remove the following key: {}", input);
330
331         RpcResultBuilder<RemoveKeyOutput> rpcResultBuilder;
332
333         dsbe.removeAuthenticationKey(RPCInputConvertorUtil.toAuthenticationKey(input));
334
335         rpcResultBuilder = RpcResultBuilder.success(new RemoveKeyOutputBuilder().build());
336
337         return rpcResultBuilder.buildFuture();
338     }
339
340     @Override
341     public ListenableFuture<RpcResult<RemoveMappingOutput>> removeMapping(RemoveMappingInput input) {
342         requireNonNull(input, "remove-mapping RPC input must be not null!");
343         LOG.trace("RPC received to remove the following mapping: {}", input);
344
345         RpcResultBuilder<RemoveMappingOutput> rpcResultBuilder;
346
347         dsbe.removeMapping(RPCInputConvertorUtil.toMapping(input));
348
349         rpcResultBuilder = RpcResultBuilder.success(new RemoveMappingOutputBuilder().build());
350
351         return rpcResultBuilder.buildFuture();
352     }
353
354     @Override
355     public void removeMapping(MappingOrigin origin, Eid key) {
356         if (origin.equals(MappingOrigin.Southbound)) {
357             mappingSystem.removeMapping(origin, key);
358         }
359         dsbe.removeMapping(DSBEInputUtil.toMapping(origin, key));
360     }
361
362     @Override
363     public ListenableFuture<RpcResult<UpdateKeyOutput>> updateKey(UpdateKeyInput input) {
364         requireNonNull(input, "update-key RPC input must be not null!");
365         LOG.trace("RPC received to update the following key: {}", input);
366
367         RpcResultBuilder<UpdateKeyOutput> rpcResultBuilder;
368
369         MappingAuthkey key = mappingSystem.getAuthenticationKey(convertToBinaryIfNecessary(input.getEid()));
370
371         if (key == null) {
372             String message = "Key doesn't exist! Please use add-key if you want to create a new authentication key.";
373             rpcResultBuilder = RpcResultBuilder.<UpdateKeyOutput>failed()
374                     .withError(ErrorType.PROTOCOL, ErrorTag.DATA_MISSING, message);
375             return rpcResultBuilder.buildFuture();
376         }
377
378         dsbe.updateAuthenticationKey(RPCInputConvertorUtil.toAuthenticationKey(input));
379         rpcResultBuilder = RpcResultBuilder.success(new UpdateKeyOutputBuilder().build());
380
381         return rpcResultBuilder.buildFuture();
382     }
383
384     @Override
385     public ListenableFuture<RpcResult<UpdateMappingOutput>> updateMapping(UpdateMappingInput input) {
386         LOG.trace("RPC received to update the following mapping: {}", input);
387         requireNonNull(input, "update-mapping RPC input must be not null!");
388
389         RpcResultBuilder<UpdateMappingOutput> rpcResultBuilder;
390
391         dsbe.updateMapping(RPCInputConvertorUtil.toMapping(input));
392
393         rpcResultBuilder = RpcResultBuilder.success(new UpdateMappingOutputBuilder().build());
394
395         return rpcResultBuilder.buildFuture();
396     }
397
398     @Override
399     public ListenableFuture<RpcResult<RemoveKeysOutput>> removeKeys(RemoveKeysInput input) {
400         // TODO Auto-generated method stub
401         return null;
402     }
403
404     @Override
405     public ListenableFuture<RpcResult<RemoveMappingsOutput>> removeMappings(RemoveMappingsInput input) {
406         // TODO Auto-generated method stub
407         return null;
408     }
409
410     @Override
411     public ListenableFuture<RpcResult<GetKeysOutput>> getKeys(GetKeysInput input) {
412         // TODO Auto-generated method stub
413         return null;
414     }
415
416     @Override
417     public ListenableFuture<RpcResult<AddMappingsOutput>> addMappings(AddMappingsInput input) {
418         // TODO Auto-generated method stub
419         return null;
420     }
421
422     @Override
423     public ListenableFuture<RpcResult<UpdateKeysOutput>> updateKeys(UpdateKeysInput input) {
424         // TODO Auto-generated method stub
425         return null;
426     }
427
428     @Override
429     public ListenableFuture<RpcResult<RemoveAllMappingsOutput>> removeAllMappings(RemoveAllMappingsInput input) {
430         // TODO Auto-generated method stub
431         return null;
432     }
433
434     @Override
435     public ListenableFuture<RpcResult<RemoveAllKeysOutput>> removeAllKeys(RemoveAllKeysInput input) {
436         // TODO Auto-generated method stub
437         return null;
438     }
439
440     @Override
441     public ListenableFuture<RpcResult<GetAllKeysOutput>> getAllKeys(GetAllKeysInput input) {
442         // TODO Auto-generated method stub
443         return null;
444     }
445
446     @Override
447     public ListenableFuture<RpcResult<UpdateMappingsOutput>> updateMappings(UpdateMappingsInput input) {
448         // TODO Auto-generated method stub
449         return null;
450     }
451
452     @Override
453     public ListenableFuture<RpcResult<AddKeysOutput>> addKeys(AddKeysInput input) {
454         // TODO Auto-generated method stub
455         return null;
456     }
457
458     @Override
459     public ListenableFuture<RpcResult<GetAllMappingsOutput>> getAllMappings(GetAllMappingsInput input) {
460         // TODO Auto-generated method stub
461         return null;
462     }
463
464     @Override
465     public ListenableFuture<RpcResult<GetMappingsOutput>> getMappings(
466             GetMappingsInput input) {
467         // TODO Auto-generated method stub
468         return null;
469     }
470
471     @Override
472     public ListenableFuture<RpcResult<RemoveAllOperationalContentOutput>> removeAllOperationalContent(
473             RemoveAllOperationalContentInput input) {
474         RpcResultBuilder<RemoveAllOperationalContentOutput> rpcResultBuilder;
475
476         /*
477          * Since master nodes ignore datastore changes for southbound originated mappings, they need to be removed
478          * explicitly.
479          */
480         if (isMaster) {
481             mappingSystem.cleanSBMappings();
482         }
483         dsbe.removeAllOperationalDatastoreContent();
484
485         rpcResultBuilder = RpcResultBuilder.success(new RemoveAllOperationalContentOutputBuilder().build());
486
487         return rpcResultBuilder.buildFuture();
488     }
489
490     @Override
491     public Eid getWidestNegativePrefix(Eid key) {
492         return mappingSystem.getWidestNegativePrefix(key);
493     }
494
495     @Override
496     public Set<Eid> getSubtree(MappingOrigin origin, Eid key) {
497         return mappingSystem.getSubtree(origin, key);
498     }
499
500     @Override
501     public void addAuthenticationKey(Eid key, MappingAuthkey authKey) {
502         dsbe.addAuthenticationKey(DSBEInputUtil.toAuthenticationKey(key, authKey));
503     }
504
505     @Override
506     public MappingAuthkey getAuthenticationKey(Eid key) {
507         return mappingSystem.getAuthenticationKey(key);
508     }
509
510     @Override
511     public void removeAuthenticationKey(Eid key) {
512         dsbe.removeAuthenticationKey(DSBEInputUtil.toAuthenticationKey(key, null));
513     }
514
515     @Override
516     public void addData(MappingOrigin origin, Eid key, String subKey, Object data) {
517         mappingSystem.addData(origin, key, subKey, data);
518     }
519
520     @Override
521     public Object getData(MappingOrigin origin, Eid key, String subKey) {
522         return mappingSystem.getData(origin, key, subKey);
523     }
524
525     @Override
526     public void removeData(MappingOrigin origin, Eid key, String subKey) {
527         mappingSystem.removeData(origin, key, subKey);
528     }
529
530     @Override
531     public Eid getParentPrefix(Eid key) {
532         return mappingSystem.getParentPrefix(key);
533     }
534
535     @Override
536     public String printMappings() {
537         return mappingSystem.printMappings();
538     }
539
540     @Override
541     public String prettyPrintMappings() {
542         return mappingSystem.prettyPrintMappings();
543     }
544
545     @Override
546     public String printKeys() {
547         return mappingSystem.printKeys();
548     }
549
550     @Override
551     public String prettyPrintKeys() {
552         return mappingSystem.prettyPrintKeys();
553     }
554
555     @PreDestroy
556     @Deactivate
557     @Override
558     public void close() throws Exception {
559         LOG.info("Mapping Service is being destroyed!");
560         rpcRegistration.close();
561         keyListener.closeDataChangeListener();
562         mappingListener.closeDataChangeListener();
563         mappingSystem.destroy();
564     }
565
566     @Override
567     public void cleanCachedMappings() {
568         mappingSystem.cleanCaches();
569         dsbe.removeAllDatastoreContent();
570     }
571
572     private static Eid convertToBinaryIfNecessary(Eid eid) {
573         if (LispAddressUtil.addressNeedsConversionToBinary(eid.getAddress())) {
574             return LispAddressUtil.convertToBinary(eid);
575         }
576         return eid;
577     }
578
579     private static MappingRecord convertFromBinaryIfNecessary(MappingRecord originalRecord) {
580         List<LocatorRecord> originalLocators = originalRecord.getLocatorRecord();
581
582         List<LocatorRecord> convertedLocators = null;
583         if (originalLocators != null) {
584             // If convertedLocators is non-null, while originalLocators is also non-null, conversion has been made
585             convertedLocators = convertFromBinaryIfNecessary(originalLocators);
586         }
587
588         if (LispAddressUtil.addressNeedsConversionFromBinary(originalRecord.getEid().getAddress())
589                 || originalLocators != null && convertedLocators != null) {
590             MappingRecordBuilder mrb = new MappingRecordBuilder(originalRecord);
591             mrb.setEid(LispAddressUtil.convertFromBinary(originalRecord.getEid()));
592             if (convertedLocators != null) {
593                 mrb.setLocatorRecord(convertedLocators);
594             }
595             return mrb.build();
596         }
597         return originalRecord;
598     }
599
600     private static List<LocatorRecord> convertFromBinaryIfNecessary(List<LocatorRecord> originalLocators) {
601         List<LocatorRecord> convertedLocators = null;
602         for (LocatorRecord record : originalLocators) {
603             if (LispAddressUtil.addressNeedsConversionFromBinary(record.getRloc().getAddress())) {
604                 LocatorRecordBuilder lrb = new LocatorRecordBuilder(record);
605                 lrb.setRloc(LispAddressUtil.convertFromBinary(record.getRloc()));
606                 if (convertedLocators == null) {
607                     convertedLocators = new ArrayList<>();
608                 }
609                 convertedLocators.add(lrb.build());
610             }
611         }
612         if (convertedLocators != null) {
613             return convertedLocators;
614         }
615         return originalLocators;
616     }
617
618     @Override
619     public void setIsMaster(boolean isMaster) {
620         this.isMaster = isMaster;
621         mappingSystem.setIsMaster(isMaster);
622     }
623
624     @Override
625     public boolean isMaster() {
626         return isMaster;
627     }
628 }