blob: b8d373bc2b6dc79476c64f771ee56d273cd3058f [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;
20import static org.onosproject.net.newresource.Resource.continuous;
21import static org.slf4j.LoggerFactory.getLogger;
22
23import java.util.Set;
24import java.util.concurrent.ExecutorService;
25
26import org.onlab.util.Bandwidth;
27import org.onosproject.net.ConnectPoint;
28import org.onosproject.net.config.NetworkConfigEvent;
29import org.onosproject.net.config.NetworkConfigListener;
30import org.onosproject.net.config.NetworkConfigService;
31import org.onosproject.net.newresource.BandwidthCapacity;
32import org.onosproject.net.newresource.ResourceAdminService;
33import 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) {
72 return CONFIG_CLASSES.contains(event.configClass());
73 }
74
75 @Override
76 public void event(NetworkConfigEvent event) {
77 if (event.configClass() == BandwidthCapacity.class) {
78 executor.submit(() -> {
79 try {
80 handleBandwidthCapacity(event);
81 } catch (Exception e) {
82 log.error("Exception handling BandwidthCapacity", e);
83 }
84 });
85 }
86 }
87
88 private void handleBandwidthCapacity(NetworkConfigEvent event) {
89 checkArgument(event.configClass() == BandwidthCapacity.class);
90
91 ConnectPoint cp = (ConnectPoint) event.subject();
92 BandwidthCapacity bwCapacity = cfgService.getConfig(cp, BandwidthCapacity.class);
93
94 switch (event.type()) {
95 case CONFIG_ADDED:
Sho SHIMIZUf95b96e2016-01-25 19:35:15 -080096 if (!adminService.registerResources(continuous(cp.deviceId(),
97 cp.port(), Bandwidth.class)
98 .resource(bwCapacity.capacity().bps()))) {
HIGUCHI Yuta1d7c9cb2016-01-20 18:22:36 -080099 log.info("Failed to register Bandwidth for {}, attempting update", cp);
100
101 // Bandwidth based on port speed, was probably already registered.
102 // need to update to the valued based on configuration
103
104 if (!updateRegistration(cp, bwCapacity)) {
105 log.warn("Failed to update Bandwidth for {}", cp);
106 }
107 }
108 break;
109
110 case CONFIG_UPDATED:
111 if (!updateRegistration(cp, bwCapacity)) {
112 log.warn("Failed to update Bandwidth for {}", cp);
113 }
114 break;
115
116 case CONFIG_REMOVED:
117 // FIXME Following should be an update to the value based on port speed
Sho SHIMIZUf95b96e2016-01-25 19:35:15 -0800118 if (!adminService.unregisterResources(continuous(cp.deviceId(),
HIGUCHI Yuta1d7c9cb2016-01-20 18:22:36 -0800119 cp.port(),
Sho SHIMIZUf95b96e2016-01-25 19:35:15 -0800120 Bandwidth.class).resource(0))) {
HIGUCHI Yuta1d7c9cb2016-01-20 18:22:36 -0800121 log.warn("Failed to unregister Bandwidth for {}", cp);
122 }
123 break;
124
125 case CONFIG_REGISTERED:
126 case CONFIG_UNREGISTERED:
127 // no-op
128 break;
129
130 default:
131 break;
132 }
133 }
134
135 private boolean updateRegistration(ConnectPoint cp, BandwidthCapacity bwCapacity) {
136 // FIXME workaround until replace/update semantics become available
137 // this potentially blows up existing registration
138 // or end up as no-op
139 //
140 // Current code end up in situation like below:
141 // PortNumber: 2
142 // MplsLabel: [[16‥240)]
143 // VlanId: [[0‥4095)]
144 // Bandwidth: 2000000.000000
145 // Bandwidth: 20000000.000000
146 //
147 // but both unregisterResources(..) and registerResources(..)
148 // returns true (success)
149
Sho SHIMIZUf95b96e2016-01-25 19:35:15 -0800150 if (!adminService.unregisterResources(continuous(cp.deviceId(), cp.port(), Bandwidth.class).resource(0))) {
HIGUCHI Yuta1d7c9cb2016-01-20 18:22:36 -0800151 log.warn("unregisterResources for {} failed", cp);
152 }
Sho SHIMIZUf95b96e2016-01-25 19:35:15 -0800153 return adminService.registerResources(continuous(cp.deviceId(),
HIGUCHI Yuta1d7c9cb2016-01-20 18:22:36 -0800154 cp.port(),
Sho SHIMIZUf95b96e2016-01-25 19:35:15 -0800155 Bandwidth.class).resource(bwCapacity.capacity().bps()));
HIGUCHI Yuta1d7c9cb2016-01-20 18:22:36 -0800156 }
157
158}