Convert interfacemanager to use mdsal-binding-util
[genius.git] / interfacemanager / interfacemanager-impl / src / main / java / org / opendaylight / genius / interfacemanager / renderer / ovs / statehelpers / OvsInterfaceTopologyStateUpdateHelper.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 static org.opendaylight.mdsal.binding.util.Datastore.OPERATIONAL;
11
12 import com.google.common.util.concurrent.ListenableFuture;
13 import java.util.Collections;
14 import java.util.List;
15 import java.util.Map;
16 import javax.inject.Inject;
17 import javax.inject.Singleton;
18 import org.apache.aries.blueprint.annotation.service.Reference;
19 import org.opendaylight.genius.interfacemanager.IfmConstants;
20 import org.opendaylight.genius.interfacemanager.IfmUtil;
21 import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
22 import org.opendaylight.genius.interfacemanager.commons.InterfaceMetaUtils;
23 import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.SouthboundUtils;
24 import org.opendaylight.genius.utils.clustering.EntityOwnershipUtils;
25 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
26 import org.opendaylight.mdsal.binding.api.DataBroker;
27 import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunner;
28 import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunnerImpl;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge._interface.info.BridgeEntry;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceBfdStatus;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceBfdStatusKey;
35 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
36 import org.opendaylight.yangtools.yang.common.Uint64;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 @Singleton
41 public class OvsInterfaceTopologyStateUpdateHelper {
42     private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceTopologyStateUpdateHelper.class);
43     private static final Logger EVENT_LOGGER = LoggerFactory.getLogger("GeniusEventLogger");
44
45     private final ManagedNewTransactionRunner txRunner;
46     private final EntityOwnershipUtils entityOwnershipUtils;
47     private final JobCoordinator coordinator;
48     private final InterfaceManagerCommonUtils interfaceManagerCommonUtils;
49     private final InterfaceMetaUtils interfaceMetaUtils;
50     private final SouthboundUtils southboundUtils;
51
52     @Inject
53     public OvsInterfaceTopologyStateUpdateHelper(@Reference DataBroker dataBroker,
54                                                  EntityOwnershipUtils entityOwnershipUtils,
55                                                  @Reference JobCoordinator coordinator,
56                                                  InterfaceManagerCommonUtils interfaceManagerCommonUtils,
57                                                  InterfaceMetaUtils interfaceMetaUtils,
58                                                  SouthboundUtils southboundUtils) {
59         this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
60         this.entityOwnershipUtils = entityOwnershipUtils;
61         this.coordinator = coordinator;
62         this.interfaceManagerCommonUtils = interfaceManagerCommonUtils;
63         this.interfaceMetaUtils = interfaceMetaUtils;
64         this.southboundUtils = southboundUtils;
65     }
66
67     /*
68      * This code is used to handle only a dpnId change scenario for a particular
69      * change, which is not expected to happen in usual cases.
70      */
71     public List<? extends ListenableFuture<?>> updateBridgeRefEntry(
72             InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid,
73             OvsdbBridgeAugmentation bridgeNew,
74             OvsdbBridgeAugmentation bridgeOld) {
75         return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, tx -> {
76             Uint64 dpnIdNew = IfmUtil.getDpnId(bridgeNew.getDatapathId());
77             Uint64 dpnIdOld = IfmUtil.getDpnId(bridgeOld.getDatapathId());
78
79             LOG.debug("updating bridge references for bridge: {}, dpnNew: {}, dpnOld: {}", bridgeNew,
80                     dpnIdNew, dpnIdOld);
81             // delete bridge reference entry for the old dpn in interface meta
82             // operational DS
83             InterfaceMetaUtils.deleteBridgeRefEntry(dpnIdOld, tx);
84
85             // create bridge reference entry in interface meta operational DS
86             InterfaceMetaUtils.createBridgeRefEntry(dpnIdNew, bridgeIid, tx);
87
88             // handle pre-provisioning of tunnels for the newly connected dpn
89             BridgeEntry bridgeEntry = interfaceMetaUtils.getBridgeEntryFromConfigDS(dpnIdNew);
90             if (bridgeEntry != null) {
91                 southboundUtils.addAllPortsToBridge(bridgeEntry, interfaceManagerCommonUtils, bridgeIid, bridgeNew);
92             }
93         }));
94     }
95
96     public List<ListenableFuture<Void>> updateTunnelState(OvsdbTerminationPointAugmentation terminationPointNew) {
97         final Interface.OperStatus interfaceBfdStatus = getTunnelOpState(terminationPointNew);
98         final String interfaceName = terminationPointNew.getName();
99         interfaceManagerCommonUtils.addBfdStateToCache(interfaceName, interfaceBfdStatus);
100         if (!entityOwnershipUtils.isEntityOwner(IfmConstants.INTERFACE_CONFIG_ENTITY,
101                 IfmConstants.INTERFACE_CONFIG_ENTITY)) {
102             return Collections.emptyList();
103         }
104
105         coordinator.enqueueJob(interfaceName, () -> {
106             // update opstate of interface if TEP has gone down/up as a result
107             // of BFD monitoring
108             final Interface interfaceState = interfaceManagerCommonUtils
109                     .getInterfaceStateFromOperDS(terminationPointNew.getName());
110             if (interfaceState != null && interfaceState.getOperStatus() != Interface.OperStatus.Unknown
111                     && interfaceState.getOperStatus() != interfaceBfdStatus) {
112                 EVENT_LOGGER.debug("IFM-OvsInterfaceTopologyState,UPDATE {} to STATUS {}", interfaceName,
113                         interfaceState.getOperStatus());
114                 LOG.debug("updating tunnel state for interface {} as {}", interfaceName, interfaceBfdStatus);
115                 return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL,
116                     tx -> InterfaceManagerCommonUtils.updateOpState(tx, interfaceName, interfaceBfdStatus)));
117             }
118             return Collections.emptyList();
119         });
120         return Collections.emptyList();
121     }
122
123     private static Interface.OperStatus getTunnelOpState(OvsdbTerminationPointAugmentation terminationPoint) {
124         if (!SouthboundUtils.bfdMonitoringEnabled(terminationPoint.getInterfaceBfd())) {
125             return Interface.OperStatus.Up;
126         }
127         Interface.OperStatus livenessState = Interface.OperStatus.Down;
128         Map<InterfaceBfdStatusKey, InterfaceBfdStatus> tunnelBfdStatus = terminationPoint.getInterfaceBfdStatus();
129         if (tunnelBfdStatus != null && !tunnelBfdStatus.isEmpty()) {
130             for (InterfaceBfdStatus bfdState : tunnelBfdStatus.values()) {
131                 if (SouthboundUtils.BFD_OP_STATE.equalsIgnoreCase(bfdState.getBfdStatusKey())) {
132                     String bfdOpState = bfdState.getBfdStatusValue();
133                     livenessState = SouthboundUtils.BFD_STATE_UP.equalsIgnoreCase(bfdOpState) ? Interface.OperStatus.Up
134                             : Interface.OperStatus.Down;
135                     break;
136                 }
137             }
138         }
139         return livenessState;
140     }
141 }