9b5fb6afd5be12354e0d7676c51a24660c6c2fdd
[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.genius.infra.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.infra.ManagedNewTransactionRunner;
20 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
21 import org.opendaylight.genius.interfacemanager.IfmConstants;
22 import org.opendaylight.genius.interfacemanager.IfmUtil;
23 import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
24 import org.opendaylight.genius.interfacemanager.commons.InterfaceMetaUtils;
25 import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.SouthboundUtils;
26 import org.opendaylight.genius.utils.clustering.EntityOwnershipUtils;
27 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
28 import org.opendaylight.mdsal.binding.api.DataBroker;
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<ListenableFuture<Void>> updateBridgeRefEntry(InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid,
72                                                              OvsdbBridgeAugmentation bridgeNew,
73                                                              OvsdbBridgeAugmentation bridgeOld) {
74         return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, tx -> {
75             Uint64 dpnIdNew = IfmUtil.getDpnId(bridgeNew.getDatapathId());
76             Uint64 dpnIdOld = IfmUtil.getDpnId(bridgeOld.getDatapathId());
77
78             LOG.debug("updating bridge references for bridge: {}, dpnNew: {}, dpnOld: {}", bridgeNew,
79                     dpnIdNew, dpnIdOld);
80             // delete bridge reference entry for the old dpn in interface meta
81             // operational DS
82             InterfaceMetaUtils.deleteBridgeRefEntry(dpnIdOld, tx);
83
84             // create bridge reference entry in interface meta operational DS
85             InterfaceMetaUtils.createBridgeRefEntry(dpnIdNew, bridgeIid, tx);
86
87             // handle pre-provisioning of tunnels for the newly connected dpn
88             BridgeEntry bridgeEntry = interfaceMetaUtils.getBridgeEntryFromConfigDS(dpnIdNew);
89             if (bridgeEntry != null) {
90                 southboundUtils.addAllPortsToBridge(bridgeEntry, interfaceManagerCommonUtils, bridgeIid, bridgeNew);
91             }
92         }));
93     }
94
95     public List<ListenableFuture<Void>> updateTunnelState(OvsdbTerminationPointAugmentation terminationPointNew) {
96         final Interface.OperStatus interfaceBfdStatus = getTunnelOpState(terminationPointNew);
97         final String interfaceName = terminationPointNew.getName();
98         interfaceManagerCommonUtils.addBfdStateToCache(interfaceName, interfaceBfdStatus);
99         if (!entityOwnershipUtils.isEntityOwner(IfmConstants.INTERFACE_CONFIG_ENTITY,
100                 IfmConstants.INTERFACE_CONFIG_ENTITY)) {
101             return Collections.emptyList();
102         }
103
104         coordinator.enqueueJob(interfaceName, () -> {
105             // update opstate of interface if TEP has gone down/up as a result
106             // of BFD monitoring
107             final Interface interfaceState = interfaceManagerCommonUtils
108                     .getInterfaceStateFromOperDS(terminationPointNew.getName());
109             if (interfaceState != null && interfaceState.getOperStatus() != Interface.OperStatus.Unknown
110                     && interfaceState.getOperStatus() != interfaceBfdStatus) {
111                 EVENT_LOGGER.debug("IFM-OvsInterfaceTopologyState,UPDATE {} to STATUS {}", interfaceName,
112                         interfaceState.getOperStatus());
113                 LOG.debug("updating tunnel state for interface {} as {}", interfaceName, interfaceBfdStatus);
114                 return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL,
115                     tx -> InterfaceManagerCommonUtils.updateOpState(tx, interfaceName, interfaceBfdStatus)));
116             }
117             return Collections.emptyList();
118         });
119         return Collections.emptyList();
120     }
121
122     private static Interface.OperStatus getTunnelOpState(OvsdbTerminationPointAugmentation terminationPoint) {
123         if (!SouthboundUtils.bfdMonitoringEnabled(terminationPoint.getInterfaceBfd())) {
124             return Interface.OperStatus.Up;
125         }
126         Interface.OperStatus livenessState = Interface.OperStatus.Down;
127         Map<InterfaceBfdStatusKey, InterfaceBfdStatus> tunnelBfdStatus = terminationPoint.getInterfaceBfdStatus();
128         if (tunnelBfdStatus != null && !tunnelBfdStatus.isEmpty()) {
129             for (InterfaceBfdStatus bfdState : tunnelBfdStatus.values()) {
130                 if (SouthboundUtils.BFD_OP_STATE.equalsIgnoreCase(bfdState.getBfdStatusKey())) {
131                     String bfdOpState = bfdState.getBfdStatusValue();
132                     livenessState = SouthboundUtils.BFD_STATE_UP.equalsIgnoreCase(bfdOpState) ? Interface.OperStatus.Up
133                             : Interface.OperStatus.Down;
134                     break;
135                 }
136             }
137         }
138         return livenessState;
139     }
140 }