Merge branch 'release-1.0.X' into develop
[lispflowmapping.git] / mappingservice / implementation / src / main / java / org / opendaylight / lispflowmapping / implementation / LispMappingService.java
index ba4ce9110f3271a44a34cd8c9ce9e1993d78f625..99d2f17d8d4a1d2f798a52ec85b664b8b1e79cf0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013 Contextream, Inc. and others.  All rights reserved.
+ * Copyright (c) 2014 Contextream, Inc. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -8,38 +8,70 @@
 
 package org.opendaylight.lispflowmapping.implementation;
 
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+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.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
+import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer;
+import org.opendaylight.controller.sal.binding.api.NotificationListener;
+import org.opendaylight.controller.sal.binding.api.NotificationService;
 import org.opendaylight.lispflowmapping.implementation.dao.InMemoryDAO;
+import org.opendaylight.lispflowmapping.implementation.dao.MappingServiceKey;
+import org.opendaylight.lispflowmapping.implementation.dao.MappingServiceNoMaskKey;
 import org.opendaylight.lispflowmapping.implementation.lisp.MapResolver;
 import org.opendaylight.lispflowmapping.implementation.lisp.MapServer;
+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.IQueryAll;
 import org.opendaylight.lispflowmapping.interfaces.dao.IRowVisitor;
-import org.opendaylight.lispflowmapping.interfaces.dao.MappingServiceKey;
-import org.opendaylight.lispflowmapping.interfaces.dao.MappingServiceNoMaskKey;
 import org.opendaylight.lispflowmapping.interfaces.lisp.IFlowMapping;
-import org.opendaylight.lispflowmapping.interfaces.lisp.IMapResolver;
-import org.opendaylight.lispflowmapping.interfaces.lisp.IMapServer;
-import org.opendaylight.lispflowmapping.type.lisp.MapNotify;
-import org.opendaylight.lispflowmapping.type.lisp.MapRegister;
-import org.opendaylight.lispflowmapping.type.lisp.MapReply;
-import org.opendaylight.lispflowmapping.type.lisp.MapRequest;
-import org.opendaylight.lispflowmapping.type.lisp.address.LispAddress;
-import org.opendaylight.lispflowmapping.type.lisp.address.LispIpv4Address;
-import org.opendaylight.lispflowmapping.type.lisp.address.LispIpv6Address;
+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.lispflowmapping.type.sbplugin.ILispSouthboundPlugin;
+import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.AddMapping;
+import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.MapNotify;
+import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.MapRegister;
+import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.MapReply;
+import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.MapRequest;
+import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.RequestMapping;
+import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.lispaddress.LispAddressContainer;
+import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.lispaddress.LispAddressContainerBuilder;
+import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.lispaddress.lispaddresscontainer.Address;
+import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.lispaddress.lispaddresscontainer.address.Ipv4Builder;
+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.osgi.framework.BundleContext;
 import org.osgi.framework.FrameworkUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class LispMappingService implements CommandProvider, IFlowMapping {
+import com.google.common.net.InetAddresses;
+
+public class LispMappingService implements CommandProvider, IFlowMapping, BindingAwareConsumer, //
+        IMapRequestResultHandler, IMapNotifyHandler {
     protected static final Logger logger = LoggerFactory.getLogger(LispMappingService.class);
 
     private ILispDAO lispDao = null;
-    private IMapResolver mapResolver;
-    private IMapServer mapServer;
+    private IMapResolverAsync mapResolver;
+    private IMapServerAsync mapServer;
+    private volatile boolean shouldIterateMask;
+    private volatile boolean shouldAuthenticate;
+    private ThreadLocal<MapReply> tlsMapReply = new ThreadLocal<MapReply>();
+    private ThreadLocal<MapNotify> tlsMapNotify = new ThreadLocal<MapNotify>();
+    private ThreadLocal<Pair<MapRequest, InetAddress>> tlsMapRequest = new ThreadLocal<Pair<MapRequest, InetAddress>>();
+
+    private ILispSouthboundPlugin lispSB = null;
+
+    private ConsumerContext session;
 
     public static void main(String[] args) throws Exception {
         LispMappingService serv = new LispMappingService();
@@ -47,10 +79,10 @@ public class LispMappingService implements CommandProvider, IFlowMapping {
         serv.init();
     }
 
-    class LispIpv4AddressInMemoryConverter implements ILispTypeConverter<LispIpv4Address, Integer> {
+    class LispIpv4AddressInMemoryConverter implements ILispTypeConverter<Ipv4Address, Integer> {
     }
 
-    class LispIpv6AddressInMemoryConverter implements ILispTypeConverter<LispIpv6Address, Integer> {
+    class LispIpv6AddressInMemoryConverter implements ILispTypeConverter<Ipv6Address, Integer> {
     }
 
     class MappingServiceKeyConvertor implements ILispTypeConverter<MappingServiceKey, Integer> {
@@ -59,31 +91,49 @@ public class LispMappingService implements CommandProvider, IFlowMapping {
     class MappingServiceNoMaskKeyConvertor implements ILispTypeConverter<MappingServiceNoMaskKey, Integer> {
     }
 
-    void setLispDao(ILispDAO dao) {
-        logger.info("LispDAO set in LispMappingService");
+    void setBindingAwareBroker(BindingAwareBroker bindingAwareBroker) {
+        logger.trace("BindingAwareBroker set!");
+        BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
+        bindingAwareBroker.registerConsumer(this, bundleContext);
+    }
+
+    void unsetBindingAwareBroker(BindingAwareBroker bindingAwareBroker) {
+        logger.debug("BindingAwareBroker was unset in LispMappingService");
+    }
+
+    public void basicInit(ILispDAO dao) {
         lispDao = dao;
         mapResolver = new MapResolver(dao);
         mapServer = new MapServer(dao);
-        logger.debug("Registering LispIpv4Address");
+    }
+
+    void setLispDao(ILispDAO dao) {
+        logger.trace("LispDAO set in LispMappingService");
+        basicInit(dao);
+        logger.trace("Registering LispIpv4Address");
         lispDao.register(LispIpv4AddressInMemoryConverter.class);
-        logger.debug("Registering LispIpv6Address");
+        logger.trace("Registering LispIpv6Address");
         lispDao.register(LispIpv6AddressInMemoryConverter.class);
-        logger.debug("Registering MappingServiceKey");
+        logger.trace("Registering MappingServiceKey");
         lispDao.register(MappingServiceKeyConvertor.class);
-        logger.debug("Registering MappingServiceNoMaskKey");
+        logger.trace("Registering MappingServiceNoMaskKey");
         lispDao.register(MappingServiceNoMaskKeyConvertor.class);
     }
 
     void unsetLispDao(ILispDAO dao) {
-        logger.debug("LispDAO was unset in LispMappingService");
+        logger.trace("LispDAO was unset in LispMappingService");
         mapServer = null;
         mapResolver = null;
         lispDao = null;
     }
 
     public void init() {
-        logger.debug("LISP (RFC6830) Mapping Service is initialized!");
-        registerWithOSGIConsole();
+        try {
+            registerWithOSGIConsole();
+            logger.info("LISP (RFC6830) Mapping Service init finished");
+        } catch (Throwable t) {
+            logger.error(t.getStackTrace().toString());
+        }
     }
 
     private void registerWithOSGIConsole() {
@@ -92,13 +142,13 @@ public class LispMappingService implements CommandProvider, IFlowMapping {
     }
 
     public void destroy() {
-        logger.debug("LISP (RFC6830) Mapping Service is destroyed!");
+        logger.info("LISP (RFC6830) Mapping Service is destroyed!");
         mapResolver = null;
         mapServer = null;
     }
 
     public void _removeEid(final CommandInterpreter ci) {
-        lispDao.remove(new LispIpv4Address(ci.nextArgument()));
+        lispDao.remove(LispAFIConvertor.asIPAfiAddress(ci.nextArgument()));
     }
 
     public void _dumpAll(final CommandInterpreter ci) {
@@ -124,6 +174,12 @@ public class LispMappingService implements CommandProvider, IFlowMapping {
         return;
     }
 
+    public void _addDefaultPassword(final CommandInterpreter ci) {
+        LispAddressContainerBuilder builder = new LispAddressContainerBuilder();
+        builder.setAddress((Address) (new Ipv4Builder().setIpv4Address(new Ipv4Address("0.0.0.0")).build()));
+        addAuthenticationKey(builder.build(), 0, "password");
+    }
+
     public String getHelp() {
         StringBuffer help = new StringBuffer();
         help.append("---LISP Mapping Service---\n");
@@ -133,30 +189,110 @@ public class LispMappingService implements CommandProvider, IFlowMapping {
     }
 
     public MapReply handleMapRequest(MapRequest request) {
-        return mapResolver.handleMapRequest(request);
+        tlsMapReply.set(null);
+        tlsMapRequest.set(null);
+        mapResolver.handleMapRequest(request, this);
+        // After this invocation we assume that the thread local is filled with
+        // the reply
+        if (tlsMapRequest.get() != null) {
+            getLispSB().handleMapRequest(tlsMapRequest.get().getLeft(), tlsMapRequest.get().getRight());
+            return null;
+        } else {
+            return tlsMapReply.get();
+        }
+
     }
 
     public MapNotify handleMapRegister(MapRegister mapRegister) {
-        return mapServer.handleMapRegister(mapRegister);
+        tlsMapNotify.set(null);
+        mapServer.handleMapRegister(mapRegister, this);
+        // After this invocation we assume that the thread local is filled with
+        // the reply
+        return tlsMapNotify.get();
     }
 
-    public String getAuthenticationKey(LispAddress address, int maskLen) {
+    public String getAuthenticationKey(LispAddressContainer address, int maskLen) {
         return mapServer.getAuthenticationKey(address, maskLen);
     }
 
-    public boolean removeAuthenticationKey(LispAddress address, int maskLen) {
+    public boolean removeAuthenticationKey(LispAddressContainer address, int maskLen) {
         return mapServer.removeAuthenticationKey(address, maskLen);
     }
 
-    public boolean addAuthenticationKey(LispAddress address, int maskLen, String key) {
+    public boolean addAuthenticationKey(LispAddressContainer address, int maskLen, String key) {
         return mapServer.addAuthenticationKey(address, maskLen, key);
     }
 
-    public boolean iterateMask() {
-        return mapResolver.iterateMask();
+    public boolean shouldIterateMask() {
+        return this.shouldIterateMask;
+    }
+
+    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 void setIterateMask(boolean iterateMask) {
-        this.mapResolver.setIterateMask(iterateMask);
+    public boolean shouldAuthenticate() {
+        return shouldAuthenticate;
     }
+
+    public void onSessionInitialized(ConsumerContext session) {
+        logger.info("Lisp Consumer session initialized!");
+        NotificationService notificationService = session.getSALService(NotificationService.class);
+        // notificationService.registerNotificationListener(LispNotification.class,
+        // this);
+        notificationService.registerNotificationListener(AddMapping.class, new MapRegisterNotificationHandler());
+        notificationService.registerNotificationListener(RequestMapping.class, new MapRequestNotificationHandler());
+        this.session = session;
+    }
+
+    private class MapRegisterNotificationHandler implements NotificationListener<AddMapping> {
+
+        @Override
+        public void onNotification(AddMapping mapRegisterNotification) {
+            MapNotify mapNotify = handleMapRegister(mapRegisterNotification.getMapRegister());
+            getLispSB().handleMapNotify(mapNotify,
+                    LispNotificationHelper.getInetAddressFromIpAddress(mapRegisterNotification.getTransportAddress().getIpAddress()));
+
+        }
+    }
+
+    private class MapRequestNotificationHandler implements NotificationListener<RequestMapping> {
+
+        @Override
+        public void onNotification(RequestMapping mapRequestNotification) {
+            MapReply mapReply = handleMapRequest(mapRequestNotification.getMapRequest());
+            getLispSB().handleMapReply(mapReply,
+                    LispNotificationHelper.getInetAddressFromIpAddress(mapRequestNotification.getTransportAddress().getIpAddress()));
+        }
+
+    }
+
+    private ILispSouthboundPlugin getLispSB() {
+        if (lispSB == null) {
+            lispSB = session.getRpcService(ILispSouthboundPlugin.class);
+        }
+        return lispSB;
+    }
+
+    public void handleMapReply(MapReply reply) {
+        tlsMapReply.set(reply);
+    }
+
+    public void handleMapNotify(MapNotify notify) {
+        tlsMapNotify.set(notify);
+    }
+
+    @Override
+    public void handleNonProxyMapRequest(MapRequest mapRequest, InetAddress targetAddress) {
+        tlsMapRequest.set(new MutablePair<MapRequest, InetAddress>(mapRequest, targetAddress));
+    }
+
 }