blob: 7645c2e335eb09b649fae4712045c70e1d89dd04 [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;
21import org.apache.felix.scr.annotations.Activate;
22import org.apache.felix.scr.annotations.Component;
23import org.apache.felix.scr.annotations.Deactivate;
24import org.apache.felix.scr.annotations.Reference;
25import org.apache.felix.scr.annotations.ReferenceCardinality;
26import org.apache.felix.scr.annotations.Service;
27import org.onlab.util.KryoNamespace;
28import org.onosproject.core.CoreService;
29import org.onosproject.evpnopenflow.rsc.DefaultVpnAfConfig;
30import org.onosproject.evpnopenflow.rsc.VpnAfConfig;
31import org.onosproject.evpnopenflow.rsc.vpnafconfig.VpnAfConfigEvent;
32import org.onosproject.evpnopenflow.rsc.vpnafconfig.VpnAfConfigListener;
33import org.onosproject.evpnopenflow.rsc.vpnafconfig.VpnAfConfigService;
Ray Milkeya95193c2017-08-10 15:35:36 -070034import org.onosproject.evpnrouteservice.VpnRouteTarget;
Mohammad Shahid4c30ea32017-08-09 18:02:10 +053035import org.onosproject.store.serializers.KryoNamespaces;
36import org.onosproject.store.service.EventuallyConsistentMap;
37import org.onosproject.store.service.StorageService;
38import org.onosproject.store.service.WallClockTimestamp;
39import org.slf4j.Logger;
40import org.slf4j.LoggerFactory;
41
42import java.util.Collection;
43import java.util.Collections;
44import java.util.HashMap;
45import java.util.Map;
46import java.util.Set;
47
48import static com.google.common.base.Preconditions.checkNotNull;
49import static org.onosproject.evpnopenflow.rsc.EvpnConstants.APP_ID;
50import static org.onosproject.evpnopenflow.rsc.EvpnConstants.DELETE;
51import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVENT_NOT_NULL;
52import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVPN_VPN_AF_CONFIG_START;
53import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EVPN_VPN_AF_CONFIG_STOP;
54import static org.onosproject.evpnopenflow.rsc.EvpnConstants.EXPORT_ROUTE_POLICY;
55import static org.onosproject.evpnopenflow.rsc.EvpnConstants.IMPORT_ROUTE_POLICY;
56import static org.onosproject.evpnopenflow.rsc.EvpnConstants.INVALID_ACTION_VPN_AF_CONFIG;
57import static org.onosproject.evpnopenflow.rsc.EvpnConstants.JSON_NOT_NULL;
58import static org.onosproject.evpnopenflow.rsc.EvpnConstants.LISTENER_NOT_NULL;
59import static org.onosproject.evpnopenflow.rsc.EvpnConstants.RESPONSE_NOT_NULL;
60import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ROUTE_TARGET_CANNOT_NOT_NULL;
61import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ROUTE_TARGET_DELETE_FAILED;
62import static org.onosproject.evpnopenflow.rsc.EvpnConstants.ROUTE_TARGET_VALUE;
63import static org.onosproject.evpnopenflow.rsc.EvpnConstants.SET;
64import static org.onosproject.evpnopenflow.rsc.EvpnConstants.SLASH;
65import static org.onosproject.evpnopenflow.rsc.EvpnConstants.UPDATE;
66import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_AF_CONFIG_CREATION_FAILED;
67import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_AF_CONFIG_IS_NOT_EXIST;
68import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_AF_CONFIG_NOT_NULL;
69import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_AF_CONFIG_STORE;
70import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_AF_CONFIG_UPDATE_FAILED;
71import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VPN_INSTANCE_ID_NOT_NULL;
72import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VRF_RT_TYPE;
73import static org.onosproject.evpnopenflow.rsc.EvpnConstants.VRF_RT_VALUE;
74
75/**
76 * Provides implementation of the VPN af config APIs.
77 */
78@Component(immediate = true)
79@Service
80public class VpnAfConfigManager implements VpnAfConfigService {
81 private final Logger log = LoggerFactory.getLogger(getClass());
82 private final Set<VpnAfConfigListener> listeners = Sets
83 .newCopyOnWriteArraySet();
84
85 protected EventuallyConsistentMap<VpnRouteTarget, VpnAfConfig>
86 vpnAfConfigStore;
87 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
88 protected StorageService storageService;
89
90 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
91 protected CoreService coreService;
92
93 @Activate
94 public void activate() {
95 coreService.registerApplication(APP_ID);
96 KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
97 .register(KryoNamespaces.API).register(VpnAfConfig.class)
98 .register(VpnRouteTarget.class);
99 vpnAfConfigStore = storageService
100 .<VpnRouteTarget, VpnAfConfig>eventuallyConsistentMapBuilder()
101 .withName(VPN_AF_CONFIG_STORE).withSerializer(serializer)
102 .withTimestampProvider((k, v) -> new WallClockTimestamp())
103 .build();
104 log.info(EVPN_VPN_AF_CONFIG_START);
105 }
106
107 @Deactivate
108 public void deactivate() {
109 vpnAfConfigStore.destroy();
110 log.info(EVPN_VPN_AF_CONFIG_STOP);
111 }
112
113 @Override
114 public boolean exists(VpnRouteTarget routeTarget) {
115 checkNotNull(routeTarget, ROUTE_TARGET_CANNOT_NOT_NULL);
116 return vpnAfConfigStore.containsKey(routeTarget);
117 }
118
119 @Override
120 public VpnAfConfig getVpnAfConfig(VpnRouteTarget routeTarget) {
121 checkNotNull(routeTarget, ROUTE_TARGET_CANNOT_NOT_NULL);
122 return vpnAfConfigStore.get(routeTarget);
123 }
124
125 @Override
126 public Collection<VpnAfConfig> getVpnAfConfigs() {
127 return Collections.unmodifiableCollection(vpnAfConfigStore.values());
128 }
129
130 @Override
131 public boolean createVpnAfConfigs(Iterable<VpnAfConfig> vpnAfConfigs) {
132 checkNotNull(vpnAfConfigs, VPN_AF_CONFIG_NOT_NULL);
133 for (VpnAfConfig vpnAfConfig : vpnAfConfigs) {
134 log.info(ROUTE_TARGET_VALUE, vpnAfConfig
135 .routeTarget().getRouteTarget());
136 vpnAfConfigStore.put(vpnAfConfig.routeTarget(), vpnAfConfig);
137 if (!vpnAfConfigStore.containsKey(vpnAfConfig.routeTarget())) {
138 log.info(VPN_AF_CONFIG_CREATION_FAILED,
139 vpnAfConfig.routeTarget().getRouteTarget());
140 return false;
141 }
142 notifyListeners(new VpnAfConfigEvent(VpnAfConfigEvent
143 .Type
144 .VPN_AF_CONFIG_SET,
145 vpnAfConfig));
146 }
147 return true;
148 }
149
150 @Override
151 public boolean updateVpnAfConfigs(Iterable<VpnAfConfig> vpnAfConfigs) {
152 checkNotNull(vpnAfConfigs, VPN_AF_CONFIG_NOT_NULL);
153 for (VpnAfConfig vpnAfConfig : vpnAfConfigs) {
154 if (!vpnAfConfigStore.containsKey(vpnAfConfig.routeTarget())) {
155 log.info(VPN_AF_CONFIG_IS_NOT_EXIST,
156 vpnAfConfig.routeTarget().getRouteTarget());
157 return false;
158 }
159 vpnAfConfigStore.put(vpnAfConfig.routeTarget(), vpnAfConfig);
160 if (!vpnAfConfig.equals(vpnAfConfigStore
161 .get(vpnAfConfig.routeTarget()))) {
162 log.info(VPN_AF_CONFIG_UPDATE_FAILED,
163 vpnAfConfig.routeTarget().getRouteTarget());
164 return false;
165 }
166 notifyListeners(new VpnAfConfigEvent(VpnAfConfigEvent
167 .Type
168 .VPN_AF_CONFIG_UPDATE,
169 vpnAfConfig));
170 }
171 return true;
172 }
173
174 @Override
175 public boolean removeVpnAfConfigs(Iterable<VpnRouteTarget> routeTargets) {
176 checkNotNull(routeTargets, VPN_INSTANCE_ID_NOT_NULL);
177 for (VpnRouteTarget routeTarget : routeTargets) {
178 VpnAfConfig vpnAfConfig = vpnAfConfigStore.get(routeTarget);
179 vpnAfConfigStore.remove(routeTarget);
180 if (vpnAfConfigStore.containsKey(routeTarget)) {
181 log.info(ROUTE_TARGET_DELETE_FAILED,
182 routeTarget.getRouteTarget());
183 return false;
184 }
185 notifyListeners(new VpnAfConfigEvent(VpnAfConfigEvent
186 .Type
187 .VPN_AF_CONFIG_DELETE,
188 vpnAfConfig));
189 }
190 return true;
191 }
192
193 @Override
194 public void processGluonConfig(String action, String key, JsonNode value) {
195 Collection<VpnAfConfig> vpnAfConfigs;
196 switch (action) {
197 case DELETE:
198 String[] list = key.split(SLASH);
199 VpnRouteTarget routeTarget = VpnRouteTarget
200 .routeTarget(list[list.length - 1]);
201 Set<VpnRouteTarget> routeTargets
202 = Sets.newHashSet(routeTarget);
203 removeVpnAfConfigs(routeTargets);
204 break;
205 case SET:
206 checkNotNull(value, RESPONSE_NOT_NULL);
207 vpnAfConfigs = changeJsonToSub(value);
208 createVpnAfConfigs(vpnAfConfigs);
209 break;
210 case UPDATE:
211 checkNotNull(value, RESPONSE_NOT_NULL);
212 vpnAfConfigs = changeJsonToSub(value);
213 updateVpnAfConfigs(vpnAfConfigs);
214 break;
215 default:
216 log.info(INVALID_ACTION_VPN_AF_CONFIG);
217 break;
218 }
219 }
220
221 /**
222 * Returns a collection of vpn af configuration.
223 *
224 * @param vpnAfConfigNode the vpn af configuration json node
225 * @return returns the collection of vpn af configuration
226 */
227 private Collection<VpnAfConfig> changeJsonToSub(JsonNode vpnAfConfigNode) {
228 checkNotNull(vpnAfConfigNode, JSON_NOT_NULL);
229 Map<VpnRouteTarget, VpnAfConfig> vpnAfConfigMap = new HashMap<>();
230 String exportRoutePolicy
231 = vpnAfConfigNode.get(EXPORT_ROUTE_POLICY).asText();
232 String importRoutePolicy
233 = vpnAfConfigNode.get(IMPORT_ROUTE_POLICY).asText();
234 String routeTargetType = vpnAfConfigNode.get(VRF_RT_TYPE).asText();
235 VpnRouteTarget routeTarget = VpnRouteTarget
236 .routeTarget(vpnAfConfigNode.get(VRF_RT_VALUE).asText());
237
238 VpnAfConfig vpnAfConfig = new DefaultVpnAfConfig(exportRoutePolicy,
239 importRoutePolicy,
240 routeTarget,
241 routeTargetType);
242 vpnAfConfigMap.put(routeTarget, vpnAfConfig);
243
244 return Collections.unmodifiableCollection(vpnAfConfigMap.values());
245 }
246
247 @Override
248 public void addListener(VpnAfConfigListener listener) {
249 checkNotNull(listener, LISTENER_NOT_NULL);
250 listeners.add(listener);
251 }
252
253 @Override
254 public void removeListener(VpnAfConfigListener listener) {
255 checkNotNull(listener, LISTENER_NOT_NULL);
256 listeners.remove(listener);
257 }
258
259 /**
260 * Notifies specify event to all listeners.
261 *
262 * @param event vpn af config event
263 */
264 private void notifyListeners(VpnAfConfigEvent event) {
265 checkNotNull(event, EVENT_NOT_NULL);
266 listeners.forEach(listener -> listener.event(event));
267 }
268}