Merge "L2 Gw create changes related to ITM Tunnels creation in neutronvpn module"
[vpnservice.git] / interfacemgr / interfacemgr-impl / src / main / java / org / opendaylight / vpnservice / interfacemgr / commons / AlivenessMonitorUtils.java
1 /*
2  * Copyright (c) 2015 - 2016 Ericsson India Global Services Pvt Ltd. 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.vpnservice.interfacemgr.commons;
9
10 import com.google.common.base.Optional;
11 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
12 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
13 import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
14 import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
15 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
16 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.*;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.monitor.params.SourceBuilder;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.monitor.profile.create.input.Profile;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.monitor.profile.create.input.ProfileBuilder;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.monitor.start.input.ConfigBuilder;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.*;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.monitor.id.map.InterfaceMonitorId;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.monitor.id.map.InterfaceMonitorIdBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.monitor.id.map.InterfaceMonitorIdKey;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.monitor.id._interface.map.MonitorIdInterface;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.monitor.id._interface.map.MonitorIdInterfaceBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.monitor.id._interface.map.MonitorIdInterfaceKey;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeVxlan;
31 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
32 import org.opendaylight.yangtools.yang.common.RpcResult;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 import java.util.ArrayList;
37 import java.util.List;
38 import java.util.concurrent.ExecutionException;
39 import java.util.concurrent.Future;
40
41 public class AlivenessMonitorUtils {
42
43     private static final Logger LOG = LoggerFactory.getLogger(AlivenessMonitorUtils.class);
44     private static final long FAILURE_THRESHOLD = 4;
45     private static final long MONITORING_INTERVAL = 10000;
46     private static final long MONITORING_WINDOW = 4;
47
48     public static void startLLDPMonitoring(AlivenessMonitorService alivenessMonitorService, DataBroker dataBroker,
49                                             Interface trunkInterface) {
50         //LLDP monitoring for the trunk interface
51         String trunkInterfaceName = trunkInterface.getName();
52         IfTunnel ifTunnel = trunkInterface.getAugmentation(IfTunnel.class);
53         if(ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeVxlan.class) && ifTunnel.isInternal()) {
54         MonitorStartInput lldpMonitorInput = new MonitorStartInputBuilder().setConfig(new ConfigBuilder()
55              .setSource(new SourceBuilder().setEndpointType(getInterfaceForMonitoring(trunkInterfaceName,
56                      ifTunnel.getTunnelSource())).build())
57              .setMode(MonitoringMode.OneOne)
58              .setProfileId(allocateProfile(alivenessMonitorService, FAILURE_THRESHOLD, ifTunnel.getMonitorInterval(), MONITORING_WINDOW,
59                      EtherTypes.Lldp)).build()).build();
60             try {
61                 Future<RpcResult<MonitorStartOutput>> result = alivenessMonitorService.monitorStart(lldpMonitorInput);
62                 RpcResult<MonitorStartOutput> rpcResult = result.get();
63                 long monitorId;
64                 if (rpcResult.isSuccessful()) {
65                     monitorId = rpcResult.getResult().getMonitorId();
66                     createOrUpdateInterfaceMonitorIdMap(dataBroker, trunkInterfaceName, monitorId);
67                     createOrUpdateMonitorIdInterfaceMap(dataBroker, trunkInterfaceName, monitorId);
68                     LOG.trace("Started LLDP monitoring with id {}", monitorId);
69                 } else {
70                     LOG.warn("RPC Call to start monitoring returned with Errors {}", rpcResult.getErrors());
71                 }
72             } catch (InterruptedException | ExecutionException e) {
73                 LOG.warn("Exception when starting monitoring", e);
74             }
75         }
76     }
77
78     public static void stopLLDPMonitoring(AlivenessMonitorService alivenessMonitorService, DataBroker dataBroker,
79                                           Interface trunkInterface) {
80         IfTunnel ifTunnel = trunkInterface.getAugmentation(IfTunnel.class);
81         if(!(ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeVxlan.class)&& ifTunnel.isInternal())){
82             return;
83         }
84         List<Long> monitorIds = getMonitorIdForInterface(dataBroker, trunkInterface.getName());
85         if (monitorIds == null) {
86             LOG.error("Monitor Id doesn't exist for Interface {}", trunkInterface);
87             return;
88         }
89         for (Long monitorId : monitorIds) {
90             String interfaceName = getInterfaceFromMonitorId(dataBroker, monitorId);
91             if (interfaceName != null) {
92                 MonitorStopInput input = new MonitorStopInputBuilder().setMonitorId(monitorId).build();
93                 alivenessMonitorService.monitorStop(input);
94                 removeMonitorIdInterfaceMap(dataBroker, monitorId);
95                 removeMonitorIdFromInterfaceMonitorIdMap(dataBroker, interfaceName, monitorId);
96                 return;
97             }
98         }
99     }
100
101     public static String getInterfaceFromMonitorId(DataBroker broker, Long monitorId) {
102         InstanceIdentifier<MonitorIdInterface> id = InstanceIdentifier.builder(MonitorIdInterfaceMap.class).child(MonitorIdInterface.class, new MonitorIdInterfaceKey(monitorId)).build();
103         Optional<MonitorIdInterface> interfaceMonitorIdMap = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, id, broker);
104         if(interfaceMonitorIdMap.isPresent()) {
105             return interfaceMonitorIdMap.get().getInterfaceName();
106         }
107         return null;
108     }
109
110     private static void removeMonitorIdInterfaceMap(DataBroker broker, long monitorId) {
111         InstanceIdentifier<MonitorIdInterface> id = InstanceIdentifier.builder(MonitorIdInterfaceMap.class).child(MonitorIdInterface.class, new MonitorIdInterfaceKey(monitorId)).build();
112         Optional<MonitorIdInterface> monitorIdInterfaceMap = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, id, broker);
113         if(monitorIdInterfaceMap.isPresent()) {
114             MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, id);
115         }
116     }
117
118     private static void removeMonitorIdFromInterfaceMonitorIdMap(DataBroker broker, String infName, long monitorId) {
119         InstanceIdentifier<InterfaceMonitorId> id = InstanceIdentifier.builder(InterfaceMonitorIdMap.class).child(InterfaceMonitorId.class, new InterfaceMonitorIdKey(infName)).build();
120         Optional<InterfaceMonitorId> interfaceMonitorIdMap = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, id, broker);
121         if(interfaceMonitorIdMap.isPresent()) {
122             InterfaceMonitorId interfaceMonitorIdInstance = interfaceMonitorIdMap.get();
123             List<Long> existingMonitorIds = interfaceMonitorIdInstance.getMonitorId();
124             if (existingMonitorIds != null && existingMonitorIds.contains(monitorId)) {
125                 existingMonitorIds.remove(monitorId);
126                 InterfaceMonitorIdBuilder interfaceMonitorIdBuilder = new InterfaceMonitorIdBuilder();
127                 interfaceMonitorIdInstance = interfaceMonitorIdBuilder.setKey(new InterfaceMonitorIdKey(infName)).setMonitorId(existingMonitorIds).build();
128                 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, id, interfaceMonitorIdInstance);
129             }
130         }
131     }
132
133     private static org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.endpoint.endpoint.type.Interface getInterfaceForMonitoring(String interfaceName, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress ipAddress) {
134         return new org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.endpoint.
135                 endpoint.type.InterfaceBuilder().setInterfaceIp(ipAddress).setInterfaceName(interfaceName).build();
136     }
137
138     public static void handleTunnelMonitorUpdates(AlivenessMonitorService alivenessMonitorService, DataBroker dataBroker,
139                                                           Interface interfaceOld, Interface interfaceNew) {
140         String interfaceName = interfaceNew.getName();
141         IfTunnel ifTunnelNew = interfaceNew.getAugmentation(IfTunnel.class);
142         if(!(ifTunnelNew.getTunnelInterfaceType().isAssignableFrom(TunnelTypeVxlan.class)&&
143                 ifTunnelNew.isInternal())){
144             return;
145         }
146         LOG.debug("handling tunnel monitoring updates for interface {}", interfaceName);
147         // Restart LLDP monitoring only if it's started already
148         List<Long> monitorIds = getMonitorIdForInterface(dataBroker, interfaceName);
149         if (monitorIds != null && monitorIds.size() > 1) {
150                 stopLLDPMonitoring(alivenessMonitorService, dataBroker, interfaceOld);
151                 if(ifTunnelNew.isMonitorEnabled()) {
152                     startLLDPMonitoring(alivenessMonitorService, dataBroker, interfaceNew);
153
154                     // Delete old profile from Aliveness Manager
155                     IfTunnel ifTunnelOld = interfaceOld.getAugmentation(IfTunnel.class);
156                     if(ifTunnelNew.getMonitorInterval() != ifTunnelOld.getMonitorInterval()) {
157                         LOG.debug("deleting older monitor profile for interface {}", interfaceName);
158                         long profileId = allocateProfile(alivenessMonitorService, FAILURE_THRESHOLD, ifTunnelOld.getMonitorInterval(), MONITORING_WINDOW, EtherTypes.Lldp);
159                         MonitorProfileDeleteInput profileDeleteInput = new MonitorProfileDeleteInputBuilder().setProfileId(profileId).build();
160                         alivenessMonitorService.monitorProfileDelete(profileDeleteInput);
161                     }
162                 }
163             }
164     }
165
166
167     public static void createOrUpdateInterfaceMonitorIdMap(DataBroker broker, String infName, long monitorId) {
168         InterfaceMonitorId interfaceMonitorIdInstance;
169         List<Long> existingMonitorIds;
170         InterfaceMonitorIdBuilder interfaceMonitorIdBuilder = new InterfaceMonitorIdBuilder();
171         InstanceIdentifier<InterfaceMonitorId> id = InstanceIdentifier.builder(InterfaceMonitorIdMap.class).child(InterfaceMonitorId.class, new InterfaceMonitorIdKey(infName)).build();
172         Optional<InterfaceMonitorId> interfaceMonitorIdMap = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, id, broker);
173         if (interfaceMonitorIdMap.isPresent()) {
174             interfaceMonitorIdInstance = interfaceMonitorIdMap.get();
175             existingMonitorIds = interfaceMonitorIdInstance.getMonitorId();
176             if (existingMonitorIds == null) {
177                 existingMonitorIds = new ArrayList<>();
178             }
179             if (!existingMonitorIds.contains(monitorId)) {
180                 existingMonitorIds.add(monitorId);
181                 interfaceMonitorIdInstance = interfaceMonitorIdBuilder.setKey(new InterfaceMonitorIdKey(infName)).setMonitorId(existingMonitorIds).build();
182                 MDSALUtil.syncUpdate(broker, LogicalDatastoreType.OPERATIONAL, id, interfaceMonitorIdInstance);
183             }
184         } else {
185             existingMonitorIds = new ArrayList<>();
186             existingMonitorIds.add(monitorId);
187             interfaceMonitorIdInstance = interfaceMonitorIdBuilder.setMonitorId(existingMonitorIds).setKey(new InterfaceMonitorIdKey(infName)).setInterfaceName(infName).build();
188             MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, id, interfaceMonitorIdInstance);
189         }
190     }
191
192     public static void createOrUpdateMonitorIdInterfaceMap(DataBroker broker,String infName,  long monitorId) {
193         MonitorIdInterface monitorIdInterfaceInstance;
194         String existinginterfaceName;
195         MonitorIdInterfaceBuilder monitorIdInterfaceBuilder = new MonitorIdInterfaceBuilder();
196         InstanceIdentifier<MonitorIdInterface> id = InstanceIdentifier.builder(MonitorIdInterfaceMap.class).child(MonitorIdInterface.class, new MonitorIdInterfaceKey(monitorId)).build();
197         Optional<MonitorIdInterface> monitorIdInterfaceMap = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, id, broker);
198         if(monitorIdInterfaceMap.isPresent()) {
199             monitorIdInterfaceInstance = monitorIdInterfaceMap.get();
200             existinginterfaceName = monitorIdInterfaceInstance.getInterfaceName();
201             if(!existinginterfaceName.equals(infName)) {
202                 monitorIdInterfaceInstance = monitorIdInterfaceBuilder.setKey(new MonitorIdInterfaceKey(monitorId)).setInterfaceName(infName).build();
203                 MDSALUtil.syncUpdate(broker, LogicalDatastoreType.OPERATIONAL, id, monitorIdInterfaceInstance);
204             }
205         } else {
206             monitorIdInterfaceInstance = monitorIdInterfaceBuilder.setMonitorId(monitorId).setKey(new MonitorIdInterfaceKey(monitorId)).setInterfaceName(infName).build();
207             MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, id, monitorIdInterfaceInstance);
208         }
209     }
210
211     public static List<Long> getMonitorIdForInterface(DataBroker broker, String infName) {
212         InstanceIdentifier<InterfaceMonitorId> id = InstanceIdentifier.builder(InterfaceMonitorIdMap.class).child(InterfaceMonitorId.class, new InterfaceMonitorIdKey(infName)).build();
213         Optional<InterfaceMonitorId> interfaceMonitorIdMap = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, id, broker);
214         if(interfaceMonitorIdMap.isPresent()) {
215             return interfaceMonitorIdMap.get().getMonitorId();
216         }
217         return null;
218     }
219
220     public static long createMonitorProfile(AlivenessMonitorService alivenessMonitor, MonitorProfileCreateInput monitorProfileCreateInput) {
221         try {
222             Future<RpcResult<MonitorProfileCreateOutput>> result = alivenessMonitor.monitorProfileCreate(monitorProfileCreateInput);
223             RpcResult<MonitorProfileCreateOutput> rpcResult = result.get();
224             if(rpcResult.isSuccessful()) {
225                 return rpcResult.getResult().getProfileId();
226             } else {
227                 LOG.warn("RPC Call to Get Profile Id Id returned with Errors {}", rpcResult.getErrors());
228             }
229         } catch (InterruptedException | ExecutionException e) {
230             LOG.warn("Exception when allocating profile Id",e);
231         }
232         return 0;
233     }
234     public static long allocateProfile(AlivenessMonitorService alivenessMonitor, long FAILURE_THRESHOLD, long MONITORING_INTERVAL,
235                                               long MONITORING_WINDOW, EtherTypes etherTypes) {
236         MonitorProfileCreateInput input = new MonitorProfileCreateInputBuilder().
237                 setProfile(new ProfileBuilder().setFailureThreshold(FAILURE_THRESHOLD)
238                         .setMonitorInterval(MONITORING_INTERVAL).setMonitorWindow(MONITORING_WINDOW).
239                                 setProtocolType(etherTypes).build()).build();
240         return createMonitorProfile(alivenessMonitor, input);
241     }
242
243     public static long allocateDefaultProfile(AlivenessMonitorService alivenessMonitor, EtherTypes etherType ) {
244         MonitorProfileCreateInput input = new MonitorProfileCreateInputBuilder().
245                 setProfile(getDefaultMonitorProfile(etherType)).build();
246         return createMonitorProfile(alivenessMonitor, input);
247     }
248
249     public static Profile getDefaultMonitorProfile(EtherTypes etherType) {
250         ProfileBuilder profileBuilder = new ProfileBuilder();
251         profileBuilder.setProtocolType(etherType);
252         profileBuilder.setFailureThreshold(FAILURE_THRESHOLD)
253                     .setMonitorInterval(MONITORING_INTERVAL).setMonitorWindow(MONITORING_WINDOW).setProtocolType(etherType);
254         return profileBuilder.build();
255     }
256 }