blob: a2ee02ca900db9de66e9cbc9e644fbbea3b8d6c3 [file] [log] [blame]
Mohammad Shahid4c30ea32017-08-09 18:02:10 +05301/*
2 * Copyright 2017-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.evpnopenflow.rsc.vpnafconfig.impl;
18
19import com.fasterxml.jackson.databind.JsonNode;
20import com.google.common.collect.Sets;
Mohammad Shahid4c30ea32017-08-09 18:02:10 +053021import org.onlab.util.KryoNamespace;
22import org.onosproject.core.CoreService;
23import org.onosproject.evpnopenflow.rsc.DefaultVpnAfConfig;
24import org.onosproject.evpnopenflow.rsc.VpnAfConfig;
25import org.onosproject.evpnopenflow.rsc.vpnafconfig.VpnAfConfigEvent;
26import org.onosproject.evpnopenflow.rsc.vpnafconfig.VpnAfConfigListener;
27import org.onosproject.evpnopenflow.rsc.vpnafconfig.VpnAfConfigService;
Ray Milkeya95193c2017-08-10 15:35:36 -070028import org.onosproject.evpnrouteservice.VpnRouteTarget;
Mohammad Shahid4c30ea32017-08-09 18:02:10 +053029import org.onosproject.store.serializers.KryoNamespaces;
30import org.onosproject.store.service.EventuallyConsistentMap;
31import org.onosproject.store.service.StorageService;
32import org.onosproject.store.service.WallClockTimestamp;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070033import org.osgi.service.component.annotations.Activate;
34import org.osgi.service.component.annotations.Component;
35import org.osgi.service.component.annotations.Deactivate;
36import org.osgi.service.component.annotations.Reference;
37import org.osgi.service.component.annotations.ReferenceCardinality;
Mohammad Shahid4c30ea32017-08-09 18:02:10 +053038import org.slf4j.Logger;
39import org.slf4j.LoggerFactory;
40
41import java.util.Collection;
42import java.util.Collections;
43import java.util.HashMap;
44import java.util.Map;
45import java.util.Set;
46
47import static com.google.common.base.Preconditions.checkNotNull;
48import static org.onosproject.evpnopenflow.rsc.EvpnConstants.APP_ID;
49import static org.onosproject.evpnopenflow.rsc.EvpnConstants.DELETE;
50import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVENT_NOT_NULL;
51import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVPN_VPN_AF_CONFIG_START;
52import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVPN_VPN_AF_CONFIG_STOP;
53import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EXPORT_ROUTE_POLICY;
54import static org.onosproject.evpnopenflow.rsc.EvpnConstants.IMPORT_ROUTE_POLICY;
55import static org.onosproject.evpnopenflow.rsc.EvpnConstants.INVALID_ACTION_VPN_AF_CONFIG;
56import static org.onosproject.evpnopenflow.rsc.EvpnConstants.JSON_NOT_NULL;
57import static org.onosproject.evpnopenflow.rsc.EvpnConstants.LISTENER_NOT_NULL;
58import static org.onosproject.evpnopenflow.rsc.EvpnConstants.RESPONSE_NOT_NULL;
59import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ROUTE_TARGET_CANNOT_NOT_NULL;
60import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ROUTE_TARGET_DELETE_FAILED;
61import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ROUTE_TARGET_VALUE;
62import static org.onosproject.evpnopenflow.rsc.EvpnConstants.SET;
63import static org.onosproject.evpnopenflow.rsc.EvpnConstants.SLASH;
64import static org.onosproject.evpnopenflow.rsc.EvpnConstants.UPDATE;
65import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_AF_CONFIG_CREATION_FAILED;
66import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_AF_CONFIG_IS_NOT_EXIST;
67import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_AF_CONFIG_NOT_NULL;
68import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_AF_CONFIG_STORE;
69import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_AF_CONFIG_UPDATE_FAILED;
70import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE_ID_NOT_NULL;
71import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VRF_RT_TYPE;
72import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VRF_RT_VALUE;
73
74/**
75 * Provides implementation of the VPN af config APIs.
76 */
Ray Milkeyd84f89b2018-08-17 14:54:17 -070077@Component(immediate = true, service = VpnAfConfigService.class)
Mohammad Shahid4c30ea32017-08-09 18:02:10 +053078public class VpnAfConfigManager implements VpnAfConfigService {
79 private final Logger log = LoggerFactory.getLogger(getClass());
80 private final Set<VpnAfConfigListener> listeners = Sets
81 .newCopyOnWriteArraySet();
82
83 protected EventuallyConsistentMap<VpnRouteTarget, VpnAfConfig>
84 vpnAfConfigStore;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070085 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Mohammad Shahid4c30ea32017-08-09 18:02:10 +053086 protected StorageService storageService;
87
Ray Milkeyd84f89b2018-08-17 14:54:17 -070088 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Mohammad Shahid4c30ea32017-08-09 18:02:10 +053089 protected CoreService coreService;
90
91 @Activate
92 public void activate() {
93 coreService.registerApplication(APP_ID);
94 KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
95 .register(KryoNamespaces.API).register(VpnAfConfig.class)
96 .register(VpnRouteTarget.class);
97 vpnAfConfigStore = storageService
98 .<VpnRouteTarget, VpnAfConfig>eventuallyConsistentMapBuilder()
99 .withName(VPN_AF_CONFIG_STORE).withSerializer(serializer)
100 .withTimestampProvider((k, v) -> new WallClockTimestamp())
101 .build();
102 log.info(EVPN_VPN_AF_CONFIG_START);
103 }
104
105 @Deactivate
106 public void deactivate() {
107 vpnAfConfigStore.destroy();
108 log.info(EVPN_VPN_AF_CONFIG_STOP);
109 }
110
111 @Override
112 public boolean exists(VpnRouteTarget routeTarget) {
113 checkNotNull(routeTarget, ROUTE_TARGET_CANNOT_NOT_NULL);
114 return vpnAfConfigStore.containsKey(routeTarget);
115 }
116
117 @Override
118 public VpnAfConfig getVpnAfConfig(VpnRouteTarget routeTarget) {
119 checkNotNull(routeTarget, ROUTE_TARGET_CANNOT_NOT_NULL);
120 return vpnAfConfigStore.get(routeTarget);
121 }
122
123 @Override
124 public Collection<VpnAfConfig> getVpnAfConfigs() {
125 return Collections.unmodifiableCollection(vpnAfConfigStore.values());
126 }
127
128 @Override
129 public boolean createVpnAfConfigs(Iterable<VpnAfConfig> vpnAfConfigs) {
130 checkNotNull(vpnAfConfigs, VPN_AF_CONFIG_NOT_NULL);
131 for (VpnAfConfig vpnAfConfig : vpnAfConfigs) {
132 log.info(ROUTE_TARGET_VALUE, vpnAfConfig
133 .routeTarget().getRouteTarget());
134 vpnAfConfigStore.put(vpnAfConfig.routeTarget(), vpnAfConfig);
135 if (!vpnAfConfigStore.containsKey(vpnAfConfig.routeTarget())) {
136 log.info(VPN_AF_CONFIG_CREATION_FAILED,
137 vpnAfConfig.routeTarget().getRouteTarget());
138 return false;
139 }
140 notifyListeners(new VpnAfConfigEvent(VpnAfConfigEvent
141 .Type
142 .VPN_AF_CONFIG_SET,
143 vpnAfConfig));
144 }
145 return true;
146 }
147
148 @Override
149 public boolean updateVpnAfConfigs(Iterable<VpnAfConfig> vpnAfConfigs) {
150 checkNotNull(vpnAfConfigs, VPN_AF_CONFIG_NOT_NULL);
151 for (VpnAfConfig vpnAfConfig : vpnAfConfigs) {
152 if (!vpnAfConfigStore.containsKey(vpnAfConfig.routeTarget())) {
153 log.info(VPN_AF_CONFIG_IS_NOT_EXIST,
154 vpnAfConfig.routeTarget().getRouteTarget());
155 return false;
156 }
157 vpnAfConfigStore.put(vpnAfConfig.routeTarget(), vpnAfConfig);
158 if (!vpnAfConfig.equals(vpnAfConfigStore
159 .get(vpnAfConfig.routeTarget()))) {
160 log.info(VPN_AF_CONFIG_UPDATE_FAILED,
161 vpnAfConfig.routeTarget().getRouteTarget());
162 return false;
163 }
164 notifyListeners(new VpnAfConfigEvent(VpnAfConfigEvent
165 .Type
166 .VPN_AF_CONFIG_UPDATE,
167 vpnAfConfig));
168 }
169 return true;
170 }
171
172 @Override
173 public boolean removeVpnAfConfigs(Iterable<VpnRouteTarget> routeTargets) {
174 checkNotNull(routeTargets, VPN_INSTANCE_ID_NOT_NULL);
175 for (VpnRouteTarget routeTarget : routeTargets) {
176 VpnAfConfig vpnAfConfig = vpnAfConfigStore.get(routeTarget);
177 vpnAfConfigStore.remove(routeTarget);
178 if (vpnAfConfigStore.containsKey(routeTarget)) {
179 log.info(ROUTE_TARGET_DELETE_FAILED,
180 routeTarget.getRouteTarget());
181 return false;
182 }
183 notifyListeners(new VpnAfConfigEvent(VpnAfConfigEvent
184 .Type
185 .VPN_AF_CONFIG_DELETE,
186 vpnAfConfig));
187 }
188 return true;
189 }
190
191 @Override
192 public void processGluonConfig(String action, String key, JsonNode value) {
193 Collection<VpnAfConfig> vpnAfConfigs;
194 switch (action) {
195 case DELETE:
196 String[] list = key.split(SLASH);
197 VpnRouteTarget routeTarget = VpnRouteTarget
198 .routeTarget(list[list.length - 1]);
199 Set<VpnRouteTarget> routeTargets
200 = Sets.newHashSet(routeTarget);
201 removeVpnAfConfigs(routeTargets);
202 break;
203 case SET:
204 checkNotNull(value, RESPONSE_NOT_NULL);
205 vpnAfConfigs = changeJsonToSub(value);
206 createVpnAfConfigs(vpnAfConfigs);
207 break;
208 case UPDATE:
209 checkNotNull(value, RESPONSE_NOT_NULL);
210 vpnAfConfigs = changeJsonToSub(value);
211 updateVpnAfConfigs(vpnAfConfigs);
212 break;
213 default:
214 log.info(INVALID_ACTION_VPN_AF_CONFIG);
215 break;
216 }
217 }
218
219 /**
220 * Returns a collection of vpn af configuration.
221 *
222 * @param vpnAfConfigNode the vpn af configuration json node
223 * @return returns the collection of vpn af configuration
224 */
225 private Collection<VpnAfConfig> changeJsonToSub(JsonNode vpnAfConfigNode) {
226 checkNotNull(vpnAfConfigNode, JSON_NOT_NULL);
227 Map<VpnRouteTarget, VpnAfConfig> vpnAfConfigMap = new HashMap<>();
228 String exportRoutePolicy
229 = vpnAfConfigNode.get(EXPORT_ROUTE_POLICY).asText();
230 String importRoutePolicy
231 = vpnAfConfigNode.get(IMPORT_ROUTE_POLICY).asText();
232 String routeTargetType = vpnAfConfigNode.get(VRF_RT_TYPE).asText();
233 VpnRouteTarget routeTarget = VpnRouteTarget
234 .routeTarget(vpnAfConfigNode.get(VRF_RT_VALUE).asText());
235
236 VpnAfConfig vpnAfConfig = new DefaultVpnAfConfig(exportRoutePolicy,
237 importRoutePolicy,
238 routeTarget,
239 routeTargetType);
240 vpnAfConfigMap.put(routeTarget, vpnAfConfig);
241
242 return Collections.unmodifiableCollection(vpnAfConfigMap.values());
243 }
244
245 @Override
246 public void addListener(VpnAfConfigListener listener) {
247 checkNotNull(listener, LISTENER_NOT_NULL);
248 listeners.add(listener);
249 }
250
251 @Override
252 public void removeListener(VpnAfConfigListener listener) {
253 checkNotNull(listener, LISTENER_NOT_NULL);
254 listeners.remove(listener);
255 }
256
257 /**
258 * Notifies specify event to all listeners.
259 *
260 * @param event vpn af config event
261 */
262 private void notifyListeners(VpnAfConfigEvent event) {
263 checkNotNull(event, EVENT_NOT_NULL);
264 listeners.forEach(listener -> listener.event(event));
265 }
266}