2 * Copyright (c) 2015 Cisco Systems, Inc. All rights reserved.
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
8 package org.opendaylight.lispflowmapping.implementation;
10 import java.util.Arrays;
11 import java.util.concurrent.Future;
13 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
14 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
15 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
16 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
17 import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
18 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
19 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
20 import org.opendaylight.lispflowmapping.implementation.config.ConfigIni;
21 import org.opendaylight.lispflowmapping.implementation.mdsal.AuthenticationKeyDataListener;
22 import org.opendaylight.lispflowmapping.implementation.mdsal.DataStoreBackEnd;
23 import org.opendaylight.lispflowmapping.implementation.mdsal.MappingDataListener;
24 import org.opendaylight.lispflowmapping.implementation.util.DSBEInputUtil;
25 import org.opendaylight.lispflowmapping.implementation.util.RPCInputConvertorUtil;
26 import org.opendaylight.lispflowmapping.interfaces.dao.ILispDAO;
27 import org.opendaylight.lispflowmapping.interfaces.mappingservice.IMappingService;
28 import org.opendaylight.lispflowmapping.lisp.util.MaskUtil;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eidtolocatorrecords.EidToLocatorRecord;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.lispaddress.LispAddressContainer;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.AddKeyInput;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.AddKeyInputBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.AddMappingInput;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.AddMappingInputBuilder;
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.GetKeyInputBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetKeyOutput;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetKeyOutputBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetMappingInput;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.GetMappingInputBuilder;
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.MappingOrigin;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.MappingserviceService;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.RemoveKeyInput;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.RemoveKeyInputBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.RemoveMappingInput;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.RemoveMappingInputBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.SiteId;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.UpdateKeyInput;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.UpdateKeyInputBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.UpdateMappingInput;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.UpdateMappingInputBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.update.key.input.EidBuilder;
55 import org.opendaylight.yangtools.yang.common.RpcError;
56 import org.opendaylight.yangtools.yang.common.RpcResult;
57 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
61 import com.google.common.base.Preconditions;
62 import com.google.common.util.concurrent.Futures;
65 * Dispatcher of API calls that implements the RPC and Java APIs in mappingservice.yang and IMappingService
66 * respectively. It also coordinates and acts as container for all objects in charge of
67 * - saving and updating md-sal datastore stored mappings
68 * - monitoring md-sal datastore mapping updates and pushing them to the in memory mapping-system
69 * - in memory mapping-system
71 * @author Lorand Jakab
72 * @author Florin Coras
75 public class MappingService implements MappingserviceService, IMappingService, BindingAwareProvider, AutoCloseable {
76 protected static final Logger LOG = LoggerFactory.getLogger(MappingService.class);
77 private static final String NOT_FOUND_TAG = "data-missing";
78 private static final String DATA_EXISTS_TAG = "data-exists";
80 private MappingSystem mappingSystem;
81 private DataStoreBackEnd dsbe;
82 private RpcRegistration<MappingserviceService> mappingServiceRpc;
83 private AuthenticationKeyDataListener keyListener;
84 private MappingDataListener mappingListener;
87 private DataBroker dataBroker;
88 private RpcProviderRegistry rpcRegistry;
89 private BindingAwareBroker bindingAwareBroker;
90 private NotificationPublishService notificationPublishService;
92 private static final ConfigIni configIni = new ConfigIni();
93 private boolean overwritePolicy = configIni.mappingOverwriteIsSet();
94 private boolean notificationPolicy = configIni.smrIsSet();
95 private boolean iterateMask = true;
97 public MappingService() {
98 LOG.debug("MappingService created!");
101 public void setDataBroker(DataBroker dataBroker) {
102 this.dataBroker = dataBroker;
105 public void setRpcProviderRegistry(RpcProviderRegistry rpc) {
106 this.rpcRegistry = rpc;
109 public void setBindingAwareBroker(BindingAwareBroker broker) {
110 this.bindingAwareBroker = broker;
113 public void setNotificationPublishService(NotificationPublishService nps) {
114 this.notificationPublishService = nps;
117 public void setDaoService(ILispDAO dao) {
122 public void setMappingOverwrite(boolean overwrite) {
123 this.overwritePolicy = overwrite;
124 if (mappingSystem != null) {
125 mappingSystem.setOverwritePolicy(overwrite);
129 public void initialize() {
130 bindingAwareBroker.registerProvider(this);
132 mappingServiceRpc = rpcRegistry.addRpcImplementation(MappingserviceService.class, this);
133 dsbe = new DataStoreBackEnd(dataBroker);
135 mappingSystem = new MappingSystem(dao, iterateMask, notificationPolicy, overwritePolicy);
136 mappingSystem.setDataStoreBackEnd(dsbe);
137 mappingSystem.initialize();
139 keyListener = new AuthenticationKeyDataListener(dataBroker, mappingSystem);
140 mappingListener = new MappingDataListener(dataBroker, mappingSystem, notificationPublishService);
144 public Future<RpcResult<Void>> addKey(AddKeyInput input) {
145 Preconditions.checkNotNull(input, "add-key RPC input must be not null!");
146 LOG.trace("RPC received to add the following key: " + input.toString());
148 RpcResultBuilder<Void> rpcResultBuilder;
150 // XXX: to remove once RPC API has been updated to remove explicit mask
151 input = new AddKeyInputBuilder(input).setLispAddressContainer(
152 MaskUtil.fixMask(input.getLispAddressContainer(), input.getMaskLength())).build();
154 String key = mappingSystem.getAuthenticationKey(input.getLispAddressContainer());
157 String message = "Key already exists! Please use update-key if you want to change it.";
158 rpcResultBuilder = RpcResultBuilder.<Void>failed()
159 .withError(RpcError.ErrorType.PROTOCOL, DATA_EXISTS_TAG, message);
160 return Futures.immediateFuture(rpcResultBuilder.build());
163 dsbe.addAuthenticationKey(RPCInputConvertorUtil.toAuthenticationKey(input));
164 rpcResultBuilder = RpcResultBuilder.success();
166 return Futures.immediateFuture(rpcResultBuilder.build());
170 public Future<RpcResult<Void>> addMapping(AddMappingInput input) {
171 Preconditions.checkNotNull(input, "add-mapping RPC input must be not null!");
172 LOG.trace("RPC received to add the following mapping: " + input.toString());
174 // XXX: to remove once RPC API has been updated to remove explicit mask
175 input = new AddMappingInputBuilder(input).setLispAddressContainer(
176 MaskUtil.fixMask(input.getLispAddressContainer(), input.getMaskLength())).build();
178 dsbe.addMapping(RPCInputConvertorUtil.toMapping(input));
180 RpcResultBuilder<Void> rpcResultBuilder;
182 rpcResultBuilder = RpcResultBuilder.success();
184 return Futures.immediateFuture(rpcResultBuilder.build());
188 public Future<RpcResult<GetKeyOutput>> getKey(GetKeyInput input) {
189 Preconditions.checkNotNull(input, "get-key RPC input must be not null!");
190 LOG.trace("RPC received to get the following key: " + input.toString());
192 // XXX: to remove once RPC API has been updated to remove explicit mask
193 input = new GetKeyInputBuilder(input).setLispAddressContainer(
194 MaskUtil.fixMask(input.getLispAddressContainer(), input.getMaskLength())).build();
196 RpcResultBuilder<GetKeyOutput> rpcResultBuilder;
198 String key = mappingSystem.getAuthenticationKey(input.getLispAddressContainer());
201 String message = "Key was not found in the mapping database";
202 rpcResultBuilder = RpcResultBuilder.<GetKeyOutput>failed()
203 .withError(RpcError.ErrorType.APPLICATION, NOT_FOUND_TAG, message);
205 rpcResultBuilder = RpcResultBuilder.success(new GetKeyOutputBuilder().setAuthkey(key));
208 return Futures.immediateFuture(rpcResultBuilder.build());
212 public Future<RpcResult<GetMappingOutput>> getMapping(GetMappingInput input) {
213 Preconditions.checkNotNull(input, "get-mapping RPC input must be not null!");
214 LOG.trace("RPC received to get the following mapping: " + input.toString());
216 // XXX: to remove once RPC API has been updated to remove explicit mask
217 input = new GetMappingInputBuilder(input).setLispAddressContainer(
218 MaskUtil.fixMask(input.getLispAddressContainer(), input.getMaskLength())).build();
220 RpcResultBuilder<GetMappingOutput> rpcResultBuilder;
222 EidToLocatorRecord reply = (EidToLocatorRecord) mappingSystem.getMapping(input.getLispAddressContainer());
225 String message = "No mapping was found in the mapping database";
226 rpcResultBuilder = RpcResultBuilder.<GetMappingOutput>failed()
227 .withError(RpcError.ErrorType.APPLICATION, NOT_FOUND_TAG, message);
229 rpcResultBuilder = RpcResultBuilder.success(new GetMappingOutputBuilder().setEidToLocatorRecord(Arrays
233 return Futures.immediateFuture(rpcResultBuilder.build());
237 public Future<RpcResult<Void>> removeKey(RemoveKeyInput input) {
238 Preconditions.checkNotNull(input, "remove-key RPC input must be not null!");
239 LOG.trace("RPC received to remove the following key: " + input.toString());
241 // XXX: to remove once RPC API has been updated to remove explicit mask
242 input = new RemoveKeyInputBuilder(input).setLispAddressContainer(
243 MaskUtil.fixMask(input.getLispAddressContainer(), input.getMaskLength())).build();
245 RpcResultBuilder<Void> rpcResultBuilder;
247 dsbe.removeAuthenticationKey(RPCInputConvertorUtil.toAuthenticationKey(input));
249 rpcResultBuilder = RpcResultBuilder.success();
251 return Futures.immediateFuture(rpcResultBuilder.build());
255 public Future<RpcResult<Void>> removeMapping(RemoveMappingInput input) {
256 Preconditions.checkNotNull(input, "remove-mapping RPC input must be not null!");
257 LOG.trace("RPC received to remove the following mapping: " + input.toString());
259 // XXX: to remove once RPC API has been updated to remove explicit mask
260 input = new RemoveMappingInputBuilder(input).setLispAddressContainer(
261 MaskUtil.fixMask(input.getLispAddressContainer(), input.getMaskLength())).build();
263 RpcResultBuilder<Void> rpcResultBuilder;
265 dsbe.removeMapping(RPCInputConvertorUtil.toMapping(input));
267 rpcResultBuilder = RpcResultBuilder.success();
269 return Futures.immediateFuture(rpcResultBuilder.build());
273 public Future<RpcResult<Void>> updateKey(UpdateKeyInput input) {
274 Preconditions.checkNotNull(input, "update-key RPC input must be not null!");
275 LOG.trace("RPC received to update the following key: " + input.toString());
277 // XXX: to remove once RPC API has been updated to remove explicit mask
278 input = new UpdateKeyInputBuilder(input).setEid(
279 new EidBuilder(input.getEid()).setLispAddressContainer(
280 MaskUtil.fixMask(input.getEid().getLispAddressContainer(), input.getEid()
281 .getMaskLength())).build()).build();
283 RpcResultBuilder<Void> rpcResultBuilder;
285 String key = mappingSystem.getAuthenticationKey(input.getEid().getLispAddressContainer());
288 String message = "Key doesn't exist! Please use add-key if you want to create a new authentication key.";
289 rpcResultBuilder = RpcResultBuilder.<Void>failed()
290 .withError(RpcError.ErrorType.PROTOCOL, NOT_FOUND_TAG, message);
291 return Futures.immediateFuture(rpcResultBuilder.build());
294 dsbe.updateAuthenticationKey(RPCInputConvertorUtil.toAuthenticationKey(input));
295 rpcResultBuilder = RpcResultBuilder.success();
297 return Futures.immediateFuture(rpcResultBuilder.build());
301 public Future<RpcResult<Void>> updateMapping(UpdateMappingInput input) {
302 LOG.trace("RPC received to update the following mapping: " + input.toString());
303 Preconditions.checkNotNull(input, "update-mapping RPC input must be not null!");
305 // XXX: to remove once RPC API has been updated to remove explicit mask
306 input = new UpdateMappingInputBuilder(input).setLispAddressContainer(
307 MaskUtil.fixMask(input.getLispAddressContainer(), input.getMaskLength())).build();
309 RpcResultBuilder<Void> rpcResultBuilder;
311 dsbe.updateMapping(RPCInputConvertorUtil.toMapping(input));
313 rpcResultBuilder = RpcResultBuilder.success();
315 return Futures.immediateFuture(rpcResultBuilder.build());
319 public void addMapping(MappingOrigin origin, LispAddressContainer key, SiteId siteId, Object data) {
320 dsbe.addMapping(DSBEInputUtil.toMapping(origin, key, siteId, (EidToLocatorRecord) data));
321 mappingSystem.updateMappingRegistration(origin, key);
325 public Object getMapping(MappingOrigin origin, LispAddressContainer key) {
326 return mappingSystem.getMapping(origin, key);
330 public Object getMapping(LispAddressContainer key) {
331 return mappingSystem.getMapping(key);
335 public Object getMapping(LispAddressContainer srcKey, LispAddressContainer dstKey) {
336 return mappingSystem.getMapping(srcKey, dstKey);
340 public void removeMapping(MappingOrigin origin, LispAddressContainer key) {
341 dsbe.removeMapping(DSBEInputUtil.toMapping(origin, key));
345 public void addAuthenticationKey(LispAddressContainer key, String authKey) {
346 dsbe.addAuthenticationKey(DSBEInputUtil.toAuthenticationKey(key, authKey));
350 public String getAuthenticationKey(LispAddressContainer key) {
351 return mappingSystem.getAuthenticationKey(key);
355 public void removeAuthenticationKey(LispAddressContainer key) {
356 dsbe.removeAuthenticationKey(DSBEInputUtil.toAuthenticationKey(key, null));
360 public void addData(MappingOrigin origin, LispAddressContainer key, String subKey, Object data) {
361 mappingSystem.addData(origin, key, subKey, data);
365 public Object getData(MappingOrigin origin, LispAddressContainer key, String subKey) {
366 return mappingSystem.getData(origin, key, subKey);
370 public void removeData(MappingOrigin origin, LispAddressContainer key, String subKey) {
371 mappingSystem.removeData(origin, key, subKey);
375 public String printMappings() {
376 return mappingSystem.printMappings();
380 public void onSessionInitiated(ProviderContext session) {
381 LOG.info("Mapping Service provider session initializing!");
385 public void close() throws Exception {
386 LOG.info("Mapping Service is being destroyed!");
387 mappingServiceRpc.close();
388 keyListener.closeDataChangeListener();
389 mappingListener.closeDataChangeListener();
393 public void cleanCachedMappings() {
394 mappingSystem.cleanCaches();
395 dsbe.removeAllMappings();