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