X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=mappingservice%2Fimplementation%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Flispflowmapping%2Fimplementation%2FLispMappingService.java;h=f3bb5d7680a71e8d77e2c815ceac9962471bb503;hb=6445920dbac192e45402c47bdd694571d3196d40;hp=825f2030e4101540c6c1e0ddfa2c4e06bda77565;hpb=22e833cb903bd6055fec73a9d571a7ca9f4b2d90;p=lispflowmapping.git diff --git a/mappingservice/implementation/src/main/java/org/opendaylight/lispflowmapping/implementation/LispMappingService.java b/mappingservice/implementation/src/main/java/org/opendaylight/lispflowmapping/implementation/LispMappingService.java index 825f2030e..f3bb5d768 100644 --- a/mappingservice/implementation/src/main/java/org/opendaylight/lispflowmapping/implementation/LispMappingService.java +++ b/mappingservice/implementation/src/main/java/org/opendaylight/lispflowmapping/implementation/LispMappingService.java @@ -8,238 +8,160 @@ package org.opendaylight.lispflowmapping.implementation; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; import java.util.List; - +import java.util.Set; +import javax.annotation.PreDestroy; +import javax.inject.Inject; +import javax.inject.Singleton; import org.apache.commons.lang3.tuple.MutablePair; import org.apache.commons.lang3.tuple.Pair; -import org.eclipse.osgi.framework.console.CommandInterpreter; -import org.eclipse.osgi.framework.console.CommandProvider; -import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; -import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext; -import org.opendaylight.controller.sal.binding.api.BindingAwareProvider; -import org.opendaylight.controller.sal.binding.api.NotificationListener; -import org.opendaylight.controller.sal.binding.api.NotificationService; -import org.opendaylight.lispflowmapping.implementation.config.ConfigIni; -import org.opendaylight.lispflowmapping.implementation.dao.HashMapDb; -import org.opendaylight.lispflowmapping.implementation.dao.MappingServiceKey; -import org.opendaylight.lispflowmapping.implementation.dao.MappingServiceKeyUtil; -import org.opendaylight.lispflowmapping.implementation.dao.MappingServiceNoMaskKey; +import org.opendaylight.lispflowmapping.config.ConfigIni; import org.opendaylight.lispflowmapping.implementation.lisp.MapResolver; import org.opendaylight.lispflowmapping.implementation.lisp.MapServer; -import org.opendaylight.lispflowmapping.implementation.mdsal.AuthenticationKeyDataListener; -import org.opendaylight.lispflowmapping.implementation.mdsal.DataStoreBackEnd; -import org.opendaylight.lispflowmapping.implementation.mdsal.MappingDataListener; -import org.opendaylight.lispflowmapping.implementation.serializer.LispMessage; -import org.opendaylight.lispflowmapping.implementation.util.LispAFIConvertor; import org.opendaylight.lispflowmapping.implementation.util.LispNotificationHelper; -import org.opendaylight.lispflowmapping.interfaces.dao.ILispDAO; -import org.opendaylight.lispflowmapping.interfaces.dao.ILispTypeConverter; -import org.opendaylight.lispflowmapping.interfaces.dao.IRowVisitor; import org.opendaylight.lispflowmapping.interfaces.lisp.IFlowMapping; -import org.opendaylight.lispflowmapping.interfaces.lisp.IFlowMappingShell; import org.opendaylight.lispflowmapping.interfaces.lisp.IMapNotifyHandler; import org.opendaylight.lispflowmapping.interfaces.lisp.IMapRequestResultHandler; import org.opendaylight.lispflowmapping.interfaces.lisp.IMapResolverAsync; -import org.opendaylight.lispflowmapping.interfaces.lisp.IMapServerAsync; -import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.AddMapping; -import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.LfmControlPlaneService; -import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.MapNotify; -import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.MapRegister; -import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.MapReply; -import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.MapRequest; -import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.RequestMapping; -import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.SendMapNotifyInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.SendMapReplyInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.SendMapRequestInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.LispAddressContainer; -import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.ipv4.Ipv4AddressBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.mapnotifymessage.MapNotifyBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.mapreplymessage.MapReplyBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.maprequestmessage.MapRequestBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.transportaddress.TransportAddress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.transportaddress.TransportAddressBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mapping.database.rev150314.db.instance.Mapping; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber; -import org.opendaylight.yangtools.yang.binding.Notification; -import org.osgi.framework.BundleContext; -import org.osgi.framework.FrameworkUtil; +import org.opendaylight.lispflowmapping.interfaces.lisp.ISmrNotificationListener; +import org.opendaylight.lispflowmapping.interfaces.mappingservice.IMappingService; +import org.opendaylight.lispflowmapping.lisp.type.LispMessage; +import org.opendaylight.lispflowmapping.lisp.util.LispAddressStringifier; +import org.opendaylight.mdsal.binding.api.NotificationService; +import org.opendaylight.mdsal.binding.api.NotificationService.CompositeListener; +import org.opendaylight.mdsal.binding.api.RpcProviderService; +import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService; +import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider; +import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.AddMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.GotMapNotify; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.GotMapReply; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapNotify; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapRegister; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapReply; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapRequest; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MappingKeepAlive; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.RequestMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.XtrId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.XtrReplyMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.XtrRequestMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.metadata.container.MapRegisterCacheMetadata; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.metadata.container.map.register.cache.metadata.EidLispAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapnotifymessage.MapNotifyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapreplymessage.MapReplyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.maprequestmessage.MapRequestBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.rloc.container.Rloc; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.transport.address.TransportAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.transport.address.TransportAddressBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.sb.rev150904.OdlLispSbService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.sb.rev150904.SendMapNotifyInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.sb.rev150904.SendMapReplyInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.sb.rev150904.SendMapRequestInputBuilder; +import org.opendaylight.yangtools.concepts.Registration; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.Reference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class LispMappingService implements CommandProvider, IFlowMapping, IFlowMappingShell, BindingAwareProvider, - IMapRequestResultHandler, IMapNotifyHandler { - protected static final Logger LOG = LoggerFactory.getLogger(LispMappingService.class); - - private static final ConfigIni configIni = new ConfigIni(); - private AuthenticationKeyDataListener keyListener; - private MappingDataListener mappingListener; - private ILispDAO lispDao = null; - private IMapResolverAsync mapResolver; - private IMapServerAsync mapServer; - private volatile boolean shouldIterateMask; - private volatile boolean shouldAuthenticate; - private volatile boolean smr = configIni.smrIsSet(); - private ThreadLocal tlsMapReply = new ThreadLocal(); - private ThreadLocal tlsMapNotify = new ThreadLocal(); - private ThreadLocal> tlsMapRequest = new ThreadLocal>(); - - private LfmControlPlaneService lispSB = null; - - private ProviderContext session; - - private DataStoreBackEnd dsbe; - private NotificationService notificationService; - private static LispMappingService lfmService = null; - - class LispIpv4AddressInMemoryConverter implements ILispTypeConverter { - } - - class LispIpv6AddressInMemoryConverter implements ILispTypeConverter { - } - - class MappingServiceKeyConvertor implements ILispTypeConverter { - } - - class MappingServiceNoMaskKeyConvertor implements ILispTypeConverter { - } - - public static LispMappingService getLispMappingService() { - return lfmService; - } +@Singleton +@Component(service = {IFlowMapping.class, IMapRequestResultHandler.class, IMapNotifyHandler.class}, + immediate = true, property = "type=default") +public class LispMappingService implements IFlowMapping, IMapRequestResultHandler, + IMapNotifyHandler, AutoCloseable, ClusterSingletonService { + private static final String LISPFLOWMAPPING_ENTITY_NAME = "lispflowmapping"; + private static final ServiceGroupIdentifier SERVICE_GROUP_IDENTIFIER = ServiceGroupIdentifier.create( + LISPFLOWMAPPING_ENTITY_NAME); - void setBindingAwareBroker(BindingAwareBroker bindingAwareBroker) { - LOG.debug("BindingAwareBroker set!"); - BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext(); - bindingAwareBroker.registerProvider(this, bundleContext); + private static final Logger LOG = LoggerFactory.getLogger(LispMappingService.class); - // For the time being we initialize variables here. But once we remove the activator, these should - // be moved to the constructor. - lfmService = this; - setLispDao(new HashMapDb()); - } + private volatile boolean smr = ConfigIni.getInstance().smrIsSet(); + private volatile String elpPolicy = ConfigIni.getInstance().getElpPolicy(); - void unsetBindingAwareBroker(BindingAwareBroker bindingAwareBroker) { - LOG.debug("BindingAwareBroker was unset in LispMappingService"); - lfmService = null; - } + private ThreadLocal tlsMapReply = new ThreadLocal<>(); + private ThreadLocal>> tlsMapNotify = new ThreadLocal<>(); + private ThreadLocal> tlsMapRequest = new ThreadLocal<>(); - public void basicInit(ILispDAO dao) { - lispDao = dao; - mapResolver = new MapResolver(dao); - mapServer = new MapServer(dao); - } - - void setLispDao(ILispDAO dao) { - LOG.trace("LispDAO set in LispMappingService"); - basicInit(dao); + private IMapResolverAsync mapResolver; + private MapServer mapServer; + + private final IMappingService mapService; + private final OdlLispSbService lispSB; + private final ClusterSingletonServiceProvider clusterSingletonService; + private final NotificationService notificationService; + private final Registration rpcRegistration; + private final Registration listenerRegistration; + private final Registration cssRegistration; + + @Inject + @Activate + public LispMappingService(@Reference final IMappingService mappingService, + @Reference final OdlLispSbService odlLispService, + @Reference final ClusterSingletonServiceProvider clusterSingletonService, + @Reference final RpcProviderService rpcProviderService, + @Reference final NotificationService notificationService) { + this.mapService = mappingService; + this.lispSB = odlLispService; + this.clusterSingletonService = clusterSingletonService; + this.notificationService = notificationService; + + // initialize + listenerRegistration = notificationService.registerCompositeListener(new CompositeListener(Set.of( + new CompositeListener.Component<>(AddMapping.class, this::onAddMapping), + new CompositeListener.Component<>(GotMapNotify.class, this::onGotMapNotify), + new CompositeListener.Component<>(RequestMapping.class, this::onRequestMapping), + new CompositeListener.Component<>(GotMapReply.class, this::onGotMapReply), + new CompositeListener.Component<>(XtrRequestMapping.class, this::onXtrRequestMapping), + new CompositeListener.Component<>(XtrReplyMapping.class, this::onXtrReplyMapping), + new CompositeListener.Component<>(MappingKeepAlive.class, this::onMappingKeepAlive)))); + rpcRegistration = rpcProviderService.registerRpcImplementation(OdlLispSbService.class, lispSB); + + mapResolver = new MapResolver(mapService, smr, elpPolicy, this); + mapServer = new MapServer(mapService, smr, this, notificationService); + cssRegistration = clusterSingletonService.registerClusterSingletonService(this); + mapResolver.setSmrNotificationListener((ISmrNotificationListener) mapServer); + LOG.info("LISP (RFC6830) Mapping Service initialized"); } - void unsetLispDao(ILispDAO dao) { - LOG.trace("LispDAO was unset in LispMappingService"); - mapServer = null; - mapResolver = null; - lispDao = null; + public boolean shouldUseSmr() { + return this.smr; } - public void init() { - try { - registerWithOSGIConsole(); - LOG.info("LISP (RFC6830) Mapping Service init finished"); - } catch (Exception e) { - LOG.error(e.getStackTrace().toString()); + @Override + public void setShouldUseSmr(boolean shouldUseSmr) { + this.smr = shouldUseSmr; + if (mapServer != null) { + mapServer.setSubscriptionService(shouldUseSmr); } - } - - private void registerWithOSGIConsole() { - BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext(); - bundleContext.registerService(CommandProvider.class.getName(), this, null); - } - - public void destroy() { - LOG.info("LISP (RFC6830) Mapping Service is destroyed!"); - mapResolver = null; - mapServer = null; - closeDataListeners(); - } - - public void _removeEid(final CommandInterpreter ci) { - LispAddressContainer eid = LispAFIConvertor.getIPContainer(ci.nextArgument()); - lispDao.remove(MappingServiceKeyUtil.generateMappingServiceKey(eid)); - } - - public void _dumpAll(final CommandInterpreter ci) { - ci.print(printMappings()); - } - - public String printMappings() { - final StringBuffer sb = new StringBuffer(); - sb.append("EID\tRLOCs\n"); - lispDao.getAll(new IRowVisitor() { - String lastKey = ""; - - public void visitRow(Object keyId, String valueKey, Object value) { - String key = keyId.getClass().getSimpleName() + "#" + keyId; - if (!lastKey.equals(key)) { - sb.append("\n" + key + "\t"); - } - sb.append(valueKey + "=" + value + "\t"); - lastKey = key; - } - }); - sb.append("\n"); - return sb.toString(); - } - - public void _setShouldOverwriteRlocs(final CommandInterpreter ci) { - try { - boolean shouldOverwriteRloc = Boolean.parseBoolean(ci.nextArgument()); - setOverwrite(shouldOverwriteRloc); - } catch (Exception e) { - ci.println("Bad Usage!!"); + if (mapResolver != null) { + mapResolver.setSubscriptionService(shouldUseSmr); } - - } - - public void _addDefaultPassword(final CommandInterpreter ci) { - addDefaultKeyIPv4(); + ConfigIni.getInstance().setSmr(shouldUseSmr); } - public void addDefaultKeyIPv4() { - LispAddressContainer address = LispAFIConvertor.toContainer( - new Ipv4AddressBuilder().setIpv4Address(new Ipv4Address("0.0.0.0")).build()); - addAuthenticationKey(address, 0, "password"); - } - - public String getHelp() { - StringBuffer help = new StringBuffer(); - help.append("---LISP Mapping Service---\n"); - help.append("\t dumpAll - Dump all current EID -> RLOC mappings\n"); - help.append("\t removeEid - Remove a single EID (/32 or /128)\n"); - help.append("\t setShouldOverwriteRlocs - Set the map server's behavior regarding existing RLOCs\n"); - help.append("\t addDefaultPassword - Add \"password\" as default password for IPv4 EIDs"); - return help.toString(); + public NotificationService getNotificationService() { + return this.notificationService; } + @Override public MapReply handleMapRequest(MapRequest request) { - return handleMapRequest(request, smr); - } - - public MapReply handleMapRequest(MapRequest request, boolean smr) { - LOG.debug("DAO: Retrieving mapping for {}/{}", - LispAFIConvertor.toString(request.getEidRecord().get(0).getLispAddressContainer()), - request.getEidRecord().get(0).getMask()); + if (LOG.isDebugEnabled()) { + LOG.debug("LISP: Retrieving mapping for {}", + LispAddressStringifier.getString(request.getEidItem().get(0).getEid())); + } tlsMapReply.set(null); tlsMapRequest.set(null); - mapResolver.handleMapRequest(request, smr, this); - // After this invocation we assume that the thread local is filled with - // the reply + mapResolver.handleMapRequest(request); + // After this invocation we assume that the thread local is filled with the reply if (tlsMapRequest.get() != null) { SendMapRequestInputBuilder smrib = new SendMapRequestInputBuilder(); - new MapRequestBuilder(tlsMapRequest.get().getLeft()); smrib.setMapRequest(new MapRequestBuilder(tlsMapRequest.get().getLeft()).build()); smrib.setTransportAddress(tlsMapRequest.get().getRight()); getLispSB().sendMapRequest(smrib.build()); @@ -247,179 +169,169 @@ public class LispMappingService implements CommandProvider, IFlowMapping, IFlowM } else { return tlsMapReply.get(); } - } - public MapNotify handleMapRegister(MapRegister mapRegister) { - return handleMapRegister(mapRegister, smr); - } - - public MapNotify handleMapRegister(MapRegister mapRegister, boolean smr) { - LOG.debug("DAO: Adding mapping for {}/{}", - LispAFIConvertor.toString(mapRegister.getEidToLocatorRecord().get(0).getLispAddressContainer()), - mapRegister.getEidToLocatorRecord().get(0).getMaskLength()); + @Override + public Pair> handleMapRegister(MapRegister mapRegister) { + if (LOG.isDebugEnabled()) { + LOG.debug("LISP: Adding mapping for {}", + LispAddressStringifier.getString(mapRegister.getMappingRecordItem().get(0) + .getMappingRecord().getEid())); + } tlsMapNotify.set(null); - mapServer.handleMapRegister(mapRegister, smr, this); - // After this invocation we assume that the thread local is filled with - // the reply + mapServer.handleMapRegister(mapRegister); + // After this invocation we assume that the thread local is filled with the reply return tlsMapNotify.get(); } - public String getAuthenticationKey(LispAddressContainer address, int maskLen) { - LOG.debug("DAO: Retrieving authentication key for {}/{}", LispAFIConvertor.toString(address), maskLen); - return mapServer.getAuthenticationKey(address, maskLen); - } - - public void removeAuthenticationKey(LispAddressContainer address, int maskLen) { - LOG.debug("DAO: Removing authentication key for {}/{}", LispAFIConvertor.toString(address), maskLen); - mapServer.removeAuthenticationKey(address, maskLen); - } - - public void addAuthenticationKey(LispAddressContainer address, int maskLen, String key) { - LOG.debug("DAO: Adding authentication key '{}' for {}/{}", key, LispAFIConvertor.toString(address), maskLen); - mapServer.addAuthenticationKey(address, maskLen, key); - } - - public void removeMapping(LispAddressContainer address, int maskLen) { - LOG.debug("DAO: Removing mapping for {}/{}", LispAFIConvertor.toString(address), maskLen); - mapServer.removeMapping(address, maskLen, smr, this); - } - - public boolean shouldIterateMask() { - return this.shouldIterateMask; - } - - public boolean shouldUseSmr() { - return this.smr; - } - - public void setShouldUseSmr(boolean smr) { - this.smr = smr; - } - - public void setShouldIterateMask(boolean shouldIterateMask) { - this.shouldIterateMask = shouldIterateMask; - this.mapResolver.setShouldIterateMask(shouldIterateMask); - this.mapServer.setShouldIterateMask(shouldIterateMask); - } - public void setShouldAuthenticate(boolean shouldAuthenticate) { - this.shouldAuthenticate = shouldAuthenticate; this.mapResolver.setShouldAuthenticate(shouldAuthenticate); - this.mapServer.setShouldAuthenticate(shouldAuthenticate); } - public boolean shouldAuthenticate() { - return shouldAuthenticate; + private void sendMapNotify(MapNotify mapNotify, TransportAddress address) { + SendMapNotifyInputBuilder smnib = new SendMapNotifyInputBuilder(); + smnib.setMapNotify(new MapNotifyBuilder(mapNotify).build()); + smnib.setTransportAddress(address); + getLispSB().sendMapNotify(smnib.build()); } - @Override - public void onSessionInitiated(ProviderContext session) { - LOG.info("Lisp Consumer session initialized!"); - notificationService = session.getSALService(NotificationService.class); - dsbe = new DataStoreBackEnd(session.getSALService(DataBroker.class)); - registerNotificationListener(AddMapping.class, new MapRegisterNotificationHandler()); - registerNotificationListener(RequestMapping.class, new MapRequestNotificationHandler()); - registerDataListeners(session.getSALService(DataBroker.class)); - this.session = session; + @VisibleForTesting + void onAddMapping(AddMapping mapRegisterNotification) { + Pair> result = handleMapRegister(mapRegisterNotification.getMapRegister()); + if (result != null && result.getLeft() != null) { + MapNotify mapNotify = result.getLeft(); + List rlocs = result.getRight(); + if (rlocs == null) { + TransportAddressBuilder tab = new TransportAddressBuilder(); + tab.setIpAddress(mapRegisterNotification.getTransportAddress().getIpAddress()); + tab.setPort(new PortNumber(LispMessage.PORT_NUMBER)); + sendMapNotify(mapNotify, tab.build()); + } else { + for (TransportAddress ta : rlocs) { + sendMapNotify(mapNotify, ta); + } + } + } else { + LOG.debug("Not sending Map-Notify"); + } } - private void registerDataListeners(DataBroker broker) { - keyListener = new AuthenticationKeyDataListener(broker, this); - mappingListener = new MappingDataListener(broker, this); + @VisibleForTesting + void onRequestMapping(RequestMapping mapRequestNotification) { + MapReply mapReply = handleMapRequest(mapRequestNotification.getMapRequest()); + if (mapReply != null) { + SendMapReplyInputBuilder smrib = new SendMapReplyInputBuilder(); + smrib.setMapReply(new MapReplyBuilder(mapReply).build()); + smrib.setTransportAddress(mapRequestNotification.getTransportAddress()); + getLispSB().sendMapReply(smrib.build()); + } else { + LOG.debug("handleMapRequest: Got null MapReply"); + } } - private void closeDataListeners() { - keyListener.closeDataChangeListener(); - mappingListener.closeDataChangeListener(); + @VisibleForTesting + void onGotMapReply(GotMapReply notification) { + LOG.debug("Received GotMapReply notification, ignoring"); } - public void registerNotificationListener(Class notificationType, NotificationListener listener) { - notificationService.registerNotificationListener(notificationType, listener); + @VisibleForTesting + void onGotMapNotify(GotMapNotify notification) { + LOG.debug("Received GotMapNotify notification, ignoring"); } - private class MapRegisterNotificationHandler implements NotificationListener { - - @Override - public void onNotification(AddMapping mapRegisterNotification) { - MapNotify mapNotify = handleMapRegister(mapRegisterNotification.getMapRegister(), smr); - if (mapNotify != null) { - TransportAddressBuilder tab = new TransportAddressBuilder(); - tab.setIpAddress(mapRegisterNotification.getTransportAddress().getIpAddress()); - tab.setPort(new PortNumber(LispMessage.PORT_NUM)); - SendMapNotifyInputBuilder smnib = new SendMapNotifyInputBuilder(); - smnib.setMapNotify(new MapNotifyBuilder(mapNotify).build()); - smnib.setTransportAddress(tab.build()); - getLispSB().sendMapNotify(smnib.build()); - } else { - LOG.warn("got null map notify"); - } - - List mappings = LispNotificationHelper.getMapping(mapRegisterNotification); - for (Mapping mapping : mappings) { - dsbe.updateMapping(mapping); - } - } + @VisibleForTesting + void onXtrRequestMapping(XtrRequestMapping notification) { + LOG.debug("Received XtrRequestMapping notification, ignoring"); } - private class MapRequestNotificationHandler implements NotificationListener { + @VisibleForTesting + void onXtrReplyMapping(XtrReplyMapping notification) { + LOG.debug("Received XtrReplyMapping notification, ignoring"); + } - @Override - public void onNotification(RequestMapping mapRequestNotification) { - MapReply mapReply = handleMapRequest(mapRequestNotification.getMapRequest()); - if (mapReply != null) { - SendMapReplyInputBuilder smrib = new SendMapReplyInputBuilder(); - smrib.setMapReply((new MapReplyBuilder(mapReply).build())); - smrib.setTransportAddress(mapRequestNotification.getTransportAddress()); - getLispSB().sendMapReply(smrib.build()); - } else { - LOG.warn("got null map reply"); - } + @VisibleForTesting + void onMappingKeepAlive(MappingKeepAlive notification) { + final MapRegisterCacheMetadata cacheMetadata = notification.getMapRegisterCacheMetadata(); + for (EidLispAddress eidLispAddress : cacheMetadata.nonnullEidLispAddress().values()) { + final Eid eid = eidLispAddress.getEid(); + final XtrId xtrId = cacheMetadata.getXtrId(); + final Long timestamp = cacheMetadata.getTimestamp(); + LOG.debug("Update map registration for eid {} with timestamp {}", LispAddressStringifier.getString(eid), + timestamp); + mapService.refreshMappingRegistration(eid, xtrId, timestamp); } } - private LfmControlPlaneService getLispSB() { - if (lispSB == null) { - lispSB = session.getRpcService(LfmControlPlaneService.class); - } + private OdlLispSbService getLispSB() { return lispSB; } + @Override public void handleMapReply(MapReply reply) { tlsMapReply.set(reply); } - public void handleMapNotify(MapNotify notify) { - tlsMapNotify.set(notify); + @Override + public void handleMapNotify(MapNotify notify, List rlocs) { + tlsMapNotify.set(new MutablePair<>(notify, rlocs)); } - public void handleSMR(MapRequest smr, LispAddressContainer subscriber) { - LOG.debug("Sending SMR to " + subscriber.toString()); + @Override + public void handleSMR(MapRequest smrMapRequest, Rloc subscriber) { + if (LOG.isDebugEnabled()) { + LOG.debug("Sending SMR Map-Request to {} with Source-EID {} and EID Record {} (reversed)", + LispAddressStringifier.getString(subscriber), + LispAddressStringifier.getString(smrMapRequest.getSourceEid().getEid()), + LispAddressStringifier.getString(smrMapRequest.getEidItem().get(0).getEid())); + } SendMapRequestInputBuilder smrib = new SendMapRequestInputBuilder(); - smrib.setMapRequest(new MapRequestBuilder(smr).build()); - smrib.setTransportAddress(LispNotificationHelper.getTransportAddressFromContainer(subscriber)); + smrib.setMapRequest(new MapRequestBuilder(smrMapRequest).build()); + smrib.setTransportAddress(LispNotificationHelper.getTransportAddressFromRloc(subscriber)); getLispSB().sendMapRequest(smrib.build()); } @Override public void handleNonProxyMapRequest(MapRequest mapRequest, TransportAddress transportAddress) { - tlsMapRequest.set(new MutablePair(mapRequest, transportAddress)); + tlsMapRequest.set(new MutablePair<>(mapRequest, transportAddress)); + } + + private void destroy() { + LOG.info("LISP (RFC6830) Mapping Service is destroyed!"); + mapResolver = null; + if (mapServer != null) { + mapServer.close(); + mapServer = null; + } + } + + @Deactivate + @PreDestroy + @Override + public void close() throws Exception { + destroy(); + cssRegistration.close(); + clusterSingletonService.close(); + rpcRegistration.close(); + listenerRegistration.close(); } @Override - public void clean() { - lispDao.removeAll(); + public void instantiateServiceInstance() { + mapService.setIsMaster(true); } @Override - public boolean shouldOverwrite() { - return mapServer.shouldOverwrite(); + public ListenableFuture closeServiceInstance() { + if (mapService != null) { + mapService.setIsMaster(false); + } + return Futures.immediateFuture(null); } @Override - public void setOverwrite(boolean overwrite) { - mapServer.setOverwrite(overwrite); + public ServiceGroupIdentifier getIdentifier() { + return SERVICE_GROUP_IDENTIFIER; } }