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