2 * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
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
8 package org.opendaylight.genius.interfacemanager.commons;
10 import com.google.common.base.Optional;
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.concurrent.ExecutionException;
14 import java.util.concurrent.Future;
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
17 import org.opendaylight.genius.interfacemanager.IfmUtil;
18 import org.opendaylight.genius.mdsalutil.MDSALUtil;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.AlivenessMonitorService;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.EtherTypes;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorProfileCreateInput;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorProfileCreateInputBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorProfileCreateOutput;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorProfileDeleteInput;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorProfileDeleteInputBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorProfileGetInput;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorProfileGetInputBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorProfileGetOutput;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorStartInput;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorStartInputBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorStartOutput;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorStopInput;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitorStopInputBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.MonitoringMode;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitor.params.SourceBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitor.profile.create.input.Profile;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitor.profile.create.input.ProfileBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitor.start.input.ConfigBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.InterfaceMonitorIdMap;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.MonitorIdInterfaceMap;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.monitor.id.map.InterfaceMonitorId;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.monitor.id.map.InterfaceMonitorIdBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.monitor.id.map.InterfaceMonitorIdKey;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.monitor.id._interface.map.MonitorIdInterface;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.monitor.id._interface.map.MonitorIdInterfaceBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.monitor.id._interface.map.MonitorIdInterfaceKey;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeLldp;
50 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
51 import org.opendaylight.yangtools.yang.common.RpcResult;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
55 public class AlivenessMonitorUtils {
57 private static final Logger LOG = LoggerFactory.getLogger(AlivenessMonitorUtils.class);
58 private static final long FAILURE_THRESHOLD = 4;
59 private static final long MONITORING_INTERVAL = 10000;
60 private static final long MONITORING_WINDOW = 4;
62 public static void startLLDPMonitoring(AlivenessMonitorService alivenessMonitorService, DataBroker dataBroker,
63 IfTunnel ifTunnel, String trunkInterfaceName) {
64 //LLDP monitoring for the tunnel interface
65 if(lldpMonitoringEnabled(ifTunnel)) {
66 MonitorStartInput lldpMonitorInput = new MonitorStartInputBuilder().setConfig(new ConfigBuilder()
67 .setSource(new SourceBuilder().setEndpointType(getInterfaceForMonitoring(trunkInterfaceName,
68 ifTunnel.getTunnelSource())).build())
69 .setMode(MonitoringMode.OneOne)
70 .setProfileId(allocateProfile(alivenessMonitorService, FAILURE_THRESHOLD, ifTunnel.getMonitorInterval(), MONITORING_WINDOW,
71 EtherTypes.Lldp)).build()).build();
73 Future<RpcResult<MonitorStartOutput>> result = alivenessMonitorService.monitorStart(lldpMonitorInput);
74 RpcResult<MonitorStartOutput> rpcResult = result.get();
76 if (rpcResult.isSuccessful()) {
77 monitorId = rpcResult.getResult().getMonitorId();
78 createOrUpdateInterfaceMonitorIdMap(dataBroker, trunkInterfaceName, monitorId);
79 createOrUpdateMonitorIdInterfaceMap(dataBroker, trunkInterfaceName, monitorId);
80 LOG.trace("Started LLDP monitoring with id {}", monitorId);
82 LOG.warn("RPC Call to start monitoring returned with Errors {}", rpcResult.getErrors());
84 } catch (InterruptedException | ExecutionException e) {
85 LOG.warn("Exception when starting monitoring", e);
90 public static void stopLLDPMonitoring(AlivenessMonitorService alivenessMonitorService, DataBroker dataBroker,
91 IfTunnel ifTunnel, String trunkInterface) {
92 if(!lldpMonitoringEnabled(ifTunnel)){
95 LOG.debug("stop LLDP monitoring for {}", trunkInterface);
96 List<Long> monitorIds = getMonitorIdForInterface(dataBroker, trunkInterface);
97 if (monitorIds == null) {
98 LOG.error("Monitor Id doesn't exist for Interface {}", trunkInterface);
101 for (Long monitorId : monitorIds) {
102 String interfaceName = getInterfaceFromMonitorId(dataBroker, monitorId);
103 if (interfaceName != null) {
104 MonitorStopInput input = new MonitorStopInputBuilder().setMonitorId(monitorId).build();
105 alivenessMonitorService.monitorStop(input);
106 removeMonitorIdInterfaceMap(dataBroker, monitorId);
107 removeMonitorIdFromInterfaceMonitorIdMap(dataBroker, interfaceName, monitorId);
113 public static String getInterfaceFromMonitorId(DataBroker broker, Long monitorId) {
114 InstanceIdentifier<MonitorIdInterface> id = InstanceIdentifier.builder(MonitorIdInterfaceMap.class).child(MonitorIdInterface.class, new MonitorIdInterfaceKey(monitorId)).build();
115 return IfmUtil.read(LogicalDatastoreType.OPERATIONAL, id, broker).transform(
116 MonitorIdInterface::getInterfaceName).orNull();
119 private static void removeMonitorIdInterfaceMap(DataBroker broker, long monitorId) {
120 InstanceIdentifier<MonitorIdInterface> id = InstanceIdentifier.builder(MonitorIdInterfaceMap.class).child(MonitorIdInterface.class, new MonitorIdInterfaceKey(monitorId)).build();
121 Optional<MonitorIdInterface> monitorIdInterfaceMap = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, id, broker);
122 if (monitorIdInterfaceMap.isPresent()) {
123 MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, id);
127 private static void removeMonitorIdFromInterfaceMonitorIdMap(DataBroker broker, String infName, long monitorId) {
128 InstanceIdentifier<InterfaceMonitorId> id = InstanceIdentifier.builder(InterfaceMonitorIdMap.class).child(InterfaceMonitorId.class, new InterfaceMonitorIdKey(infName)).build();
129 Optional<InterfaceMonitorId> interfaceMonitorIdMap = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, id, broker);
130 if (interfaceMonitorIdMap.isPresent()) {
131 InterfaceMonitorId interfaceMonitorIdInstance = interfaceMonitorIdMap.get();
132 List<Long> existingMonitorIds = interfaceMonitorIdInstance.getMonitorId();
133 if (existingMonitorIds != null && existingMonitorIds.contains(monitorId)) {
134 existingMonitorIds.remove(monitorId);
135 InterfaceMonitorIdBuilder interfaceMonitorIdBuilder = new InterfaceMonitorIdBuilder();
136 interfaceMonitorIdInstance = interfaceMonitorIdBuilder.setKey(new InterfaceMonitorIdKey(infName)).setMonitorId(existingMonitorIds).build();
137 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, id, interfaceMonitorIdInstance);
142 private static org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.endpoint.endpoint.type.Interface getInterfaceForMonitoring(String interfaceName, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress ipAddress) {
143 return new org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.endpoint.
144 endpoint.type.InterfaceBuilder().setInterfaceIp(ipAddress).setInterfaceName(interfaceName).build();
147 public static void handleTunnelMonitorUpdates(AlivenessMonitorService alivenessMonitorService, DataBroker dataBroker,
148 Interface interfaceOld, Interface interfaceNew) {
149 String interfaceName = interfaceNew.getName();
150 IfTunnel ifTunnelNew = interfaceNew.getAugmentation(IfTunnel.class);
151 if(!lldpMonitoringEnabled(ifTunnelNew)){
154 LOG.debug("handling tunnel monitoring updates for interface {}", interfaceName);
156 stopLLDPMonitoring(alivenessMonitorService, dataBroker, ifTunnelNew, interfaceOld.getName());
157 if(ifTunnelNew.isMonitorEnabled()) {
158 startLLDPMonitoring(alivenessMonitorService, dataBroker, ifTunnelNew, interfaceName);
160 // Delete old profile from Aliveness Manager
161 IfTunnel ifTunnelOld = interfaceOld.getAugmentation(IfTunnel.class);
162 if(ifTunnelNew.getMonitorInterval() != ifTunnelOld.getMonitorInterval()) {
163 LOG.debug("deleting older monitor profile for interface {}", interfaceName);
164 long profileId = allocateProfile(alivenessMonitorService, FAILURE_THRESHOLD, ifTunnelOld.getMonitorInterval(), MONITORING_WINDOW, EtherTypes.Lldp);
165 MonitorProfileDeleteInput profileDeleteInput = new MonitorProfileDeleteInputBuilder().setProfileId(profileId).build();
166 alivenessMonitorService.monitorProfileDelete(profileDeleteInput);
172 public static void createOrUpdateInterfaceMonitorIdMap(DataBroker broker, String infName, long monitorId) {
173 InterfaceMonitorId interfaceMonitorIdInstance;
174 List<Long> existingMonitorIds;
175 InterfaceMonitorIdBuilder interfaceMonitorIdBuilder = new InterfaceMonitorIdBuilder();
176 InstanceIdentifier<InterfaceMonitorId> id = InstanceIdentifier.builder(InterfaceMonitorIdMap.class).child(InterfaceMonitorId.class, new InterfaceMonitorIdKey(infName)).build();
177 Optional<InterfaceMonitorId> interfaceMonitorIdMap = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, id, broker);
178 if (interfaceMonitorIdMap.isPresent()) {
179 interfaceMonitorIdInstance = interfaceMonitorIdMap.get();
180 existingMonitorIds = interfaceMonitorIdInstance.getMonitorId();
181 if (existingMonitorIds == null) {
182 existingMonitorIds = new ArrayList<>();
184 if (!existingMonitorIds.contains(monitorId)) {
185 existingMonitorIds.add(monitorId);
186 interfaceMonitorIdInstance = interfaceMonitorIdBuilder.setKey(new InterfaceMonitorIdKey(infName)).setMonitorId(existingMonitorIds).build();
187 MDSALUtil.syncUpdate(broker, LogicalDatastoreType.OPERATIONAL, id, interfaceMonitorIdInstance);
190 existingMonitorIds = new ArrayList<>();
191 existingMonitorIds.add(monitorId);
192 interfaceMonitorIdInstance = interfaceMonitorIdBuilder.setMonitorId(existingMonitorIds).setKey(new InterfaceMonitorIdKey(infName)).setInterfaceName(infName).build();
193 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, id, interfaceMonitorIdInstance);
197 public static void createOrUpdateMonitorIdInterfaceMap(DataBroker broker,String infName, long monitorId) {
198 MonitorIdInterface monitorIdInterfaceInstance;
199 String existinginterfaceName;
200 MonitorIdInterfaceBuilder monitorIdInterfaceBuilder = new MonitorIdInterfaceBuilder();
201 InstanceIdentifier<MonitorIdInterface> id = InstanceIdentifier.builder(MonitorIdInterfaceMap.class).child(MonitorIdInterface.class, new MonitorIdInterfaceKey(monitorId)).build();
202 Optional<MonitorIdInterface> monitorIdInterfaceMap = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, id, broker);
203 if(monitorIdInterfaceMap.isPresent()) {
204 monitorIdInterfaceInstance = monitorIdInterfaceMap.get();
205 existinginterfaceName = monitorIdInterfaceInstance.getInterfaceName();
206 if(!existinginterfaceName.equals(infName)) {
207 monitorIdInterfaceInstance = monitorIdInterfaceBuilder.setKey(new MonitorIdInterfaceKey(monitorId)).setInterfaceName(infName).build();
208 MDSALUtil.syncUpdate(broker, LogicalDatastoreType.OPERATIONAL, id, monitorIdInterfaceInstance);
211 monitorIdInterfaceInstance = monitorIdInterfaceBuilder.setMonitorId(monitorId).setKey(new MonitorIdInterfaceKey(monitorId)).setInterfaceName(infName).build();
212 MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, id, monitorIdInterfaceInstance);
216 public static List<Long> getMonitorIdForInterface(DataBroker broker, String infName) {
217 InstanceIdentifier<InterfaceMonitorId> id = InstanceIdentifier.builder(InterfaceMonitorIdMap.class).child(InterfaceMonitorId.class, new InterfaceMonitorIdKey(infName)).build();
218 return IfmUtil.read(LogicalDatastoreType.OPERATIONAL, id, broker).transform(
219 InterfaceMonitorId::getMonitorId).orNull();
222 public static long createMonitorProfile(AlivenessMonitorService alivenessMonitor, MonitorProfileCreateInput monitorProfileCreateInput) {
224 Future<RpcResult<MonitorProfileCreateOutput>> result = alivenessMonitor.monitorProfileCreate(monitorProfileCreateInput);
225 RpcResult<MonitorProfileCreateOutput> rpcResult = result.get();
226 if(rpcResult.isSuccessful()) {
227 return rpcResult.getResult().getProfileId();
229 LOG.warn("RPC Call to Get Profile Id Id returned with Errors {}.. Trying to fetch existing profile ID", rpcResult.getErrors());
231 Profile createProfile = monitorProfileCreateInput.getProfile();
232 Future<RpcResult<MonitorProfileGetOutput>> existingProfile = alivenessMonitor.monitorProfileGet(buildMonitorGetProfile(createProfile.getMonitorInterval(), createProfile.getMonitorWindow(), createProfile.getFailureThreshold(), createProfile.getProtocolType()));
233 RpcResult<MonitorProfileGetOutput> rpcGetResult = existingProfile.get();
234 if(rpcGetResult.isSuccessful()){
235 return rpcGetResult.getResult().getProfileId();
237 LOG.warn("RPC Call to Get Existing Profile Id returned with Errors {}", rpcGetResult.getErrors());
240 LOG.warn("Exception when getting existing profile",e);
243 } catch (InterruptedException | ExecutionException e) {
244 LOG.warn("Exception when allocating profile Id",e);
249 private static MonitorProfileGetInput buildMonitorGetProfile(long monitorInterval, long monitorWindow, long failureThreshold, EtherTypes protocolType){
250 MonitorProfileGetInputBuilder buildGetProfile = new MonitorProfileGetInputBuilder();
251 org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitor.profile.get.input.ProfileBuilder profileBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.monitor.profile.get.input.ProfileBuilder();
252 profileBuilder.setFailureThreshold(failureThreshold);
253 profileBuilder.setMonitorInterval(monitorInterval);
254 profileBuilder.setMonitorWindow(monitorWindow);
255 profileBuilder.setProtocolType(protocolType);
256 buildGetProfile.setProfile(profileBuilder.build());
257 return (buildGetProfile.build());
260 public static long allocateProfile(AlivenessMonitorService alivenessMonitor, long FAILURE_THRESHOLD, long MONITORING_INTERVAL,
261 long MONITORING_WINDOW, EtherTypes etherTypes) {
262 MonitorProfileCreateInput input = new MonitorProfileCreateInputBuilder().
263 setProfile(new ProfileBuilder().setFailureThreshold(FAILURE_THRESHOLD)
264 .setMonitorInterval(MONITORING_INTERVAL).setMonitorWindow(MONITORING_WINDOW).
265 setProtocolType(etherTypes).build()).build();
266 return createMonitorProfile(alivenessMonitor, input);
269 public static boolean lldpMonitoringEnabled(IfTunnel ifTunnel){
270 return ifTunnel.isInternal() && ifTunnel.isMonitorEnabled() &&
271 TunnelMonitoringTypeLldp.class.isAssignableFrom(ifTunnel.getMonitorProtocol());
274 public static Profile getDefaultMonitorProfile(EtherTypes etherType) {
275 ProfileBuilder profileBuilder = new ProfileBuilder();
276 profileBuilder.setProtocolType(etherType);
277 profileBuilder.setFailureThreshold(FAILURE_THRESHOLD)
278 .setMonitorInterval(MONITORING_INTERVAL).setMonitorWindow(MONITORING_WINDOW).setProtocolType(etherType);
279 return profileBuilder.build();