blob: 7a04b65c91ac76706aa104db038c63cb0d20af92 [file] [log] [blame]
HIGUCHI Yuta1d7c9cb2016-01-20 18:22:36 -08001/*
2 * Copyright 2016 Open Networking Laboratory
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 */
16package org.onosproject.net.newresource.impl;
17
18import static com.google.common.base.Preconditions.checkArgument;
19import static com.google.common.base.Preconditions.checkNotNull;
HIGUCHI Yuta1d7c9cb2016-01-20 18:22:36 -080020import static org.slf4j.LoggerFactory.getLogger;
21
22import java.util.Set;
23import java.util.concurrent.ExecutorService;
24
25import org.onlab.util.Bandwidth;
26import org.onosproject.net.ConnectPoint;
27import org.onosproject.net.config.NetworkConfigEvent;
28import org.onosproject.net.config.NetworkConfigListener;
29import org.onosproject.net.config.NetworkConfigService;
30import org.onosproject.net.newresource.BandwidthCapacity;
31import org.onosproject.net.newresource.ResourceAdminService;
Sho SHIMIZU460b9722016-01-28 10:48:26 -080032import org.onosproject.net.newresource.Resources;
HIGUCHI Yuta1d7c9cb2016-01-20 18:22:36 -080033import org.slf4j.Logger;
34
35import com.google.common.annotations.Beta;
36import com.google.common.collect.ImmutableSet;
37
38// TODO Consider merging this with ResourceDeviceListener.
39/**
40 * Handler for NetworkConfiguration changes.
41 */
42@Beta
43final class ResourceNetworkConfigListener implements NetworkConfigListener {
44
45 /**
46 * Config classes relevant to this listener.
47 */
48 private static final Set<Class<?>> CONFIG_CLASSES = ImmutableSet.of(BandwidthCapacity.class);
49
50 private final Logger log = getLogger(getClass());
51
52 private final ResourceAdminService adminService;
53 private final NetworkConfigService cfgService;
54 private final ExecutorService executor;
55
56 /**
57 * Creates an instance of listener.
58 *
59 * @param adminService {@link ResourceAdminService}
60 * @param cfgService {@link NetworkConfigService}
61 * @param executor Executor to use.
62 */
63 ResourceNetworkConfigListener(ResourceAdminService adminService, NetworkConfigService cfgService,
64 ExecutorService executor) {
65 this.adminService = checkNotNull(adminService);
66 this.cfgService = checkNotNull(cfgService);
67 this.executor = checkNotNull(executor);
68 }
69
70 @Override
71 public boolean isRelevant(NetworkConfigEvent event) {
HIGUCHI Yuta86523892016-02-18 16:33:11 -080072 switch (event.type()) {
73 case CONFIG_ADDED:
74 case CONFIG_REMOVED:
75 case CONFIG_UPDATED:
76 return CONFIG_CLASSES.contains(event.configClass());
77
78 case CONFIG_REGISTERED:
79 case CONFIG_UNREGISTERED:
80 default:
81 return false;
82 }
HIGUCHI Yuta1d7c9cb2016-01-20 18:22:36 -080083 }
84
85 @Override
86 public void event(NetworkConfigEvent event) {
87 if (event.configClass() == BandwidthCapacity.class) {
88 executor.submit(() -> {
89 try {
90 handleBandwidthCapacity(event);
91 } catch (Exception e) {
92 log.error("Exception handling BandwidthCapacity", e);
93 }
94 });
95 }
96 }
97
98 private void handleBandwidthCapacity(NetworkConfigEvent event) {
99 checkArgument(event.configClass() == BandwidthCapacity.class);
100
101 ConnectPoint cp = (ConnectPoint) event.subject();
102 BandwidthCapacity bwCapacity = cfgService.getConfig(cp, BandwidthCapacity.class);
103
104 switch (event.type()) {
105 case CONFIG_ADDED:
Sho SHIMIZU7b326972016-02-09 15:53:39 -0800106 if (!adminService.register(Resources.continuous(cp.deviceId(),
Sho SHIMIZU460b9722016-01-28 10:48:26 -0800107 cp.port(), Bandwidth.class)
Sho SHIMIZUf95b96e2016-01-25 19:35:15 -0800108 .resource(bwCapacity.capacity().bps()))) {
HIGUCHI Yuta1d7c9cb2016-01-20 18:22:36 -0800109 log.info("Failed to register Bandwidth for {}, attempting update", cp);
110
111 // Bandwidth based on port speed, was probably already registered.
112 // need to update to the valued based on configuration
113
114 if (!updateRegistration(cp, bwCapacity)) {
115 log.warn("Failed to update Bandwidth for {}", cp);
116 }
117 }
118 break;
119
120 case CONFIG_UPDATED:
121 if (!updateRegistration(cp, bwCapacity)) {
122 log.warn("Failed to update Bandwidth for {}", cp);
123 }
124 break;
125
126 case CONFIG_REMOVED:
127 // FIXME Following should be an update to the value based on port speed
Sho SHIMIZU7b326972016-02-09 15:53:39 -0800128 if (!adminService.unregister(Resources.continuous(cp.deviceId(),
Sho SHIMIZU460b9722016-01-28 10:48:26 -0800129 cp.port(),
Sho SHIMIZU72f81b12016-02-09 09:26:17 -0800130 Bandwidth.class).id())) {
HIGUCHI Yuta1d7c9cb2016-01-20 18:22:36 -0800131 log.warn("Failed to unregister Bandwidth for {}", cp);
132 }
133 break;
134
135 case CONFIG_REGISTERED:
136 case CONFIG_UNREGISTERED:
137 // no-op
138 break;
139
140 default:
141 break;
142 }
143 }
144
145 private boolean updateRegistration(ConnectPoint cp, BandwidthCapacity bwCapacity) {
146 // FIXME workaround until replace/update semantics become available
147 // this potentially blows up existing registration
148 // or end up as no-op
149 //
150 // Current code end up in situation like below:
151 // PortNumber: 2
152 // MplsLabel: [[16‥240)]
153 // VlanId: [[0‥4095)]
154 // Bandwidth: 2000000.000000
155 // Bandwidth: 20000000.000000
156 //
157 // but both unregisterResources(..) and registerResources(..)
158 // returns true (success)
159
Sho SHIMIZU7b326972016-02-09 15:53:39 -0800160 if (!adminService.unregister(
Sho SHIMIZU72f81b12016-02-09 09:26:17 -0800161 Resources.continuous(cp.deviceId(), cp.port(), Bandwidth.class).id())) {
HIGUCHI Yuta1d7c9cb2016-01-20 18:22:36 -0800162 log.warn("unregisterResources for {} failed", cp);
163 }
Sho SHIMIZU7b326972016-02-09 15:53:39 -0800164 return adminService.register(Resources.continuous(cp.deviceId(),
Sho SHIMIZU460b9722016-01-28 10:48:26 -0800165 cp.port(),
166 Bandwidth.class).resource(bwCapacity.capacity().bps()));
HIGUCHI Yuta1d7c9cb2016-01-20 18:22:36 -0800167 }
168
169}