Bump versions by x.(y+1).z
[lispflowmapping.git] / mappingservice / implementation / src / main / java / org / opendaylight / lispflowmapping / implementation / LispMappingService.java
1 /*
2  * Copyright (c) 2014 Contextream, Inc. and others.  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
9 package org.opendaylight.lispflowmapping.implementation;
10
11 import java.net.InetAddress;
12 import java.net.UnknownHostException;
13
14 import org.eclipse.osgi.framework.console.CommandInterpreter;
15 import org.eclipse.osgi.framework.console.CommandProvider;
16 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
17 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
18 import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer;
19 import org.opendaylight.controller.sal.binding.api.NotificationListener;
20 import org.opendaylight.controller.sal.binding.api.NotificationService;
21 import org.opendaylight.lispflowmapping.implementation.dao.InMemoryDAO;
22 import org.opendaylight.lispflowmapping.implementation.dao.MappingServiceKey;
23 import org.opendaylight.lispflowmapping.implementation.dao.MappingServiceNoMaskKey;
24 import org.opendaylight.lispflowmapping.implementation.lisp.MapResolver;
25 import org.opendaylight.lispflowmapping.implementation.lisp.MapServer;
26 import org.opendaylight.lispflowmapping.implementation.util.LispAFIConvertor;
27 import org.opendaylight.lispflowmapping.implementation.util.LispNotificationHelper;
28 import org.opendaylight.lispflowmapping.interfaces.dao.ILispDAO;
29 import org.opendaylight.lispflowmapping.interfaces.dao.ILispTypeConverter;
30 import org.opendaylight.lispflowmapping.interfaces.dao.IQueryAll;
31 import org.opendaylight.lispflowmapping.interfaces.dao.IRowVisitor;
32 import org.opendaylight.lispflowmapping.interfaces.lisp.IFlowMapping;
33 import org.opendaylight.lispflowmapping.interfaces.lisp.IMapNotifyHandler;
34 import org.opendaylight.lispflowmapping.interfaces.lisp.IMapReplyHandler;
35 import org.opendaylight.lispflowmapping.interfaces.lisp.IMapResolverAsync;
36 import org.opendaylight.lispflowmapping.interfaces.lisp.IMapServerAsync;
37 import org.opendaylight.lispflowmapping.type.sbplugin.ILispSouthboundPlugin;
38 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.AddMapping;
39 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.MapNotify;
40 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.MapRegister;
41 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.MapReply;
42 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.MapRequest;
43 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.RequestMapping;
44 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.lispaddress.LispAddressContainer;
45 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.lispaddress.LispAddressContainerBuilder;
46 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.lispaddress.lispaddresscontainer.Address;
47 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.lispaddress.lispaddresscontainer.address.Ipv4Builder;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
50 import org.osgi.framework.BundleContext;
51 import org.osgi.framework.FrameworkUtil;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54
55 import com.google.common.net.InetAddresses;
56
57 public class LispMappingService implements CommandProvider, IFlowMapping, BindingAwareConsumer, //
58         IMapReplyHandler, IMapNotifyHandler {
59     protected static final Logger logger = LoggerFactory.getLogger(LispMappingService.class);
60
61     private ILispDAO lispDao = null;
62     private IMapResolverAsync mapResolver;
63     private IMapServerAsync mapServer;
64     private volatile boolean shouldIterateMask;
65     private volatile boolean shouldAuthenticate;
66     private ThreadLocal<MapReply> tlsMapReply = new ThreadLocal<MapReply>();
67     private ThreadLocal<MapNotify> tlsMapNotify = new ThreadLocal<MapNotify>();
68
69     private ILispSouthboundPlugin lispSB = null;
70
71     private ConsumerContext session;
72
73     public static void main(String[] args) throws Exception {
74         LispMappingService serv = new LispMappingService();
75         serv.setLispDao(new InMemoryDAO());
76         serv.init();
77     }
78
79     class LispIpv4AddressInMemoryConverter implements ILispTypeConverter<Ipv4Address, Integer> {
80     }
81
82     class LispIpv6AddressInMemoryConverter implements ILispTypeConverter<Ipv6Address, Integer> {
83     }
84
85     class MappingServiceKeyConvertor implements ILispTypeConverter<MappingServiceKey, Integer> {
86     }
87
88     class MappingServiceNoMaskKeyConvertor implements ILispTypeConverter<MappingServiceNoMaskKey, Integer> {
89     }
90
91     void setBindingAwareBroker(BindingAwareBroker bindingAwareBroker) {
92         logger.trace("BindingAwareBroker set!");
93         BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
94         bindingAwareBroker.registerConsumer(this, bundleContext);
95     }
96
97     void unsetBindingAwareBroker(BindingAwareBroker bindingAwareBroker) {
98         logger.debug("BindingAwareBroker was unset in LispMappingService");
99     }
100
101     public void basicInit(ILispDAO dao) {
102         lispDao = dao;
103         mapResolver = new MapResolver(dao);
104         mapServer = new MapServer(dao);
105     }
106
107     void setLispDao(ILispDAO dao) {
108         logger.trace("LispDAO set in LispMappingService");
109         basicInit(dao);
110         logger.trace("Registering LispIpv4Address");
111         lispDao.register(LispIpv4AddressInMemoryConverter.class);
112         logger.trace("Registering LispIpv6Address");
113         lispDao.register(LispIpv6AddressInMemoryConverter.class);
114         logger.trace("Registering MappingServiceKey");
115         lispDao.register(MappingServiceKeyConvertor.class);
116         logger.trace("Registering MappingServiceNoMaskKey");
117         lispDao.register(MappingServiceNoMaskKeyConvertor.class);
118     }
119
120     void unsetLispDao(ILispDAO dao) {
121         logger.trace("LispDAO was unset in LispMappingService");
122         mapServer = null;
123         mapResolver = null;
124         lispDao = null;
125     }
126
127     public void init() {
128         try {
129             registerWithOSGIConsole();
130             logger.info("LISP (RFC6830) Mapping Service init finished");
131         } catch (Throwable t) {
132             logger.error(t.getStackTrace().toString());
133         }
134     }
135
136     private void registerWithOSGIConsole() {
137         BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
138         bundleContext.registerService(CommandProvider.class.getName(), this, null);
139     }
140
141     public void destroy() {
142         logger.info("LISP (RFC6830) Mapping Service is destroyed!");
143         mapResolver = null;
144         mapServer = null;
145     }
146
147     public void _removeEid(final CommandInterpreter ci) {
148         lispDao.remove(LispAFIConvertor.asIPAfiAddress(ci.nextArgument()));
149     }
150
151     public void _dumpAll(final CommandInterpreter ci) {
152         ci.println("EID\tRLOCs");
153         if (lispDao instanceof IQueryAll) {
154             ((IQueryAll) lispDao).getAll(new IRowVisitor() {
155                 String lastKey = "";
156
157                 public void visitRow(Class<?> keyType, Object keyId, String valueKey, Object value) {
158                     String key = keyType.getSimpleName() + "#" + keyId;
159                     if (!lastKey.equals(key)) {
160                         ci.println();
161                         ci.print(key + "\t");
162                     }
163                     ci.print(valueKey + "=" + value + "\t");
164                     lastKey = key;
165                 }
166             });
167             ci.println();
168         } else {
169             ci.println("Not implemented by this DAO");
170         }
171         return;
172     }
173
174     public void _addDefaultPassword(final CommandInterpreter ci) {
175         LispAddressContainerBuilder builder = new LispAddressContainerBuilder();
176         builder.setAddress((Address) (new Ipv4Builder().setIpv4Address(new Ipv4Address("0.0.0.0")).build()));
177         addAuthenticationKey(builder.build(), 0, "password");
178     }
179
180     public String getHelp() {
181         StringBuffer help = new StringBuffer();
182         help.append("---LISP Mapping Service---\n");
183         help.append("\t dumpAll        - Dump all current EID -> RLOC mapping\n");
184         help.append("\t removeEid      - Remove a single LispIPv4Address Eid\n");
185         return help.toString();
186     }
187
188     public MapReply handleMapRequest(MapRequest request) {
189         tlsMapReply.set(null);
190         mapResolver.handleMapRequest(request, this);
191         // After this invocation we assume that the thread local is filled with
192         // the reply
193         return tlsMapReply.get();
194
195     }
196
197     public MapNotify handleMapRegister(MapRegister mapRegister) {
198         tlsMapNotify.set(null);
199         mapServer.handleMapRegister(mapRegister, this);
200         // After this invocation we assume that the thread local is filled with
201         // the reply
202         return tlsMapNotify.get();
203     }
204
205     public String getAuthenticationKey(LispAddressContainer address, int maskLen) {
206         return mapServer.getAuthenticationKey(address, maskLen);
207     }
208
209     public boolean removeAuthenticationKey(LispAddressContainer address, int maskLen) {
210         return mapServer.removeAuthenticationKey(address, maskLen);
211     }
212
213     public boolean addAuthenticationKey(LispAddressContainer address, int maskLen, String key) {
214         return mapServer.addAuthenticationKey(address, maskLen, key);
215     }
216
217     public boolean shouldIterateMask() {
218         return this.shouldIterateMask;
219     }
220
221     public void setShouldIterateMask(boolean shouldIterateMask) {
222         this.shouldIterateMask = shouldIterateMask;
223         this.mapResolver.setShouldIterateMask(shouldIterateMask);
224         this.mapServer.setShouldIterateMask(shouldIterateMask);
225     }
226
227     public void setShouldAuthenticate(boolean shouldAuthenticate) {
228         this.shouldAuthenticate = shouldAuthenticate;
229         this.mapResolver.setShouldAuthenticate(shouldAuthenticate);
230         this.mapServer.setShouldAuthenticate(shouldAuthenticate);
231     }
232
233     public boolean shouldAuthenticate() {
234         return shouldAuthenticate;
235     }
236
237     public void onSessionInitialized(ConsumerContext session) {
238         logger.info("Lisp Consumer session initialized!");
239         NotificationService notificationService = session.getSALService(NotificationService.class);
240         // notificationService.registerNotificationListener(LispNotification.class,
241         // this);
242         notificationService.registerNotificationListener(AddMapping.class, new MapRegisterNotificationHandler());
243         notificationService.registerNotificationListener(RequestMapping.class, new MapRequestNotificationHandler());
244         this.session = session;
245     }
246
247     private class MapRegisterNotificationHandler implements NotificationListener<AddMapping> {
248
249         @Override
250         public void onNotification(AddMapping mapRegisterNotification) {
251             MapNotify mapNotify = handleMapRegister(mapRegisterNotification.getMapRegister());
252             getLispSB().handleMapNotify(mapNotify,
253                     LispNotificationHelper.getInetAddressFromIpAddress(mapRegisterNotification.getTransportAddress().getIpAddress()));
254
255         }
256     }
257
258     private class MapRequestNotificationHandler implements NotificationListener<RequestMapping> {
259
260         @Override
261         public void onNotification(RequestMapping mapRequestNotification) {
262             MapReply mapReply = handleMapRequest(mapRequestNotification.getMapRequest());
263             getLispSB().handleMapReply(mapReply,
264                     LispNotificationHelper.getInetAddressFromIpAddress(mapRequestNotification.getTransportAddress().getIpAddress()));
265         }
266
267     }
268
269     private ILispSouthboundPlugin getLispSB() {
270         if (lispSB == null) {
271             lispSB = session.getRpcService(ILispSouthboundPlugin.class);
272         }
273         return lispSB;
274     }
275
276     public void handleMapReply(MapReply reply) {
277         tlsMapReply.set(reply);
278     }
279
280     public void handleMapNotify(MapNotify notify) {
281         tlsMapNotify.set(notify);
282     }
283 }