Bug 5182 - Customized name support for VLAN trunk should be supported
[vpnservice.git] / interfacemgr / interfacemgr-impl / src / main / java / org / opendaylight / vpnservice / interfacemgr / renderer / ovs / statehelpers / OvsInterfaceStateUpdateHelper.java
1 /*
2  * Copyright (c) 2015 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.renderer.ovs.statehelpers;
9
10 import com.google.common.util.concurrent.ListenableFuture;
11 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
12 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
13 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
14 import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
15 import org.opendaylight.vpnservice.interfacemgr.commons.AlivenessMonitorUtils;
16 import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
17 import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
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.yang.types.rev100924.MacAddress;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.AlivenessMonitorService;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel;
29 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 import java.util.ArrayList;
34 import java.util.List;
35
36 public class OvsInterfaceStateUpdateHelper {
37     private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceStateUpdateHelper.class);
38
39     public static List<ListenableFuture<Void>> updateState(InstanceIdentifier<FlowCapableNodeConnector> key,
40                                                            AlivenessMonitorService alivenessMonitorService,
41                                                            DataBroker dataBroker, String portName,
42                                                            FlowCapableNodeConnector flowCapableNodeConnectorNew,
43                                                            FlowCapableNodeConnector flowCapableNodeConnectorOld) {
44         LOG.debug("Update of Interface State for port: {}", portName);
45         List<ListenableFuture<Void>> futures = new ArrayList<>();
46         WriteTransaction t = dataBroker.newWriteOnlyTransaction();
47
48         Interface.OperStatus operStatusNew =
49                 flowCapableNodeConnectorNew.getState().isLinkDown() ? Interface.OperStatus.Down : Interface.OperStatus.Up;
50         Interface.AdminStatus adminStatusNew =
51                 flowCapableNodeConnectorNew.getState().isBlocked() ? Interface.AdminStatus.Down : Interface.AdminStatus.Up;
52         MacAddress macAddressNew = flowCapableNodeConnectorNew.getHardwareAddress();
53
54         Interface.OperStatus operStatusOld =
55                 flowCapableNodeConnectorOld.getState().isLinkDown() ? Interface.OperStatus.Down : Interface.OperStatus.Up;
56         Interface.AdminStatus adminStatusOld =
57                 flowCapableNodeConnectorOld.getState().isBlocked() ? Interface.AdminStatus.Down : Interface.AdminStatus.Up;
58         MacAddress macAddressOld = flowCapableNodeConnectorOld.getHardwareAddress();
59
60         boolean opstateModified = false;
61         boolean adminStateModified = false;
62         boolean hardwareAddressModified = false;
63         if (!operStatusNew.equals(operStatusOld)) {
64             opstateModified = true;
65         }
66         if (!adminStatusNew.equals(adminStatusOld)) {
67             adminStateModified = true;
68         }
69         if (!macAddressNew.equals(macAddressOld)) {
70             hardwareAddressModified = true;
71         }
72
73         if (!opstateModified && !adminStateModified && !hardwareAddressModified) {
74             LOG.debug("If State entry for port: {} Not Modified.", portName);
75             return futures;
76         }
77
78         InstanceIdentifier<Interface> ifStateId = IfmUtil.buildStateInterfaceId(portName);
79         InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
80         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface = null;
81         boolean modified = false;
82         if (opstateModified) {
83             LOG.debug("Opstate Modified for Port: {}", portName);
84             InterfaceKey interfaceKey = new InterfaceKey(portName);
85              iface = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
86
87             // If interface config admin state is disabled, set operstate of the Interface State entity to Down.
88             if (iface != null && !iface.isEnabled()) {
89                 operStatusNew = Interface.OperStatus.Down;
90             }
91
92             ifaceBuilder.setOperStatus(operStatusNew);
93             modified = true;
94         }
95
96         if (adminStateModified) {
97             LOG.debug("Admin state Modified for Port: {}", portName);
98             ifaceBuilder.setAdminStatus(adminStatusNew);
99             modified = true;
100         }
101
102         if (hardwareAddressModified) {
103             LOG.debug("Hw-Address Modified for Port: {}", portName);
104             PhysAddress physAddress = new PhysAddress(macAddressNew.getValue());
105             ifaceBuilder.setPhysAddress(physAddress);
106             modified = true;
107         }
108
109         /* FIXME: Is there chance that lower layer node-connector info is updated.
110                   Not Considering for now.
111          */
112
113         if (modified) {
114             ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(portName));
115             t.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build());
116
117             InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(portName);
118             InterfaceParentEntry interfaceParentEntry =
119                     InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceParentEntryKey, dataBroker);
120             if (interfaceParentEntry == null || interfaceParentEntry.getInterfaceChildEntry() == null) {
121                 futures.add(t.submit());
122                 // start/stop monitoring based on opState
123                 IfTunnel ifTunnel = iface.getAugmentation(IfTunnel.class);
124                 if(ifTunnel != null) {
125                     if (operStatusNew == Interface.OperStatus.Down)
126                         AlivenessMonitorUtils.stopLLDPMonitoring(alivenessMonitorService, dataBroker, iface);
127                     else
128                         AlivenessMonitorUtils.startLLDPMonitoring(alivenessMonitorService, dataBroker, iface);
129                 }
130                 return futures;
131             }
132             for(InterfaceChildEntry higherlayerChild : interfaceParentEntry.getInterfaceChildEntry()) {
133                 InstanceIdentifier<Interface> higherLayerIfChildStateId =
134                         IfmUtil.buildStateInterfaceId(higherlayerChild.getChildInterface());
135                 t.merge(LogicalDatastoreType.OPERATIONAL, higherLayerIfChildStateId, ifaceBuilder.build());
136                 InterfaceParentEntryKey higherLayerParentEntryKey = new InterfaceParentEntryKey(higherlayerChild.getChildInterface());
137                 InterfaceParentEntry higherLayerParent =
138                         InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(higherLayerParentEntryKey, dataBroker);
139                 if(higherLayerParent != null && higherLayerParent.getInterfaceChildEntry() != null) {
140                     for (InterfaceChildEntry interfaceChildEntry : higherLayerParent.getInterfaceChildEntry()) {
141                         LOG.debug("Updating if-state entries for Vlan-Trunk Members for port: {}", portName);
142                         //FIXME: If the no. of child entries exceeds 100, perform txn updates in batches of 100.
143                         InstanceIdentifier<Interface> ifChildStateId =
144                                 IfmUtil.buildStateInterfaceId(interfaceChildEntry.getChildInterface());
145                         t.merge(LogicalDatastoreType.OPERATIONAL, ifChildStateId, ifaceBuilder.build());
146                     }
147                 }
148             }
149         }
150
151         futures.add(t.submit());
152         return futures;
153     }
154 }