5807db58c1c857940dae2e2c7e6c871ed3161b8a
[genius.git] / itm / itm-impl / src / main / java / org / opendaylight / genius / itm / itmdirecttunnels / workers / TunnelStateAddWorker.java
1 /*
2  * Copyright (c) 2018 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.itm.itmdirecttunnels.workers;
9
10 import com.google.common.util.concurrent.ListenableFuture;
11 import java.util.Collections;
12 import java.util.List;
13 import java.util.concurrent.ExecutionException;
14 import org.opendaylight.genius.infra.Datastore;
15 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
16 import org.opendaylight.genius.interfacemanager.globals.IfmConstants;
17 import org.opendaylight.genius.itm.globals.ITMConstants;
18 import org.opendaylight.genius.itm.impl.ITMBatchingUtils;
19 import org.opendaylight.genius.itm.impl.ItmUtils;
20 import org.opendaylight.genius.itm.itmdirecttunnels.renderer.ovs.utilities.DirectTunnelUtils;
21 import org.opendaylight.genius.itm.utils.DpnTepInterfaceInfo;
22 import org.opendaylight.genius.itm.utils.TunnelStateInfo;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.IfIndexesTunnelMap;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210._if.indexes.tunnel.map.IfIndexTunnel;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210._if.indexes.tunnel.map.IfIndexTunnelBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210._if.indexes.tunnel.map.IfIndexTunnelKey;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeInternal;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelOperStatus;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListKey;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.state.tunnel.list.DstInfoBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.state.tunnel.list.SrcInfoBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
40 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
41 import org.opendaylight.yangtools.yang.common.OperationFailedException;
42 import org.opendaylight.yangtools.yang.common.Uint64;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45
46 public final class TunnelStateAddWorker {
47
48     private static final Logger LOG = LoggerFactory.getLogger(TunnelStateAddWorker.class);
49     private static final Logger EVENT_LOGGER = LoggerFactory.getLogger("GeniusEventLogger");
50
51     private final DirectTunnelUtils directTunnelUtils;
52     private final ManagedNewTransactionRunner txRunner;
53
54     public TunnelStateAddWorker(final DirectTunnelUtils directTunnelUtils, final ManagedNewTransactionRunner txRunner) {
55         this.directTunnelUtils = directTunnelUtils;
56         this.txRunner = txRunner;
57     }
58
59     public List<ListenableFuture<Void>> addState(TunnelStateInfo tunnelStateInfo)
60             throws ExecutionException, InterruptedException, OperationFailedException {
61
62         // When this method is invoked, all parameters necessary should be available
63         // Retrieve Port No from nodeConnectorId
64         NodeConnectorId nodeConnectorId = InstanceIdentifier.keyOf(tunnelStateInfo.getNodeConnectorInfo()
65                 .getNodeConnectorId().firstIdentifierOf(NodeConnector.class)).getId();
66         String tunnelName = tunnelStateInfo.getNodeConnectorInfo().getNodeConnector().getName();
67         if (tunnelName != null && tunnelName.startsWith("of")) {
68             tunnelName = tunnelStateInfo.getDpnTepInterfaceInfo().getTunnelName();
69         }
70
71         String interfaceName = tunnelName;
72
73         long portNo = DirectTunnelUtils.getPortNumberFromNodeConnectorId(nodeConnectorId);
74         EVENT_LOGGER.debug("ITM-TunnelState, ADD to oper DS {}", interfaceName);
75         if (portNo == ITMConstants.INVALID_PORT_NO) {
76             LOG.error("Cannot derive port number, not proceeding with Interface State addition for interface: {}",
77                 interfaceName);
78             EVENT_LOGGER.debug("ITM-TunnelState,ADD Table 0 flow for {} completed", interfaceName);
79             return Collections.emptyList();
80         }
81
82         LOG.info("adding interface state to Oper DS for interface: {}", interfaceName);
83
84         // Fetch the interface/Tunnel from config DS if exists
85         // If it doesnt exists then "park" the processing and comeback to it when the data is available and
86         // this will be triggered by the corres. listener. Caching and de-caching has to be synchronized.
87         StateTunnelList stateTnl = addStateEntry(interfaceName, portNo, tunnelStateInfo);
88
89         // This will be only tunnel If so not required
90         // If this interface is a tunnel interface, create the tunnel ingress flow,
91         // Egress flow for table 95 is installed based on dstId of the remote dpn,
92         // and start tunnel monitoring
93         if (stateTnl != null) {
94             return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(Datastore.CONFIGURATION,
95                 tx -> {
96                     Uint64 dpId = DirectTunnelUtils.getDpnFromNodeConnectorId(nodeConnectorId);
97                     directTunnelUtils.addTunnelIngressFlow(tx, dpId, portNo, interfaceName,
98                         stateTnl.getIfIndex().toJava(),
99                         tunnelStateInfo.getDstDpnTepsInfo().getTunnelEndPoints().get(0).getIpAddress()
100                             .getIpv4Address());
101                     directTunnelUtils.addTunnelEgressFlow(tx, dpId, String.valueOf(portNo),
102                         tunnelStateInfo.getDstDpnTepsInfo().getDstId(), interfaceName,
103                         tunnelStateInfo.getDstDpnTepsInfo().getTunnelEndPoints().get(0).getIpAddress());
104                 }));
105         }
106         return Collections.emptyList();
107     }
108
109     private StateTunnelList addStateEntry(String interfaceName, long portNo, TunnelStateInfo tunnelStateInfo)
110             throws ExecutionException, InterruptedException, OperationFailedException {
111         LOG.debug("Start addStateEntry adding interface state for {}", interfaceName);
112         final StateTunnelListBuilder stlBuilder = new StateTunnelListBuilder();
113         Class<? extends TunnelTypeBase> tunnelType;
114         DPNTEPsInfo srcDpnTepsInfo = tunnelStateInfo.getSrcDpnTepsInfo();
115
116         DpnTepInterfaceInfo dpnTepInfo = tunnelStateInfo.getDpnTepInterfaceInfo();
117         LOG.debug("Source Dpn TEP Interface Info {}", dpnTepInfo);
118         tunnelType = dpnTepInfo.getTunnelType();
119
120         final SrcInfoBuilder srcInfoBuilder =
121                 new SrcInfoBuilder().setTepDeviceId(tunnelStateInfo.getTunnelEndPointInfo().getSrcEndPointInfo());
122         final DstInfoBuilder dstInfoBuilder =
123                 new DstInfoBuilder().setTepDeviceId(tunnelStateInfo.getTunnelEndPointInfo().getDstEndPointInfo());
124         LOG.trace("Source Dpn TEP Info {}",srcDpnTepsInfo);
125         TunnelEndPoints srcEndPtInfo = srcDpnTepsInfo.getTunnelEndPoints().get(0);
126         srcInfoBuilder.setTepIp(srcEndPtInfo.getIpAddress());
127         // As ITM Direct Tunnels deals with only Internal Tunnels.
128         // Relook at this when it deals with external as well
129         srcInfoBuilder.setTepDeviceType(TepTypeInternal.class);
130
131         DPNTEPsInfo dstDpnTePsInfo = tunnelStateInfo.getDstDpnTepsInfo();
132         LOG.trace("Dest Dpn TEP Info {}", dstDpnTePsInfo);
133         TunnelEndPoints dstEndPtInfo = dstDpnTePsInfo.getTunnelEndPoints().get(0);
134         dstInfoBuilder.setTepIp(dstEndPtInfo.getIpAddress());
135         // As ITM Direct Tunnels deals with only Internal Tunnels.
136         // Relook at this when it deals with external as well
137         dstInfoBuilder.setTepDeviceType(TepTypeInternal.class);
138
139         Interface.OperStatus operStatus = Interface.OperStatus.Up;
140
141         // ITM Direct Tunnels NOT SETTING THE TEP TYPe coz its not available. CHECK IF REQUIRED
142         TunnelOperStatus tunnelOperStatus = DirectTunnelUtils.convertInterfaceToTunnelOperState(operStatus);
143         boolean tunnelState = operStatus.equals(Interface.OperStatus.Up);
144
145         StateTunnelListKey tlKey = new StateTunnelListKey(interfaceName);
146         stlBuilder.withKey(tlKey).setOperState(tunnelOperStatus).setTunnelState(tunnelState)
147         .setDstInfo(dstInfoBuilder.build()).setSrcInfo(srcInfoBuilder.build()).setTransportType(tunnelType)
148         .setPortNumber(String.valueOf(portNo));
149         int ifIndex = directTunnelUtils.allocateId(IfmConstants.IFM_IDPOOL_NAME, interfaceName);
150         createLportTagInterfaceMap(interfaceName, ifIndex);
151         stlBuilder.setIfIndex(ifIndex);
152         InstanceIdentifier<StateTunnelList> stListId = ItmUtils.buildStateTunnelListId(tlKey);
153         LOG.info("Batching the Creation of tunnel_state: {} for Id: {}", stlBuilder.build(), stListId);
154         ITMBatchingUtils.write(stListId, stlBuilder.build(), ITMBatchingUtils.EntityType.DEFAULT_OPERATIONAL);
155         return stlBuilder.build();
156     }
157
158     private void createLportTagInterfaceMap(String infName, Integer ifIndex) {
159         LOG.debug("creating lport tag to interface map for {}", infName);
160         InstanceIdentifier<IfIndexTunnel> id = InstanceIdentifier.builder(IfIndexesTunnelMap.class)
161                 .child(IfIndexTunnel.class, new IfIndexTunnelKey(ifIndex)).build();
162         IfIndexTunnel ifIndexInterface = new IfIndexTunnelBuilder().setIfIndex(ifIndex)
163             .withKey(new IfIndexTunnelKey(ifIndex)).setInterfaceName(infName).build();
164         ITMBatchingUtils.write(id, ifIndexInterface, ITMBatchingUtils.EntityType.DEFAULT_OPERATIONAL);
165     }
166 }