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