02a3a2ace4b75378a70845e77260d25515e67e9a
[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.InterfaceManagerCommonUtils;
16 import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
17 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry;
26 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 import java.util.ArrayList;
31 import java.util.List;
32
33 public class OvsInterfaceStateUpdateHelper {
34     private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceStateUpdateHelper.class);
35
36     public static List<ListenableFuture<Void>> updateState(InstanceIdentifier<FlowCapableNodeConnector> key,
37                                                            DataBroker dataBroker, String portName,
38                                                            FlowCapableNodeConnector flowCapableNodeConnectorNew,
39                                                            FlowCapableNodeConnector flowCapableNodeConnectorOld) {
40         LOG.debug("Update of Interface State for port: {}", portName);
41         List<ListenableFuture<Void>> futures = new ArrayList<>();
42         WriteTransaction t = dataBroker.newWriteOnlyTransaction();
43
44         Interface.OperStatus operStatusNew =
45                 flowCapableNodeConnectorNew.getState().isLinkDown() ? Interface.OperStatus.Down : Interface.OperStatus.Up;
46         Interface.AdminStatus adminStatusNew =
47                 flowCapableNodeConnectorNew.getState().isBlocked() ? Interface.AdminStatus.Down : Interface.AdminStatus.Up;
48         MacAddress macAddressNew = flowCapableNodeConnectorNew.getHardwareAddress();
49
50         Interface.OperStatus operStatusOld =
51                 flowCapableNodeConnectorOld.getState().isLinkDown() ? Interface.OperStatus.Down : Interface.OperStatus.Up;
52         Interface.AdminStatus adminStatusOld =
53                 flowCapableNodeConnectorOld.getState().isBlocked() ? Interface.AdminStatus.Down : Interface.AdminStatus.Up;
54         MacAddress macAddressOld = flowCapableNodeConnectorOld.getHardwareAddress();
55
56         boolean opstateModified = false;
57         boolean adminStateModified = false;
58         boolean hardwareAddressModified = false;
59         if (!operStatusNew.equals(operStatusOld)) {
60             opstateModified = true;
61         }
62         if (!adminStatusNew.equals(adminStatusOld)) {
63             adminStateModified = true;
64         }
65         if (!macAddressNew.equals(macAddressOld)) {
66             hardwareAddressModified = true;
67         }
68
69         if (!opstateModified && !adminStateModified && !hardwareAddressModified) {
70             LOG.debug("If State entry for port: {} Not Modified.", portName);
71             return futures;
72         }
73
74         InstanceIdentifier<Interface> ifStateId = IfmUtil.buildStateInterfaceId(portName);
75         InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
76
77         boolean modified = false;
78         if (opstateModified) {
79             LOG.debug("Opstate Modified for Port: {}", portName);
80             InterfaceKey interfaceKey = new InterfaceKey(portName);
81             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
82                     InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
83
84             // If interface config admin state is disabled, set operstate of the Interface State entity to Down.
85             if (iface != null && !iface.isEnabled()) {
86                 operStatusNew = Interface.OperStatus.Down;
87             }
88
89             ifaceBuilder.setOperStatus(operStatusNew);
90             modified = true;
91         }
92
93         if (adminStateModified) {
94             LOG.debug("Admin state Modified for Port: {}", portName);
95             ifaceBuilder.setAdminStatus(adminStatusNew);
96             modified = true;
97         }
98
99         if (hardwareAddressModified) {
100             LOG.debug("Hw-Address Modified for Port: {}", portName);
101             PhysAddress physAddress = new PhysAddress(macAddressNew.getValue());
102             ifaceBuilder.setPhysAddress(physAddress);
103             modified = true;
104         }
105
106         /* FIXME: Is there chance that lower layer node-connector info is updated.
107                   Not Considering for now.
108          */
109
110         if (modified) {
111             ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(portName));
112             t.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build());
113
114             InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(portName);
115             InterfaceParentEntry interfaceParentEntry =
116                     InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceParentEntryKey, dataBroker);
117             if (interfaceParentEntry == null) {
118                 futures.add(t.submit());
119                 return futures;
120             }
121
122             List<InterfaceChildEntry> interfaceChildEntries = interfaceParentEntry.getInterfaceChildEntry();
123             if (interfaceChildEntries == null) {
124                 futures.add(t.submit());
125                 return futures;
126             }
127
128             LOG.debug("Updating if-state entries for Vlan-Trunk Members for port: {}", portName);
129             //FIXME: If the no. of child entries exceeds 100, perform txn updates in batches of 100.
130             for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries) {
131                 InstanceIdentifier<Interface> ifChildStateId =
132                         IfmUtil.buildStateInterfaceId(interfaceChildEntry.getChildInterface());
133                 t.merge(LogicalDatastoreType.OPERATIONAL, ifChildStateId, ifaceBuilder.build());
134             }
135         }
136
137         futures.add(t.submit());
138         return futures;
139     }
140 }