MRI version bumpup for Aluminium
[netvirt.git] / vpnmanager / impl / src / main / java / org / opendaylight / netvirt / vpnmanager / intervpnlink / InterVpnLinkCacheImpl.java
1 /*
2  * Copyright © 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
9 package org.opendaylight.netvirt.vpnmanager.intervpnlink;
10
11 import com.google.common.collect.ImmutableList;
12 import java.util.List;
13 import java.util.Optional;
14 import java.util.concurrent.ConcurrentHashMap;
15 import java.util.concurrent.ConcurrentMap;
16 import java.util.concurrent.ExecutionException;
17 import javax.annotation.PostConstruct;
18 import javax.inject.Inject;
19 import javax.inject.Singleton;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
22 import org.opendaylight.mdsal.binding.api.DataBroker;
23 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
24 import org.opendaylight.netvirt.vpnmanager.api.intervpnlink.InterVpnLinkCache;
25 import org.opendaylight.netvirt.vpnmanager.api.intervpnlink.InterVpnLinkDataComposite;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.InterVpnLinkStates;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.InterVpnLinks;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.link.states.InterVpnLinkState;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.links.InterVpnLink;
30 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 /**
35  * Implementation of InterVpnLinkCache.
36  */
37 @Singleton
38 public class InterVpnLinkCacheImpl implements InterVpnLinkCache {
39     private static final Logger LOG = LoggerFactory.getLogger(InterVpnLinkCacheImpl.class);
40
41     // Cache that maps endpoints with their respective InterVpnLinkComposite
42     private final ConcurrentMap<String, InterVpnLinkDataComposite> endpointToInterVpnLinkCache =
43             new ConcurrentHashMap<>();
44
45     // Cache that maps Vpn UUIDs with their respective InterVpnLinkComposite
46     private final ConcurrentMap<String, InterVpnLinkDataComposite> uuidToInterVpnLinkCache =
47             new ConcurrentHashMap<>();
48
49     // Cache that maps InterVpnLink names with their corresponding InterVpnLinkComposite.
50     private final ConcurrentMap<String, InterVpnLinkDataComposite> nameToInterVpnLinkCache =
51             new ConcurrentHashMap<>();
52
53     private final DataBroker dataBroker;
54
55     @Inject
56     public InterVpnLinkCacheImpl(DataBroker dataBroker) {
57         this.dataBroker = dataBroker;
58     }
59
60     @PostConstruct
61     public void initialFeed() {
62         // Read all InterVpnLinks and InterVpnLinkStates from MD-SAL.
63         InstanceIdentifier<InterVpnLinks> interVpnLinksIid = InstanceIdentifier.builder(InterVpnLinks.class).build();
64         try {
65             Optional<InterVpnLinks> optIVpnLinksOpData = SingleTransactionDataBroker.syncReadOptional(dataBroker,
66                     LogicalDatastoreType.CONFIGURATION, interVpnLinksIid);
67             if (!optIVpnLinksOpData.isPresent()) {
68                 return; // Nothing to be added to cache
69             }
70             InterVpnLinks interVpnLinks = optIVpnLinksOpData.get();
71             for (InterVpnLink interVpnLink : interVpnLinks.nonnullInterVpnLink().values()) {
72                 addInterVpnLinkToCaches(interVpnLink);
73             }
74
75             // Now the States
76             InstanceIdentifier<InterVpnLinkStates> interVpnLinkStateIid =
77                     InstanceIdentifier.builder(InterVpnLinkStates.class).build();
78
79             Optional<InterVpnLinkStates> optIVpnLinkStateOpData =
80                     SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
81                             interVpnLinkStateIid);
82             if (!optIVpnLinkStateOpData.isPresent()) {
83                 return;
84             }
85             InterVpnLinkStates interVpnLinkStates = optIVpnLinkStateOpData.get();
86             for (InterVpnLinkState interVpnLinkState : interVpnLinkStates.nonnullInterVpnLinkState().values()) {
87                 addInterVpnLinkStateToCaches(interVpnLinkState);
88             }
89         } catch (ExecutionException | InterruptedException e) {
90             LOG.error("initialFeed: Exception while reading interVpnLink DS", e);
91         }
92     }
93
94     @Override
95     public void addInterVpnLinkToCaches(InterVpnLink interVpnLink) {
96
97         String ivlName = interVpnLink.getName();
98         LOG.debug("Adding InterVpnLink {} with vpn1=[id={} endpoint={}] and vpn2=[id={}  endpoint={}] ]",
99                   ivlName, interVpnLink.getFirstEndpoint().getVpnUuid(),
100                 interVpnLink.getFirstEndpoint().getIpAddress(), interVpnLink.getSecondEndpoint().getVpnUuid(),
101                 interVpnLink.getSecondEndpoint().getIpAddress());
102
103         InterVpnLinkDataComposite interVpnLinkDataComposite = getInterVpnLinkByName(ivlName).orElse(null);
104         if (interVpnLinkDataComposite != null) {
105             interVpnLinkDataComposite.setInterVpnLinkConfig(interVpnLink);
106         } else {
107             interVpnLinkDataComposite = new InterVpnLinkDataComposite(interVpnLink);
108             addToIVpnLinkNameCache(interVpnLinkDataComposite);
109         }
110
111         addToEndpointCache(interVpnLinkDataComposite);
112         addToVpnUuidCache(interVpnLinkDataComposite);
113     }
114
115     @Override
116     public void addInterVpnLinkStateToCaches(InterVpnLinkState interVpnLinkState) {
117
118         String ivlName = interVpnLinkState.getInterVpnLinkName();
119         LOG.debug("Adding InterVpnLinkState {} with vpn1=[{}]  and vpn2=[{}]",
120                   ivlName, interVpnLinkState.getFirstEndpointState(), interVpnLinkState.getSecondEndpointState());
121
122         InterVpnLinkDataComposite ivl = getInterVpnLinkByName(ivlName).orElse(null);
123         if (ivl != null) {
124             ivl.setInterVpnLinkState(interVpnLinkState);
125         } else {
126             ivl = new InterVpnLinkDataComposite(interVpnLinkState);
127             addToIVpnLinkNameCache(ivl);
128         }
129
130         addToEndpointCache(ivl);
131         addToVpnUuidCache(ivl);
132     }
133
134     private void addToEndpointCache(InterVpnLinkDataComposite interVpnLink) {
135         safePut(endpointToInterVpnLinkCache, interVpnLink.getFirstEndpointIpAddr().orElse(null), interVpnLink);
136         safePut(endpointToInterVpnLinkCache, interVpnLink.getSecondEndpointIpAddr().orElse(null), interVpnLink);
137     }
138
139     private void addToVpnUuidCache(InterVpnLinkDataComposite interVpnLink) {
140         safePut(uuidToInterVpnLinkCache, interVpnLink.getFirstEndpointVpnUuid().orElse(null), interVpnLink);
141         safePut(uuidToInterVpnLinkCache, interVpnLink.getSecondEndpointVpnUuid().orElse(null), interVpnLink);
142     }
143
144     private void addToIVpnLinkNameCache(InterVpnLinkDataComposite interVpnLink) {
145         safePut(nameToInterVpnLinkCache, interVpnLink.getInterVpnLinkName(), interVpnLink);
146     }
147
148     @Override
149     public void removeInterVpnLinkFromCache(InterVpnLink interVpnLink) {
150         safeRemove(endpointToInterVpnLinkCache, interVpnLink.getFirstEndpoint().getIpAddress().getValue());
151         safeRemove(endpointToInterVpnLinkCache, interVpnLink.getSecondEndpoint().getIpAddress().getValue());
152
153         safeRemove(uuidToInterVpnLinkCache, interVpnLink.getFirstEndpoint().getVpnUuid().getValue());
154         safeRemove(uuidToInterVpnLinkCache, interVpnLink.getSecondEndpoint().getVpnUuid().getValue());
155     }
156
157
158     @Override
159     public void removeInterVpnLinkStateFromCache(InterVpnLinkState interVpnLinkState) {
160         Optional<InterVpnLinkDataComposite> optIVpnLinkComposite =
161                 getInterVpnLinkByName(interVpnLinkState.getInterVpnLinkName());
162
163         if (optIVpnLinkComposite.isPresent()) {
164             InterVpnLinkDataComposite interVpnLinkComposite = optIVpnLinkComposite.get();
165             removeFromEndpointIpAddressCache(interVpnLinkComposite);
166             removeFromVpnUuidCache(interVpnLinkComposite);
167             removeFromInterVpnLinkNameCache(interVpnLinkComposite);
168         }
169     }
170
171     private void removeFromInterVpnLinkNameCache(InterVpnLinkDataComposite interVpnLinkComposite) {
172         safeRemove(nameToInterVpnLinkCache, interVpnLinkComposite.getInterVpnLinkName());
173     }
174
175
176     private void removeFromVpnUuidCache(InterVpnLinkDataComposite interVpnLinkComposite) {
177         safeRemove(uuidToInterVpnLinkCache, interVpnLinkComposite.getFirstEndpointVpnUuid().orElse(null));
178         safeRemove(uuidToInterVpnLinkCache, interVpnLinkComposite.getSecondEndpointVpnUuid().orElse(null));
179     }
180
181
182     private void removeFromEndpointIpAddressCache(InterVpnLinkDataComposite interVpnLinkComposite) {
183         safeRemove(endpointToInterVpnLinkCache, interVpnLinkComposite.getFirstEndpointIpAddr().orElse(null));
184         safeRemove(endpointToInterVpnLinkCache, interVpnLinkComposite.getSecondEndpointIpAddr().orElse(null));
185     }
186
187     @Override
188     public Optional<InterVpnLinkDataComposite> getInterVpnLinkByName(String interVpnLinkName) {
189         return Optional.ofNullable(safeGet(nameToInterVpnLinkCache, interVpnLinkName));
190     }
191
192     @Override
193     public Optional<InterVpnLinkDataComposite> getInterVpnLinkByEndpoint(String endpointIp) {
194         LOG.trace("Checking if {} is configured as an InterVpnLink endpoint", endpointIp);
195         return Optional.ofNullable(safeGet(endpointToInterVpnLinkCache, endpointIp));
196     }
197
198     @Override
199     public Optional<InterVpnLinkDataComposite> getInterVpnLinkByVpnId(String vpnId) {
200         return Optional.ofNullable(safeGet(uuidToInterVpnLinkCache, vpnId));
201     }
202
203     @Override
204     public List<InterVpnLinkDataComposite> getAllInterVpnLinks() {
205         return ImmutableList.copyOf(nameToInterVpnLinkCache.values());
206     }
207
208     private <T> void safeRemove(ConcurrentMap<T, ?> fromMap, @Nullable T key) {
209         if (key != null) {
210             fromMap.remove(key);
211         }
212     }
213
214     @Nullable
215     private <K, V> V safeGet(ConcurrentMap<K, V> fromMap, @Nullable K key) {
216         return key != null ? fromMap.get(key) : null;
217     }
218
219     private <K, V> void safePut(ConcurrentMap<K, V> toMap, @Nullable K key, V value) {
220         if (key != null) {
221             toMap.put(key, value);
222         }
223     }
224 }