blob: 88d8bc6cd646c0451e7b934684e3e11b3a0da42c [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:
96 if (!adminService.registerResources(continuous(bwCapacity.capacity().bps(),
97 cp.deviceId(),
98 cp.port(), Bandwidth.class))) {
99 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
118 if (!adminService.unregisterResources(continuous(0,
119 cp.deviceId(),
120 cp.port(),
121 Bandwidth.class))) {
122 log.warn("Failed to unregister Bandwidth for {}", cp);
123 }
124 break;
125
126 case CONFIG_REGISTERED:
127 case CONFIG_UNREGISTERED:
128 // no-op
129 break;
130
131 default:
132 break;
133 }
134 }
135
136 private boolean updateRegistration(ConnectPoint cp, BandwidthCapacity bwCapacity) {
137 // FIXME workaround until replace/update semantics become available
138 // this potentially blows up existing registration
139 // or end up as no-op
140 //
141 // Current code end up in situation like below:
142 // PortNumber: 2
143 // MplsLabel: [[16‥240)]
144 // VlanId: [[0‥4095)]
145 // Bandwidth: 2000000.000000
146 // Bandwidth: 20000000.000000
147 //
148 // but both unregisterResources(..) and registerResources(..)
149 // returns true (success)
150
151 if (!adminService.unregisterResources(continuous(0, cp.deviceId(), cp.port(), Bandwidth.class))) {
152 log.warn("unregisterResources for {} failed", cp);
153 }
154 return adminService.registerResources(continuous(bwCapacity.capacity().bps(),
155 cp.deviceId(),
156 cp.port(),
157 Bandwidth.class));
158 }
159
160}