MDSAL-API Migration
[genius.git] / itm / itm-impl / src / main / java / org / opendaylight / genius / itm / cache / DPNTEPsInfoCache.java
1 /*
2  * Copyright (c) 2017 Inocybe Technologies 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.cache;
9
10 import java.util.ArrayList;
11 import java.util.Collection;
12 import java.util.List;
13 import java.util.Optional;
14 import javax.inject.Inject;
15 import javax.inject.Singleton;
16 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
17 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
18 import org.opendaylight.genius.itm.globals.ITMConstants;
19 import org.opendaylight.genius.itm.itmdirecttunnels.renderer.ovs.utilities.DirectTunnelUtils;
20 import org.opendaylight.genius.itm.itmdirecttunnels.workers.TunnelStateAddWorker;
21 import org.opendaylight.genius.itm.itmdirecttunnels.workers.TunnelStateAddWorkerForNodeConnector;
22 import org.opendaylight.genius.itm.utils.TunnelEndPointInfo;
23 import org.opendaylight.genius.itm.utils.TunnelStateInfo;
24 import org.opendaylight.genius.itm.utils.TunnelStateInfoBuilder;
25 import org.opendaylight.genius.mdsalutil.cache.InstanceIdDataObjectCache;
26 import org.opendaylight.infrautils.caches.CacheProvider;
27 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
28 import org.opendaylight.infrautils.utils.concurrent.NamedSimpleReentrantLock.Acquired;
29 import org.opendaylight.mdsal.binding.api.DataBroker;
30 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
33 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
34 import org.opendaylight.yangtools.yang.common.Uint64;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 /**
39  * Caches DPNTEPsInfo objects.
40  *
41  * @author Thomas Pantelis
42  */
43 @SuppressWarnings("checkstyle:AbbreviationAsWordInName")
44 @Singleton
45 public class DPNTEPsInfoCache extends InstanceIdDataObjectCache<DPNTEPsInfo> {
46
47     private static final Logger LOG = LoggerFactory.getLogger(DPNTEPsInfoCache.class);
48     private static final Logger EVENT_LOGGER = LoggerFactory.getLogger("GeniusEventLogger");
49
50     private final DirectTunnelUtils directTunnelUtils;
51     private final JobCoordinator coordinator;
52     private final UnprocessedNodeConnectorEndPointCache unprocessedNodeConnectorEndPointCache;
53     private final ManagedNewTransactionRunner txRunner;
54
55     @Inject
56     public DPNTEPsInfoCache(final DataBroker dataBroker, final CacheProvider cacheProvider,
57                             final DirectTunnelUtils directTunnelUtils, final JobCoordinator coordinator,
58                             final UnprocessedNodeConnectorEndPointCache unprocessedNodeConnectorEndPointCache) {
59         super(DPNTEPsInfo.class, dataBroker, LogicalDatastoreType.CONFIGURATION,
60                 InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class).build(), cacheProvider);
61         this.directTunnelUtils = directTunnelUtils;
62         this.coordinator = coordinator;
63         this.unprocessedNodeConnectorEndPointCache = unprocessedNodeConnectorEndPointCache;
64         this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
65     }
66
67     @Override
68     protected void added(InstanceIdentifier<DPNTEPsInfo> path, DPNTEPsInfo dpnTepsInfo) {
69         LOG.info("DPNTepsInfo Add Received for {}", dpnTepsInfo.getDPNID());
70         String dpnId = dpnTepsInfo.getDPNID().toString();
71
72         Collection<TunnelStateInfo> tunnelStateInfoList;
73         try (Acquired lock = directTunnelUtils.lockTunnel(dpnId)) {
74             tunnelStateInfoList = unprocessedNodeConnectorEndPointCache.remove(dpnId);
75         }
76
77         if (tunnelStateInfoList != null) {
78             for (TunnelStateInfo tsInfo : tunnelStateInfoList) {
79                 String interfaceName = tsInfo.getDpnTepInterfaceInfo().getTunnelName();
80                 DPNTEPsInfo srcDpnTepsInfo = null;
81                 DPNTEPsInfo dstDpnTepsInfo = null;
82                 LOG.debug("Processing the Unprocessed NodeConnector EndPoint Cache for DPN {}", dpnTepsInfo.getDPNID());
83                 TunnelEndPointInfo tunnelEndPointInfo = tsInfo.getTunnelEndPointInfo();
84                 if (dpnId.equals(tunnelEndPointInfo.getSrcEndPointInfo())) {
85                     srcDpnTepsInfo = dpnTepsInfo;
86                     dstDpnTepsInfo = tsInfo.getDstDpnTepsInfo();
87                     if (dstDpnTepsInfo == null) {
88                         // Check if the destination End Point has come
89                         try (Acquired lock = directTunnelUtils.lockTunnel(tunnelEndPointInfo.getDstEndPointInfo())) {
90                             Optional<DPNTEPsInfo> dstInfoOpt = getDPNTepFromDPNId(
91                                     Uint64.valueOf(tunnelEndPointInfo.getDstEndPointInfo()));
92                             if (dstInfoOpt.isPresent()) {
93                                 dstDpnTepsInfo = dstInfoOpt.get();
94                             } else {
95                                 TunnelStateInfo tunnelStateInfoNew = new TunnelStateInfoBuilder()
96                                     .setNodeConnectorInfo(tsInfo.getNodeConnectorInfo())
97                                     .setDpnTepInterfaceInfo(tsInfo.getDpnTepInterfaceInfo())
98                                     .setTunnelEndPointInfo(tsInfo.getTunnelEndPointInfo())
99                                     .setSrcDpnTepsInfo(srcDpnTepsInfo).build();
100                                 LOG.trace("Destination DPNTepsInfo is null for tunnel {}. Hence Parking with key {}",
101                                         interfaceName, tunnelEndPointInfo.getDstEndPointInfo());
102                                 unprocessedNodeConnectorEndPointCache.add(tunnelEndPointInfo
103                                         .getDstEndPointInfo(), tunnelStateInfoNew);
104                             }
105                         }
106                     }
107                 } else if (dpnId.equals(tunnelEndPointInfo.getDstEndPointInfo())) {
108                     dstDpnTepsInfo = dpnTepsInfo;
109                     srcDpnTepsInfo = tsInfo.getSrcDpnTepsInfo();
110                     // Check if the destination End Point has come
111                     if (srcDpnTepsInfo == null) {
112                         try (Acquired lock = directTunnelUtils.lockTunnel(tunnelEndPointInfo.getSrcEndPointInfo())) {
113                             Optional<DPNTEPsInfo> srcInfoOpt = getDPNTepFromDPNId(
114                                     Uint64.valueOf(tunnelEndPointInfo.getSrcEndPointInfo()));
115                             if (srcInfoOpt.isPresent()) {
116                                 srcDpnTepsInfo = srcInfoOpt.get();
117                             } else {
118                                 TunnelStateInfo tunnelStateInfoNew = new TunnelStateInfoBuilder().setNodeConnectorInfo(
119                                     tsInfo.getNodeConnectorInfo())
120                                     .setDpnTepInterfaceInfo(tsInfo.getDpnTepInterfaceInfo())
121                                     .setTunnelEndPointInfo(tsInfo.getTunnelEndPointInfo())
122                                     .setDstDpnTepsInfo(dstDpnTepsInfo).build();
123                                 LOG.trace("Source DPNTepsInfo is null for tunnel {}. Hence Parking with key {}",
124                                         interfaceName,
125                                         tsInfo.getTunnelEndPointInfo().getSrcEndPointInfo());
126                                 unprocessedNodeConnectorEndPointCache.add(tunnelEndPointInfo.getSrcEndPointInfo(),
127                                         tunnelStateInfoNew);
128                             }
129                         }
130                     }
131                 }
132
133                 if (srcDpnTepsInfo != null && dstDpnTepsInfo != null && directTunnelUtils.isEntityOwner()) {
134                     TunnelStateInfo tunnelStateInfoNew = new TunnelStateInfoBuilder()
135                         .setNodeConnectorInfo(tsInfo.getNodeConnectorInfo())
136                         .setDpnTepInterfaceInfo(tsInfo.getDpnTepInterfaceInfo())
137                         .setTunnelEndPointInfo(tsInfo.getTunnelEndPointInfo())
138                         .setSrcDpnTepsInfo(srcDpnTepsInfo).setDstDpnTepsInfo(dstDpnTepsInfo).build();
139                     LOG.debug("Queueing TunnelStateAddWorker to DJC for tunnel {}", interfaceName);
140                     EVENT_LOGGER.debug("ITM-DpnTepsInfoCache,ADD {}", interfaceName);
141                     coordinator.enqueueJob(interfaceName,
142                         new TunnelStateAddWorkerForNodeConnector(new TunnelStateAddWorker(directTunnelUtils, txRunner),
143                             tunnelStateInfoNew), ITMConstants.JOB_MAX_RETRIES);
144                 }
145             }
146         }
147     }
148
149     public List<DPNTEPsInfo> getDPNTepListFromDPNId(List<Uint64> dpnIds) {
150         Collection<DPNTEPsInfo> meshedDpnList = this.getAllPresent() ;
151         List<DPNTEPsInfo> cfgDpnList = new ArrayList<>();
152         for (Uint64 dpnId : dpnIds) {
153             for (DPNTEPsInfo teps : meshedDpnList) {
154                 if (dpnId.equals(teps.getDPNID())) {
155                     cfgDpnList.add(teps);
156                 }
157             }
158         }
159         return cfgDpnList;
160     }
161
162     public Optional<DPNTEPsInfo> getDPNTepFromDPNId(Uint64 dpnId) {
163         Collection<DPNTEPsInfo> meshedDpnList = this.getAllPresent() ;
164         return meshedDpnList.stream().filter(info -> dpnId.equals(info.getDPNID())).findFirst();
165     }
166 }