Enforce basic checkstyle on mappingservice.*
[lispflowmapping.git] / mappingservice / implementation / src / main / java / org / opendaylight / lispflowmapping / implementation / lisp / MapResolver.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.lisp;
10
11 import java.util.ArrayList;
12 import java.util.HashSet;
13 import java.util.List;
14 import java.util.Map.Entry;
15
16 import org.opendaylight.lispflowmapping.implementation.config.ConfigIni;
17 import org.opendaylight.lispflowmapping.implementation.dao.MappingServiceKeyUtil;
18 import org.opendaylight.lispflowmapping.implementation.util.DAOMappingUtil;
19 import org.opendaylight.lispflowmapping.implementation.util.LispAFIConvertor;
20 import org.opendaylight.lispflowmapping.implementation.util.LispNotificationHelper;
21 import org.opendaylight.lispflowmapping.interfaces.dao.ILispDAO;
22 import org.opendaylight.lispflowmapping.interfaces.dao.IMappingServiceKey;
23 import org.opendaylight.lispflowmapping.interfaces.dao.MappingEntry;
24 import org.opendaylight.lispflowmapping.interfaces.dao.MappingServiceRLOCGroup;
25 import org.opendaylight.lispflowmapping.interfaces.dao.MappingServiceSubscriberRLOC;
26 import org.opendaylight.lispflowmapping.interfaces.lisp.IMapRequestResultHandler;
27 import org.opendaylight.lispflowmapping.interfaces.lisp.IMapResolverAsync;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.EidToLocatorRecord.Action;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.LcafTrafficEngineeringAddress;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.MapRequest;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.eidrecords.EidRecord;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.eidtolocatorrecords.EidToLocatorRecord;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.eidtolocatorrecords.EidToLocatorRecordBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lcaftrafficengineeringaddress.Hops;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.lispaddress.LispAddressContainer;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.locatorrecords.LocatorRecord;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.locatorrecords.LocatorRecordBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.mapreplymessage.MapReplyBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.maprequest.ItrRloc;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42
43 public class MapResolver extends AbstractLispComponent implements IMapResolverAsync {
44
45     private static final int TTL_RLOC_TIMED_OUT = 1;
46     private static final int TTL_NO_RLOC_KNOWN = 15;
47     protected static final Logger LOG = LoggerFactory.getLogger(MapResolver.class);
48
49     private static final ConfigIni configIni = new ConfigIni();
50     private static final String elpPolicy = configIni.getElpPolicy();
51
52     public MapResolver(ILispDAO dao) {
53         this(dao, true, true);
54     }
55
56     public MapResolver(ILispDAO dao, boolean authenticate, boolean iterateMask) {
57         super(dao, authenticate, iterateMask);
58     }
59
60     public void handleMapRequest(MapRequest request, boolean smr, IMapRequestResultHandler callback) {
61         if (dao == null) {
62             LOG.warn("handleMapRequest called while dao is uninitialized");
63             return;
64         }
65         if (request.isPitr()) {
66             if (request.getEidRecord().size() > 0) {
67                 EidRecord eid = request.getEidRecord().get(0);
68                 Object result = DAOMappingUtil.getLocatorsSpecificByEidRecord(eid, dao, ADDRESS_SUBKEY, shouldIterateMask());
69                 if (result != null && result instanceof MappingServiceRLOCGroup) {
70                     MappingServiceRLOCGroup locatorsGroup = (MappingServiceRLOCGroup) result;
71                     if (locatorsGroup != null && locatorsGroup.getRecords().size() > 0) {
72                         callback.handleNonProxyMapRequest(request,
73                                 LispNotificationHelper.getTransportAddressFromContainer(locatorsGroup.getRecords().get(0).getLispAddressContainer()));
74                     }
75                 }
76             }
77
78         } else {
79             MapReplyBuilder builder = new MapReplyBuilder();
80             builder.setEchoNonceEnabled(false);
81             builder.setProbe(false);
82             builder.setSecurityEnabled(false);
83             builder.setNonce(request.getNonce());
84             builder.setEidToLocatorRecord(new ArrayList<EidToLocatorRecord>());
85             for (EidRecord eid : request.getEidRecord()) {
86                 EidToLocatorRecordBuilder recordBuilder = new EidToLocatorRecordBuilder();
87                 Entry<IMappingServiceKey, List<MappingServiceRLOCGroup>> mapping = DAOMappingUtil.getMappingForEidRecord(eid, dao);
88                 recordBuilder.setRecordTtl(0);
89                 recordBuilder.setAction(Action.NoAction);
90                 recordBuilder.setAuthoritative(false);
91                 recordBuilder.setMapVersion((short) 0);
92                 recordBuilder.setMaskLength((short) mapping.getKey().getMask());
93                 recordBuilder.setLispAddressContainer(mapping.getKey().getEID());
94                 recordBuilder.setLocatorRecord(new ArrayList<LocatorRecord>());
95                 List<MappingServiceRLOCGroup> locators = mapping.getValue();
96                 if (locators != null && locators.size() > 0) {
97                     List<ItrRloc> itrRlocs = request.getItrRloc();
98                     addLocatorGroups(recordBuilder, locators, itrRlocs);
99                     if (itrRlocs != null && itrRlocs.size() > 0) {
100                         LispAddressContainer itrRloc = itrRlocs.get(0).getLispAddressContainer();
101                         MappingServiceSubscriberRLOC subscriberRloc = new MappingServiceSubscriberRLOC(itrRloc);
102                         HashSet<MappingServiceSubscriberRLOC> subscribers = getSubscribers(mapping.getKey().getEID(), mapping.getKey().getMask());
103                         if (subscribers == null) {
104                             subscribers = new HashSet<MappingServiceSubscriberRLOC>();
105                         } else if (subscribers.contains(subscriberRloc)) {
106                             /*
107                              * If there is an entry already for this
108                              * subscriberRloc, remove it, so that it gets the
109                              * new timestamp
110                              */
111                             subscribers.remove(subscriberRloc);
112                         }
113                         if (smr) {
114                             IMappingServiceKey key = MappingServiceKeyUtil.generateMappingServiceKey(mapping.getKey().getEID(),
115                                     mapping.getKey().getMask());
116                             LOG.trace("Adding new subscriber: " + subscriberRloc.toString());
117                             subscribers.add(subscriberRloc);
118                             dao.put(key, new MappingEntry<HashSet<MappingServiceSubscriberRLOC>>(SUBSCRIBERS_SUBKEY, subscribers));
119                         }
120                     }
121                 } else {
122                     recordBuilder
123                             .setAction(org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.control.plane.rev150314.eidtolocatorrecords.EidToLocatorRecord.Action.NativelyForward);
124                     if (shouldAuthenticate() && getPassword(eid.getLispAddressContainer(), eid.getMask()) != null) {
125                         recordBuilder.setRecordTtl(TTL_RLOC_TIMED_OUT);
126                     } else {
127                         recordBuilder.setRecordTtl(TTL_NO_RLOC_KNOWN);
128
129                     }
130                 }
131                 builder.getEidToLocatorRecord().add(recordBuilder.build());
132             }
133
134             callback.handleMapReply(builder.build());
135         }
136     }
137
138     private void addLocatorGroups(EidToLocatorRecordBuilder recordBuilder, List<MappingServiceRLOCGroup> rlocs, List<ItrRloc> itrRlocs) {
139         for (MappingServiceRLOCGroup rloc : rlocs) {
140             addLocators(recordBuilder, rloc, itrRlocs);
141             recordBuilder.setRecordTtl(rloc.getTtl());
142         }
143     }
144
145     private void addLocators(EidToLocatorRecordBuilder recordBuilder, MappingServiceRLOCGroup locatorObject, List<ItrRloc> itrRlocs) {
146         if (locatorObject == null) {
147             return;
148         }
149
150         recordBuilder.setAction(locatorObject.getAction());
151         recordBuilder.setAuthoritative(locatorObject.isAuthoritative());
152         recordBuilder.setRecordTtl(locatorObject.getTtl());
153
154         try {
155             for (LocatorRecord record : locatorObject.getRecords()) {
156                 LispAddressContainer container = record.getLispAddressContainer();
157
158                 // For non-ELP RLOCs, or when ELP policy is default, just add the locator and be done
159                 if ((!(container.getAddress() instanceof LcafTrafficEngineeringAddress)) || elpPolicy.equalsIgnoreCase("default")) {
160                     recordBuilder.getLocatorRecord().add(
161                             new LocatorRecordBuilder().setLocalLocator(record.isLocalLocator()).setRlocProbed(record.isRlocProbed())
162                                     .setWeight(record.getWeight()).setPriority(record.getPriority()).setMulticastWeight(record.getMulticastWeight())
163                                     .setMulticastPriority(record.getMulticastPriority()).setRouted(true)
164                                     .setLispAddressContainer(container).build());
165                     continue;
166                 }
167
168                 LispAddressContainer nextHop = getNextELPHop((LcafTrafficEngineeringAddress) container.getAddress(), itrRlocs);
169                 if (nextHop != null) {
170                     java.lang.Short priority = record.getPriority();
171                     if (elpPolicy.equalsIgnoreCase("both")) {
172                         recordBuilder.getLocatorRecord().add(
173                                 new LocatorRecordBuilder().setLocalLocator(record.isLocalLocator()).setRlocProbed(record.isRlocProbed())
174                                         .setWeight(record.getWeight()).setPriority(record.getPriority()).setMulticastWeight(record.getMulticastWeight())
175                                         .setMulticastPriority(record.getMulticastPriority()).setRouted(true)
176                                         .setLispAddressContainer(container).build());
177                         // Make the priority of the added simple locator lower so that ELP is used by default if
178                         // the xTR understands ELP.  Exclude 255, since that means don't use for unicast forwarding
179                         // XXX Complex cases like several ELPs with different priorities are not handled
180                         if (priority != 254 || priority !=255) {
181                             priority++;
182                         }
183                     }
184                     // Build and add the simple RLOC
185                     recordBuilder.getLocatorRecord().add(
186                             new LocatorRecordBuilder().setLocalLocator(record.isLocalLocator()).setRlocProbed(record.isRlocProbed())
187                             .setWeight(record.getWeight()).setPriority(priority).setMulticastWeight(record.getMulticastWeight())
188                             .setMulticastPriority(record.getMulticastPriority()).setRouted(true)
189                             .setLispAddressContainer(nextHop).build());
190                 }
191             }
192         } catch (ClassCastException cce) {
193         }
194     }
195
196     private LispAddressContainer getNextELPHop(LcafTrafficEngineeringAddress elp, List<ItrRloc> itrRlocs) {
197         LispAddressContainer nextHop = null;
198         List<Hops> hops = elp.getHops();
199
200         if (hops != null && hops.size() > 0) {
201             // By default we return the first hop
202             nextHop = LispAFIConvertor.toContainer(LispAFIConvertor.toAFIfromPrimitive(hops.get(0).getHop().getPrimitiveAddress()));
203             for (Hops hop : hops) {
204                 LispAddressContainer hopContainer = LispAFIConvertor.toContainer(LispAFIConvertor.toAFIfromPrimitive(hop.getHop().getPrimitiveAddress()));
205                 for (ItrRloc itrRloc : itrRlocs) {
206                     if (itrRloc.getLispAddressContainer().equals(hopContainer)) {
207                         int i = hops.indexOf(hop);
208                         if (i < hops.size() - 1) {
209                             nextHop = LispAFIConvertor.toContainer(LispAFIConvertor.toAFIfromPrimitive(hops.get(i+1).getHop().getPrimitiveAddress()));
210                             return nextHop;
211                         }
212                     }
213                 }
214             }
215         }
216
217         return nextHop;
218     }
219
220 }