Log enhancements for better debuggability
[genius.git] / interfacemanager / interfacemanager-impl / src / main / java / org / opendaylight / genius / interfacemanager / renderer / ovs / statehelpers / OvsInterfaceStateUpdateHelper.java
1 /*
2  * Copyright (c) 2016, 2017 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.genius.interfacemanager.renderer.ovs.statehelpers;
9
10 import com.google.common.util.concurrent.ListenableFuture;
11 import java.util.ArrayList;
12 import java.util.List;
13 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
14 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
15 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
16 import org.opendaylight.genius.interfacemanager.IfmUtil;
17 import org.opendaylight.genius.interfacemanager.commons.AlivenessMonitorUtils;
18 import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.AlivenessMonitorService;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
27 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 public class OvsInterfaceStateUpdateHelper {
32     private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceStateUpdateHelper.class);
33
34     public static List<ListenableFuture<Void>> updateState(InstanceIdentifier<FlowCapableNodeConnector> key,
35             AlivenessMonitorService alivenessMonitorService, DataBroker dataBroker, String interfaceName,
36             FlowCapableNodeConnector flowCapableNodeConnectorNew,
37             FlowCapableNodeConnector flowCapableNodeConnectorOld) {
38         LOG.debug("Updating interface state information for interface: {}", interfaceName);
39         List<ListenableFuture<Void>> futures = new ArrayList<>();
40
41         Interface.OperStatus operStatusNew = InterfaceManagerCommonUtils.getOpState(flowCapableNodeConnectorNew);
42         MacAddress macAddressNew = flowCapableNodeConnectorNew.getHardwareAddress();
43
44         Interface.OperStatus operStatusOld = InterfaceManagerCommonUtils.getOpState(flowCapableNodeConnectorOld);
45         MacAddress macAddressOld = flowCapableNodeConnectorOld.getHardwareAddress();
46
47         boolean opstateModified = false;
48         boolean hardwareAddressModified = false;
49         if (!operStatusNew.equals(operStatusOld)) {
50             opstateModified = true;
51         }
52         if (!macAddressNew.equals(macAddressOld)) {
53             hardwareAddressModified = true;
54         }
55
56         if (!opstateModified && !hardwareAddressModified) {
57             LOG.debug("If State entry for port: {} Not Modified.", interfaceName);
58             return futures;
59         }
60
61         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
62             .interfaces.rev140508.interfaces.Interface iface = InterfaceManagerCommonUtils
63                 .getInterfaceFromConfigDS(interfaceName, dataBroker);
64
65         // For monitoring enabled tunnels, skip opstate update
66         if (isTunnelInterface(iface) && !modifyTunnelOpState(iface, opstateModified)) {
67             LOG.debug("skip interface-state updation for monitoring enabled tunnel interface {}", interfaceName);
68             opstateModified = false;
69         }
70
71         if (!opstateModified && !hardwareAddressModified) {
72             LOG.debug("If State entry for port: {} Not Modified.", interfaceName);
73             return futures;
74         }
75         InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
76         if (hardwareAddressModified) {
77             LOG.debug("Hw-Address Modified for Port: {}", interfaceName);
78             PhysAddress physAddress = new PhysAddress(macAddressNew.getValue());
79             ifaceBuilder.setPhysAddress(physAddress);
80         }
81         // modify the attributes in interface operational DS
82         WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
83         handleInterfaceStateUpdates(iface, transaction, dataBroker, ifaceBuilder, opstateModified, interfaceName,
84                 flowCapableNodeConnectorNew.getName(), operStatusNew);
85
86         // start/stop monitoring based on opState
87         if (isTunnelInterface(iface) && opstateModified) {
88             handleTunnelMonitoringUpdates(alivenessMonitorService, dataBroker, iface.getAugmentation(IfTunnel.class),
89                     iface.getName(), operStatusNew);
90         }
91
92         futures.add(transaction.submit());
93         return futures;
94     }
95
96     public static void updateInterfaceStateOnNodeRemove(String interfaceName,
97             FlowCapableNodeConnector flowCapableNodeConnector, DataBroker dataBroker,
98             AlivenessMonitorService alivenessMonitorService, WriteTransaction transaction) {
99         LOG.debug("Updating interface oper-status to UNKNOWN for : {}", interfaceName);
100
101         InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
102         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
103             .ietf.interfaces.rev140508.interfaces.Interface iface = InterfaceManagerCommonUtils
104                 .getInterfaceFromConfigDS(interfaceName, dataBroker);
105         handleInterfaceStateUpdates(iface, transaction, dataBroker, ifaceBuilder, true, interfaceName,
106                 flowCapableNodeConnector.getName(), Interface.OperStatus.Unknown);
107         if (InterfaceManagerCommonUtils.isTunnelInterface(iface)) {
108             handleTunnelMonitoringUpdates(alivenessMonitorService, dataBroker, iface.getAugmentation(IfTunnel.class),
109                     interfaceName, Interface.OperStatus.Unknown);
110         }
111     }
112
113     public static void handleInterfaceStateUpdates(
114             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
115                 .ietf.interfaces.rev140508.interfaces.Interface iface,
116             WriteTransaction transaction, DataBroker dataBroker, InterfaceBuilder ifaceBuilder, boolean opStateModified,
117             String interfaceName, String portName, Interface.OperStatus opState) {
118         // if interface config DS is null, do the update only for the
119         // lower-layer-interfaces
120         // which have no corresponding config entries
121         if (iface == null && !interfaceName.equals(portName)) {
122             return;
123         }
124         LOG.debug("updating interface state entry for {}", interfaceName);
125         InstanceIdentifier<Interface> ifStateId = IfmUtil.buildStateInterfaceId(interfaceName);
126         ifaceBuilder.setKey(new InterfaceKey(interfaceName));
127         if (modifyOpState(iface, opStateModified)) {
128             LOG.debug("updating interface oper status as {} for {}", opState.name(), interfaceName);
129             ifaceBuilder.setOperStatus(opState);
130         }
131         transaction.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build(), false);
132     }
133
134     public static void handleTunnelMonitoringUpdates(AlivenessMonitorService alivenessMonitorService,
135             DataBroker dataBroker, IfTunnel ifTunnel, String interfaceName, Interface.OperStatus operStatus) {
136         LOG.debug("handling tunnel monitoring updates for {} due to opstate modification", interfaceName);
137         if (operStatus == Interface.OperStatus.Down || operStatus == Interface.OperStatus.Unknown) {
138             AlivenessMonitorUtils.stopLLDPMonitoring(alivenessMonitorService, dataBroker, ifTunnel, interfaceName);
139         } else {
140             AlivenessMonitorUtils.startLLDPMonitoring(alivenessMonitorService, dataBroker, ifTunnel, interfaceName);
141         }
142     }
143
144     public static boolean modifyOpState(
145             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
146                 .interfaces.rev140508.interfaces.Interface iface,
147             boolean opStateModified) {
148         return opStateModified && (iface == null || iface != null && iface.isEnabled());
149     }
150
151     public static boolean isTunnelInterface(
152             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
153                 .ietf.interfaces.rev140508.interfaces.Interface iface) {
154         return iface != null && iface.getAugmentation(IfTunnel.class) != null;
155     }
156
157     public static boolean modifyTunnelOpState(
158             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
159                 .ietf.interfaces.rev140508.interfaces.Interface iface,
160             boolean opStateModified) {
161         if (!iface.getAugmentation(IfTunnel.class).isMonitorEnabled()) {
162             return modifyOpState(iface, opStateModified);
163         }
164         return false;
165     }
166 }