4ec0dbae529e15a3ec6f3b293fc88606e6f2e2b0
[lispflowmapping.git] / mappingservice / implementation / src / main / java / org / opendaylight / lispflowmapping / implementation / lisp / AbstractLispComponent.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 package org.opendaylight.lispflowmapping.implementation.lisp;
9
10 import java.util.HashSet;
11
12 import org.opendaylight.lispflowmapping.implementation.dao.HashMapDb;
13 import org.opendaylight.lispflowmapping.implementation.dao.MappingServiceKeyUtil;
14 import org.opendaylight.lispflowmapping.implementation.util.LispAFIConvertor;
15 import org.opendaylight.lispflowmapping.implementation.util.MaskUtil;
16 import org.opendaylight.lispflowmapping.interfaces.dao.ILispDAO;
17 import org.opendaylight.lispflowmapping.interfaces.dao.IMappingServiceKey;
18 import org.opendaylight.lispflowmapping.interfaces.dao.MappingEntry;
19 import org.opendaylight.lispflowmapping.interfaces.dao.MappingServiceSubscriberRLOC;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.LispAFIAddress;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.LispAddressContainer;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.lispaddresscontainer.address.LcafSourceDest;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25
26 public abstract class AbstractLispComponent {
27
28     public static final String PASSWORD_SUBKEY = "password";
29     public static final String ADDRESS_SUBKEY = "address";
30     public static final String SUBSCRIBERS_SUBKEY = "subscribers";
31     public static final String LCAF_SRCDST_SUBKEY = "lcaf_srcdst";
32     public static final Logger LOG = LoggerFactory.getLogger(AbstractLispComponent.class);
33
34     protected ILispDAO dao;
35     protected volatile boolean iterateMask;
36     protected volatile boolean authenticate;
37
38     public AbstractLispComponent(ILispDAO dao, boolean authenticate, boolean iterateMask) {
39         this.dao = dao;
40         this.iterateMask = iterateMask;
41         this.authenticate = authenticate;
42     }
43
44     public boolean shouldIterateMask() {
45         return iterateMask;
46     }
47
48     public void setShouldIterateMask(boolean shouldIterateMask) {
49         this.iterateMask = shouldIterateMask;
50     }
51
52     public boolean shouldAuthenticate() {
53         return authenticate;
54     }
55
56     public void setShouldAuthenticate(boolean shouldAuthenticate) {
57         this.authenticate = shouldAuthenticate;
58     }
59
60     protected String getPassword(LispAddressContainer prefix, int maskLength) {
61         if (MaskUtil.isMaskable(LispAFIConvertor.toAFI(prefix))) {
62             return getPasswordForMaskable(prefix, maskLength, dao);
63         } else if (prefix.getAddress() instanceof LcafSourceDest) {
64             ILispDAO srcDstDao = getSrcDstInnerDao(prefix, maskLength);
65             if (srcDstDao != null) {
66                 return getPasswordForMaskable(LispAFIConvertor.toContainer(getSrcForLcafSrcDst(prefix)),
67                         getSrcMaskForLcafSrcDst(prefix), srcDstDao);
68             }
69             return null;
70         } else {
71             IMappingServiceKey key = MappingServiceKeyUtil.generateMappingServiceKey(prefix, maskLength);
72             Object password = dao.getSpecific(key, PASSWORD_SUBKEY);
73             if (password != null && password instanceof String) {
74                 return (String) password;
75             } else {
76                 LOG.warn("Failed to find password!");
77                 return null;
78             }
79         }
80     }
81
82     private String getPasswordForMaskable(LispAddressContainer prefix, int maskLength, ILispDAO db) {
83         while (maskLength >= 0) {
84             IMappingServiceKey key = MappingServiceKeyUtil.generateMappingServiceKey(prefix, maskLength);
85             Object password = db.getSpecific(key, PASSWORD_SUBKEY);
86             if (password != null && password instanceof String) {
87                 return (String) password;
88             } else if (shouldIterateMask()) {
89                 maskLength -= 1;
90             } else {
91                 LOG.warn("Failed to find password!");
92                 return null;
93             }
94         }
95         return null;
96     }
97
98     @SuppressWarnings("unchecked")
99     private HashSet<MappingServiceSubscriberRLOC> getSubscribers(LispAddressContainer prefix, int maskLength,
100             ILispDAO dao) {
101         Object subscribers;
102
103         IMappingServiceKey key = MappingServiceKeyUtil.generateMappingServiceKey(prefix, maskLength);
104         subscribers = dao.getSpecific(key, SUBSCRIBERS_SUBKEY);
105
106         if (subscribers != null && subscribers instanceof HashSet<?>) {
107             return (HashSet<MappingServiceSubscriberRLOC>) subscribers;
108         }
109         return null;
110     }
111
112     protected HashSet<MappingServiceSubscriberRLOC> getSubscribers(LispAddressContainer prefix, int maskLength) {
113         // For SrcDst we merge the subscriber set from the parent DAO with the source specific DAO
114         if (prefix.getAddress() instanceof LcafSourceDest) {
115             HashSet<MappingServiceSubscriberRLOC> resultSet = new HashSet<MappingServiceSubscriberRLOC>();
116             boolean haveResult = false;
117
118             LispAddressContainer srcAddr = LispAFIConvertor.toContainer(getSrcForLcafSrcDst(prefix));
119             short srcMask = getSrcMaskForLcafSrcDst(prefix);
120             ILispDAO srcDstDao = getSrcDstInnerDao(prefix, maskLength);
121             HashSet<MappingServiceSubscriberRLOC> srcDstSubscribers = getSubscribers(srcAddr, srcMask, srcDstDao);
122             if (srcDstSubscribers != null) {
123                 resultSet.addAll(srcDstSubscribers);
124                 haveResult = true;
125             }
126
127             LispAddressContainer dstAddr = LispAFIConvertor.toContainer(getDstForLcafSrcDst(prefix));
128             short dstMask = getDstMaskForLcafSrcDst(prefix);
129             HashSet<MappingServiceSubscriberRLOC> subscribers = getSubscribers(dstAddr, dstMask, dao);
130             if (subscribers != null) {
131                 resultSet.addAll(subscribers);
132                 haveResult = true;
133             }
134
135             if (haveResult) {
136                 return resultSet;
137             }
138         } else {
139             return getSubscribers(prefix, maskLength, dao);
140         }
141         return null;
142     }
143
144     protected static LispAFIAddress getSrcForLcafSrcDst(LispAddressContainer container) {
145         return LispAFIConvertor.toAFIfromPrimitive(((LcafSourceDest) container.getAddress()).getLcafSourceDestAddr().
146                 getSrcAddress().getPrimitiveAddress());
147     }
148
149     protected static LispAFIAddress getDstForLcafSrcDst(LispAddressContainer container) {
150         return LispAFIConvertor.toAFIfromPrimitive(((LcafSourceDest) container.getAddress()).getLcafSourceDestAddr().
151                 getDstAddress().getPrimitiveAddress());
152     }
153
154     protected static short getSrcMaskForLcafSrcDst(LispAddressContainer container) {
155         return ((LcafSourceDest) container.getAddress()).getLcafSourceDestAddr().getSrcMaskLength();
156     }
157
158     protected static short getDstMaskForLcafSrcDst(LispAddressContainer container) {
159         return ((LcafSourceDest) container.getAddress()).getLcafSourceDestAddr().getDstMaskLength();
160     }
161
162     // SrcDst LCAFs are stored in a 2-tier DAO with dst having priority over src. This method returns the DAO
163     // associated to a dst or creates it if it doesn't exist.
164     protected ILispDAO getOrInstantiateSrcDstInnerDao(LispAddressContainer address, int maskLen) {
165         IMappingServiceKey dstKey = MappingServiceKeyUtil.generateMappingServiceKey(getDstForLcafSrcDst(address),
166                 getDstMaskForLcafSrcDst(address));
167         ILispDAO srcDstDao = (ILispDAO) dao.getSpecific(dstKey, LCAF_SRCDST_SUBKEY);
168         if (srcDstDao == null) {
169             srcDstDao = new HashMapDb();
170             dao.put(dstKey, new MappingEntry<>(LCAF_SRCDST_SUBKEY, srcDstDao));
171         }
172         return srcDstDao;
173     }
174
175     // SrcDst LCAFs are stored in a 2-tier DAO with dst having priority over src. This method returns the DAO
176     // associated to a dst or null if it doesn't exist.
177     protected ILispDAO getSrcDstInnerDao(LispAddressContainer address, int maskLen) {
178         IMappingServiceKey dstKey = MappingServiceKeyUtil.generateMappingServiceKey(getDstForLcafSrcDst(address),
179                 getDstMaskForLcafSrcDst(address));
180         return (ILispDAO) dao.getSpecific(dstKey, LCAF_SRCDST_SUBKEY);
181     }
182 }