afaebfdef1c9d58822e37ccb48c597445053bf73
[netvirt.git] /
1 /*
2  * Copyright (c) 2016 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.api.intervpnlink;
10
11 import java.util.concurrent.ConcurrentHashMap;
12
13 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
14 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
15 import org.opendaylight.genius.utils.cache.CacheUtil;
16 import org.opendaylight.genius.mdsalutil.MDSALUtil;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.InterVpnLinkStates;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.InterVpnLinks;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.link.states.InterVpnLinkState;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.links.InterVpnLink;
21 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24
25 import com.google.common.base.Optional;
26
27 /**
28  * Manages some utility caches in order to speed (avoid) reads from MD-SAL.
29  * InterVpnLink is something that rarely changes and is frequently queried.
30  *
31  *
32  */
33 public class InterVpnLinkCache {
34
35     // Cache that maps endpoints with their respective InterVpnLinkComposite
36     public static final String ENDPOINT_2_IVPNLINK_CACHE_NAME = "EndpointToInterVpnLinkCache";
37
38     // Cache that maps Vpn UUIDs with their respective InterVpnLinkComposite
39     public static final String UUID_2_IVPNLINK_CACHE_NAME = "UuidToInterVpnLinkCache";
40
41     // It maps InterVpnLink names with their corresponding InterVpnLinkComposite.
42     public static final String IVPNLINK_NAME_2_IVPNLINK_CACHE_NAME = "NameToInterVpnLinkCache";
43
44     private static final Logger LOG = LoggerFactory.getLogger(InterVpnLinkCache.class);
45
46     ///////////////////////////////////
47     //  Initialization / Destruction  //
48     ///////////////////////////////////
49
50     public static synchronized void createInterVpnLinkCaches(DataBroker dataBroker) {
51         boolean emptyCaches = true;
52         if (CacheUtil.getCache(ENDPOINT_2_IVPNLINK_CACHE_NAME) == null) {
53             CacheUtil.createCache(ENDPOINT_2_IVPNLINK_CACHE_NAME);
54         } else {
55             emptyCaches = false;
56         }
57
58         if (CacheUtil.getCache(UUID_2_IVPNLINK_CACHE_NAME) == null) {
59             CacheUtil.createCache(UUID_2_IVPNLINK_CACHE_NAME);
60         } else {
61             emptyCaches = false;
62         }
63
64         if (CacheUtil.getCache(IVPNLINK_NAME_2_IVPNLINK_CACHE_NAME) == null) {
65             CacheUtil.createCache(IVPNLINK_NAME_2_IVPNLINK_CACHE_NAME);
66         } else {
67             emptyCaches = false;
68         }
69
70         if ( emptyCaches ) {
71             initialFeed(dataBroker);
72         }
73     }
74
75     public static synchronized void destroyCaches() {
76         if (CacheUtil.getCache(ENDPOINT_2_IVPNLINK_CACHE_NAME) != null) {
77             CacheUtil.destroyCache(ENDPOINT_2_IVPNLINK_CACHE_NAME);
78         }
79
80         if (CacheUtil.getCache(UUID_2_IVPNLINK_CACHE_NAME) != null) {
81             CacheUtil.destroyCache(UUID_2_IVPNLINK_CACHE_NAME);
82         }
83
84         if (CacheUtil.getCache(IVPNLINK_NAME_2_IVPNLINK_CACHE_NAME) != null) {
85             CacheUtil.destroyCache(IVPNLINK_NAME_2_IVPNLINK_CACHE_NAME);
86         }
87     }
88
89     /////////////////////
90     //      feeding    //
91     /////////////////////
92
93     private static void initialFeed(DataBroker broker) {
94         // Read all InterVpnLinks and InterVpnLinkStates from MD-SAL.
95         InstanceIdentifier<InterVpnLinks> interVpnLinksIid = InstanceIdentifier.builder(InterVpnLinks.class).build();
96
97         Optional<InterVpnLinks> optIVpnLinksOpData =
98             MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, interVpnLinksIid);
99
100         if ( !optIVpnLinksOpData.isPresent() ) {
101             return; // Nothing to be added to cache
102         }
103         InterVpnLinks interVpnLinks = optIVpnLinksOpData.get();
104         for ( InterVpnLink iVpnLink : interVpnLinks.getInterVpnLink() ) {
105             addInterVpnLinkToCaches(iVpnLink);
106         }
107
108         // Now the States
109         InstanceIdentifier<InterVpnLinkStates> interVpnLinkStateIid =
110             InstanceIdentifier.builder(InterVpnLinkStates.class).build();
111
112         Optional<InterVpnLinkStates> optIVpnLinkStateOpData =
113             MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, interVpnLinkStateIid);
114         if ( !optIVpnLinkStateOpData.isPresent() ) {
115             return;
116         }
117         InterVpnLinkStates iVpnLinkStates = optIVpnLinkStateOpData.get();
118         for ( InterVpnLinkState iVpnLinkState : iVpnLinkStates.getInterVpnLinkState() ) {
119             addInterVpnLinkStateToCaches(iVpnLinkState);
120         }
121     }
122
123     public static void addInterVpnLinkToCaches(InterVpnLink iVpnLink) {
124
125         LOG.debug("Adding InterVpnLink {} with vpn1=[id={} endpoint={}] and vpn2=[id={}  endpoint={}] ]",
126                   iVpnLink.getName(), iVpnLink.getFirstEndpoint().getVpnUuid(),
127                   iVpnLink.getFirstEndpoint().getIpAddress(), iVpnLink.getSecondEndpoint().getVpnUuid(),
128                   iVpnLink.getSecondEndpoint().getIpAddress());
129
130         InterVpnLinkDataComposite iVpnLinkComposite;
131
132         Optional<InterVpnLinkDataComposite> optIVpnLinkComposite =
133             getInterVpnLinkByName(iVpnLink.getName());
134
135         if ( optIVpnLinkComposite.isPresent() ) {
136             iVpnLinkComposite = optIVpnLinkComposite.get();
137             iVpnLinkComposite.setInterVpnLinkConfig(iVpnLink);
138         } else {
139             iVpnLinkComposite = new InterVpnLinkDataComposite(iVpnLink);
140             addToIVpnLinkNameCache(iVpnLinkComposite);
141         }
142
143         addToEndpointCache(iVpnLinkComposite);
144         addToVpnUuidCache(iVpnLinkComposite);
145     }
146
147
148     public static void addInterVpnLinkStateToCaches(InterVpnLinkState iVpnLinkState) {
149
150         LOG.debug("Adding InterVpnLinkState {} with vpn1=[{}]  and vpn2=[{}]",
151                   iVpnLinkState.getInterVpnLinkName(), iVpnLinkState.getFirstEndpointState(),
152                   iVpnLinkState.getSecondEndpointState());
153
154         Optional<InterVpnLinkDataComposite> optIVpnLink = getInterVpnLinkByName(iVpnLinkState.getInterVpnLinkName());
155
156         InterVpnLinkDataComposite iVpnLink;
157         if ( optIVpnLink.isPresent() ) {
158             iVpnLink = optIVpnLink.get();
159             iVpnLink.setInterVpnLinkState(iVpnLinkState);
160         } else {
161             iVpnLink = new InterVpnLinkDataComposite(iVpnLinkState);
162             addToIVpnLinkNameCache(iVpnLink);
163         }
164
165         addToEndpointCache(iVpnLink);
166         addToVpnUuidCache(iVpnLink);
167     }
168
169     private static void addToEndpointCache(InterVpnLinkDataComposite iVpnLink) {
170         ConcurrentHashMap<String, InterVpnLinkDataComposite> cache =
171             (ConcurrentHashMap<String, InterVpnLinkDataComposite>) CacheUtil.getCache(ENDPOINT_2_IVPNLINK_CACHE_NAME);
172         if ( iVpnLink.getFirstEndpointIpAddr().isPresent() ) {
173             cache.put(iVpnLink.getFirstEndpointIpAddr().get(), iVpnLink);
174         }
175         if ( iVpnLink.getSecondEndpointIpAddr().isPresent() ) {
176             cache.put(iVpnLink.getSecondEndpointIpAddr().get(), iVpnLink);
177         }
178     }
179
180     private static void addToVpnUuidCache(InterVpnLinkDataComposite iVpnLink) {
181         ConcurrentHashMap<String, InterVpnLinkDataComposite> cache =
182             (ConcurrentHashMap<String, InterVpnLinkDataComposite>) CacheUtil.getCache(UUID_2_IVPNLINK_CACHE_NAME);
183         if ( iVpnLink.getFirstEndpointVpnUuid().isPresent() ) {
184             cache.put(iVpnLink.getFirstEndpointVpnUuid().get(), iVpnLink);
185         }
186         if ( iVpnLink.getSecondEndpointVpnUuid().isPresent() ) {
187             cache.put(iVpnLink.getSecondEndpointVpnUuid().get(), iVpnLink);
188         }
189     }
190
191     private static void addToIVpnLinkNameCache(InterVpnLinkDataComposite iVpnLink) {
192         ConcurrentHashMap<String, InterVpnLinkDataComposite> cache =
193             (ConcurrentHashMap<String, InterVpnLinkDataComposite>) CacheUtil.getCache(IVPNLINK_NAME_2_IVPNLINK_CACHE_NAME);
194         cache.put(iVpnLink.getInterVpnLinkName(), iVpnLink);
195         if ( iVpnLink.getSecondEndpointIpAddr().isPresent() ) {
196             cache.put(iVpnLink.getSecondEndpointIpAddr().get(), iVpnLink);
197         }
198     }
199
200     public static void removeInterVpnLinkFromCache(InterVpnLink iVpnLink) {
201         ConcurrentHashMap<String, InterVpnLink> cache =
202             (ConcurrentHashMap<String, InterVpnLink>) CacheUtil.getCache(ENDPOINT_2_IVPNLINK_CACHE_NAME);
203         cache.remove(iVpnLink.getFirstEndpoint().getIpAddress().getValue());
204         cache.remove(iVpnLink.getSecondEndpoint().getIpAddress().getValue());
205
206         ConcurrentHashMap<String, InterVpnLink> cache2 =
207             (ConcurrentHashMap<String, InterVpnLink>) CacheUtil.getCache(UUID_2_IVPNLINK_CACHE_NAME);
208         cache2.remove(iVpnLink.getFirstEndpoint().getVpnUuid().getValue());
209         cache2.remove(iVpnLink.getSecondEndpoint().getVpnUuid().getValue());
210     }
211
212
213     public static void removeInterVpnLinkStateFromCache(InterVpnLinkState iVpnLinkState) {
214         Optional<InterVpnLinkDataComposite> optIVpnLinkComposite =
215             getInterVpnLinkByName(iVpnLinkState.getInterVpnLinkName());
216
217         if ( optIVpnLinkComposite.isPresent() ) {
218             InterVpnLinkDataComposite iVpnLinkComposite = optIVpnLinkComposite.get();
219             removeFromEndpointIpAddressCache(iVpnLinkComposite);
220             removeFromVpnUuidCache(iVpnLinkComposite);
221             removeFromInterVpnLinkNameCache(iVpnLinkComposite);
222         }
223     }
224
225     private static void removeFromInterVpnLinkNameCache(InterVpnLinkDataComposite iVpnLinkComposite) {
226         ConcurrentHashMap<String, InterVpnLinkDataComposite> cache =
227             (ConcurrentHashMap<String, InterVpnLinkDataComposite>) CacheUtil.getCache(IVPNLINK_NAME_2_IVPNLINK_CACHE_NAME);
228         cache.remove(iVpnLinkComposite.getInterVpnLinkName());
229     }
230
231
232     private static void removeFromVpnUuidCache(InterVpnLinkDataComposite iVpnLinkComposite) {
233         ConcurrentHashMap<String, InterVpnLink> cache =
234             (ConcurrentHashMap<String, InterVpnLink>) CacheUtil.getCache(UUID_2_IVPNLINK_CACHE_NAME);
235         Optional<String> opt1stEndpointUuid = iVpnLinkComposite.getFirstEndpointVpnUuid();
236         if ( opt1stEndpointUuid.isPresent() ) {
237             cache.remove(opt1stEndpointUuid.get());
238         }
239         Optional<String> opt2ndEndpointUuid = iVpnLinkComposite.getSecondEndpointVpnUuid();
240         cache.remove(opt2ndEndpointUuid.get());
241     }
242
243
244     private static void removeFromEndpointIpAddressCache(InterVpnLinkDataComposite iVpnLinkComposite) {
245         ConcurrentHashMap<String, InterVpnLink> cache =
246             (ConcurrentHashMap<String, InterVpnLink>) CacheUtil.getCache(ENDPOINT_2_IVPNLINK_CACHE_NAME);
247         Optional<String> opt1stEndpointIpAddr = iVpnLinkComposite.getFirstEndpointIpAddr();
248         if ( opt1stEndpointIpAddr.isPresent() ) {
249             cache.remove(opt1stEndpointIpAddr.get());
250         }
251         Optional<String> opt2ndEndpointIpAddr = iVpnLinkComposite.getSecondEndpointIpAddr();
252         cache.remove(opt2ndEndpointIpAddr.get());
253     }
254
255
256     /////////////////////
257     //  Cache Usage    //
258     /////////////////////
259
260     public static Optional<InterVpnLinkDataComposite> getInterVpnLinkByName(String iVpnLinkName) {
261         ConcurrentHashMap<String, InterVpnLinkDataComposite> cache =
262             (ConcurrentHashMap<String, InterVpnLinkDataComposite>) CacheUtil.getCache(IVPNLINK_NAME_2_IVPNLINK_CACHE_NAME);
263         InterVpnLinkDataComposite iVpnLink = cache.get(iVpnLinkName);
264         return (iVpnLink == null) ? Optional.<InterVpnLinkDataComposite>absent() : Optional.of(iVpnLink);
265     }
266
267     public static Optional<InterVpnLinkDataComposite> getInterVpnLinkByEndpoint(String endpointIp) {
268         LOG.trace("Checking if {} is configured as an InterVpnLink endpoint", endpointIp);
269         ConcurrentHashMap<String, InterVpnLinkDataComposite> cache =
270             (ConcurrentHashMap<String, InterVpnLinkDataComposite>) CacheUtil.getCache(ENDPOINT_2_IVPNLINK_CACHE_NAME);
271         InterVpnLinkDataComposite iVpnLink = cache.get(endpointIp);
272         LOG.trace("_XX IP {} is configured for InterVpnLink {}", endpointIp, iVpnLink);
273         return (iVpnLink == null) ? Optional.<InterVpnLinkDataComposite>absent() : Optional.of(iVpnLink);
274     }
275
276     public static Optional<InterVpnLinkDataComposite> getInterVpnLinkByVpnId(String vpnId) {
277         ConcurrentHashMap<String, InterVpnLinkDataComposite> cache2 =
278             (ConcurrentHashMap<String, InterVpnLinkDataComposite>) CacheUtil.getCache(UUID_2_IVPNLINK_CACHE_NAME);
279         InterVpnLinkDataComposite iVpnLink = cache2.get(vpnId);
280         return (iVpnLink == null) ? Optional.<InterVpnLinkDataComposite>absent() : Optional.of(iVpnLink);
281     }
282
283 }