blob: 6d5fa9c37b078f8cd45eeb5fcd7638f2d464be20 [file] [log] [blame]
yoonseondc3210d2017-01-25 16:03:10 -08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
yoonseondc3210d2017-01-25 16:03:10 -08003 *
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.incubator.net.virtual.impl;
18
19import org.onosproject.core.ApplicationId;
20import org.onosproject.incubator.net.virtual.NetworkId;
21import org.onosproject.incubator.net.virtual.VirtualNetworkGroupStore;
22import org.onosproject.incubator.net.virtual.VirtualNetworkService;
23import org.onosproject.incubator.net.virtual.event.AbstractVirtualListenerManager;
24import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProviderService;
25import org.onosproject.incubator.net.virtual.provider.VirtualGroupProvider;
26import org.onosproject.incubator.net.virtual.provider.VirtualGroupProviderService;
27import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
28import org.onosproject.net.DeviceId;
29import org.onosproject.net.device.DeviceEvent;
30import org.onosproject.net.device.DeviceListener;
31import org.onosproject.net.device.DeviceService;
32import org.onosproject.net.group.Group;
33import org.onosproject.net.group.GroupBuckets;
34import org.onosproject.net.group.GroupDescription;
35import org.onosproject.net.group.GroupEvent;
36import org.onosproject.net.group.GroupKey;
37import org.onosproject.net.group.GroupListener;
38import org.onosproject.net.group.GroupOperation;
39import org.onosproject.net.group.GroupOperations;
40import org.onosproject.net.group.GroupService;
41import org.onosproject.net.group.GroupStoreDelegate;
42import org.onosproject.net.provider.ProviderId;
43import org.slf4j.Logger;
44import org.slf4j.LoggerFactory;
45
46import java.util.Collection;
47import java.util.Collections;
48import java.util.Set;
49
50/**
51 * Group service implementation built on the virtual network service.
52 */
53public class VirtualNetworkGroupManager
54 extends AbstractVirtualListenerManager<GroupEvent, GroupListener>
55 implements GroupService {
56
57 private final Logger log = LoggerFactory.getLogger(getClass());
58
59 private final VirtualNetworkGroupStore store;
60
61 private VirtualProviderRegistryService providerRegistryService = null;
62 private VirtualGroupProviderService innerProviderService;
63 private InternalStoreDelegate storeDelegate;
64 private DeviceService deviceService;
65
66 //TODO: make this configurable
67 private boolean purgeOnDisconnection = false;
68
69 public VirtualNetworkGroupManager(VirtualNetworkService manager, NetworkId networkId) {
Yoonseon Hanb14461b2017-03-07 14:08:01 +090070 super(manager, networkId, GroupEvent.class);
yoonseondc3210d2017-01-25 16:03:10 -080071
72 store = serviceDirectory.get(VirtualNetworkGroupStore.class);
73 deviceService = manager.get(networkId, DeviceService.class);
74
75 providerRegistryService =
76 serviceDirectory.get(VirtualProviderRegistryService.class);
77 innerProviderService = new InternalGroupProviderService();
78 providerRegistryService.registerProviderService(networkId(), innerProviderService);
79
80 this.storeDelegate = new InternalStoreDelegate();
81 store.setDelegate(networkId, this.storeDelegate);
82
83 log.info("Started");
84 }
85
86 @Override
87 public void addGroup(GroupDescription groupDesc) {
88 store.storeGroupDescription(networkId(), groupDesc);
89 }
90
91 @Override
92 public Group getGroup(DeviceId deviceId, GroupKey appCookie) {
93 return store.getGroup(networkId(), deviceId, appCookie);
94 }
95
96 @Override
97 public void addBucketsToGroup(DeviceId deviceId, GroupKey oldCookie, GroupBuckets buckets,
98 GroupKey newCookie, ApplicationId appId) {
99 store.updateGroupDescription(networkId(),
100 deviceId,
101 oldCookie,
102 VirtualNetworkGroupStore.UpdateType.ADD,
103 buckets,
104 newCookie);
105 }
106
107 @Override
108 public void removeBucketsFromGroup(DeviceId deviceId, GroupKey oldCookie,
109 GroupBuckets buckets, GroupKey newCookie,
110 ApplicationId appId) {
111 store.updateGroupDescription(networkId(),
112 deviceId,
113 oldCookie,
114 VirtualNetworkGroupStore.UpdateType.REMOVE,
115 buckets,
116 newCookie);
117
118 }
119
120 @Override
121 public void setBucketsForGroup(DeviceId deviceId,
122 GroupKey oldCookie,
123 GroupBuckets buckets,
124 GroupKey newCookie,
125 ApplicationId appId) {
126 store.updateGroupDescription(networkId(),
127 deviceId,
128 oldCookie,
129 VirtualNetworkGroupStore.UpdateType.SET,
130 buckets,
131 newCookie);
132 }
133
134 @Override
135 public void purgeGroupEntries(DeviceId deviceId) {
136 store.purgeGroupEntry(networkId(), deviceId);
137 }
138
139 @Override
140 public void purgeGroupEntries() {
141 store.purgeGroupEntries(networkId());
142 }
143
144 @Override
145 public void removeGroup(DeviceId deviceId, GroupKey appCookie, ApplicationId appId) {
146 store.deleteGroupDescription(networkId(), deviceId, appCookie);
147 }
148
149 @Override
150 public Iterable<Group> getGroups(DeviceId deviceId, ApplicationId appId) {
151 return store.getGroups(networkId(), deviceId);
152 }
153
154 @Override
155 public Iterable<Group> getGroups(DeviceId deviceId) {
156 return store.getGroups(networkId(), deviceId);
157 }
158
159 private class InternalGroupProviderService
160 extends AbstractVirtualProviderService<VirtualGroupProvider>
161 implements VirtualGroupProviderService {
162
163 protected InternalGroupProviderService() {
164 Set<ProviderId> providerIds =
165 providerRegistryService.getProvidersByService(this);
166 ProviderId providerId = providerIds.stream().findFirst().get();
167 VirtualGroupProvider provider = (VirtualGroupProvider)
168 providerRegistryService.getProvider(providerId);
169 setProvider(provider);
170 }
171
172 @Override
173 public void groupOperationFailed(DeviceId deviceId,
174 GroupOperation operation) {
175 store.groupOperationFailed(networkId(), deviceId, operation);
176 }
177
178 @Override
179 public void pushGroupMetrics(DeviceId deviceId, Collection<Group> groupEntries) {
180 log.trace("Received group metrics from device {}", deviceId);
181 checkValidity();
182 store.pushGroupMetrics(networkId(), deviceId, groupEntries);
183 }
184
185 @Override
186 public void notifyOfFailovers(Collection<Group> failoverGroups) {
187 store.notifyOfFailovers(networkId(), failoverGroups);
188 }
189 }
190
191 private class InternalStoreDelegate implements GroupStoreDelegate {
192 @Override
193 public void notify(GroupEvent event) {
194 final Group group = event.subject();
195 VirtualGroupProvider groupProvider = innerProviderService.provider();
196 GroupOperations groupOps = null;
197 switch (event.type()) {
198 case GROUP_ADD_REQUESTED:
199 log.debug("GROUP_ADD_REQUESTED for Group {} on device {}",
200 group.id(), group.deviceId());
201 GroupOperation groupAddOp = GroupOperation.
202 createAddGroupOperation(group.id(),
203 group.type(),
204 group.buckets());
205 groupOps = new GroupOperations(
206 Collections.singletonList(groupAddOp));
207 groupProvider.performGroupOperation(networkId(), group.deviceId(),
208 groupOps);
209 break;
210
211 case GROUP_UPDATE_REQUESTED:
212 log.debug("GROUP_UPDATE_REQUESTED for Group {} on device {}",
213 group.id(), group.deviceId());
214 GroupOperation groupModifyOp = GroupOperation.
215 createModifyGroupOperation(group.id(),
216 group.type(),
217 group.buckets());
218 groupOps = new GroupOperations(
219 Collections.singletonList(groupModifyOp));
220 groupProvider.performGroupOperation(networkId(), group.deviceId(),
221 groupOps);
222 break;
223
224 case GROUP_REMOVE_REQUESTED:
225 log.debug("GROUP_REMOVE_REQUESTED for Group {} on device {}",
226 group.id(), group.deviceId());
227 GroupOperation groupDeleteOp = GroupOperation.
228 createDeleteGroupOperation(group.id(),
229 group.type());
230 groupOps = new GroupOperations(
231 Collections.singletonList(groupDeleteOp));
232 groupProvider.performGroupOperation(networkId(), group.deviceId(),
233 groupOps);
234 break;
235
236 case GROUP_ADDED:
237 case GROUP_UPDATED:
238 case GROUP_REMOVED:
239 case GROUP_ADD_FAILED:
240 case GROUP_UPDATE_FAILED:
241 case GROUP_REMOVE_FAILED:
242 case GROUP_BUCKET_FAILOVER:
243 post(event);
244 break;
245 default:
246 break;
247 }
248 }
249 }
250
251 private class InternalDeviceListener implements DeviceListener {
252 @Override
253 public void event(DeviceEvent event) {
254 switch (event.type()) {
255 case DEVICE_REMOVED:
256 case DEVICE_AVAILABILITY_CHANGED:
257 DeviceId deviceId = event.subject().id();
258 if (!deviceService.isAvailable(deviceId)) {
259 log.debug("Device {} became un available; clearing initial audit status",
260 event.type(), event.subject().id());
261 store.deviceInitialAuditCompleted(networkId(), event.subject().id(), false);
262
263 if (purgeOnDisconnection) {
264 store.purgeGroupEntry(networkId(), deviceId);
265 }
266 }
267 break;
268 default:
269 break;
270 }
271 }
272 }
273}