blob: 44db6344d80b9346a34d7cc718ec1fb6d13af9bb [file] [log] [blame]
Kyuhwi Choic5b33ea2016-04-26 11:45:32 +09001/*
2 * Copyright 2016-present 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 */
16
Hyunsun Moon71701292016-05-09 12:00:54 -070017package org.onosproject.scalablegateway.impl;
Kyuhwi Choic5b33ea2016-04-26 11:45:32 +090018
Kyuhwi Choidc2973b2016-05-13 14:54:31 +090019import com.google.common.collect.Lists;
20import com.google.common.collect.Maps;
21import org.apache.felix.scr.annotations.Activate;
22import org.apache.felix.scr.annotations.Component;
23import org.apache.felix.scr.annotations.Deactivate;
24
25import org.apache.felix.scr.annotations.Reference;
26import org.apache.felix.scr.annotations.ReferenceCardinality;
27import org.apache.felix.scr.annotations.Service;
28import org.onosproject.core.ApplicationId;
29import org.onosproject.core.CoreService;
30
Kyuhwi Choic5b33ea2016-04-26 11:45:32 +090031import org.onosproject.core.GroupId;
32import org.onosproject.net.DeviceId;
Kyuhwi Choidc2973b2016-05-13 14:54:31 +090033import org.onosproject.net.Port;
Kyuhwi Choic5b33ea2016-04-26 11:45:32 +090034import org.onosproject.net.PortNumber;
Kyuhwi Choidc2973b2016-05-13 14:54:31 +090035import org.onosproject.net.config.ConfigFactory;
36import org.onosproject.net.config.NetworkConfigEvent;
37import org.onosproject.net.config.NetworkConfigListener;
38import org.onosproject.net.config.NetworkConfigRegistry;
39import org.onosproject.net.config.NetworkConfigService;
40import org.onosproject.net.config.basics.SubjectFactories;
41import org.onosproject.net.device.DeviceService;
Kyuhwi Choib0718212016-06-01 11:33:27 +090042import org.onosproject.net.driver.DriverService;
43import org.onosproject.net.group.Group;
44import org.onosproject.net.group.GroupDescription;
45import org.onosproject.net.group.GroupService;
Hyunsun Moon71701292016-05-09 12:00:54 -070046import org.onosproject.scalablegateway.api.GatewayNode;
Kyuhwi Choidc2973b2016-05-13 14:54:31 +090047import org.onosproject.scalablegateway.api.GatewayNodeConfig;
Hyunsun Moon71701292016-05-09 12:00:54 -070048import org.onosproject.scalablegateway.api.ScalableGatewayService;
Kyuhwi Choic5b33ea2016-04-26 11:45:32 +090049
50import java.util.List;
Kyuhwi Choidc2973b2016-05-13 14:54:31 +090051import java.util.Map;
52
53import org.slf4j.Logger;
54import org.slf4j.LoggerFactory;
55
56import static com.google.common.base.Preconditions.checkNotNull;
Kyuhwi Choic5b33ea2016-04-26 11:45:32 +090057
58/**
59 * Manages gateway node for gateway scalability.
60 */
Kyuhwi Choidc2973b2016-05-13 14:54:31 +090061
62@Service
63@Component(immediate = true)
Kyuhwi Choic5b33ea2016-04-26 11:45:32 +090064public class ScalableGatewayManager implements ScalableGatewayService {
Kyuhwi Choidc2973b2016-05-13 14:54:31 +090065 private final Logger log = LoggerFactory.getLogger(getClass());
66
67 private ApplicationId appId;
68 private static final String APP_ID = "org.onosproject.scalablegateway";
69 private static final String APP_NAME = "scalablegateway";
70 private static final String GATEWAYNODE_CAN_NOT_BE_NULL = "The gateway node can not be null";
71 private static final String PORT_CAN_NOT_BE_NULL = "The port can not be null";
72 private static final String FAIL_ADD_GATEWAY = "Adding process is failed as existing deivce id";
73 private static final String FAIL_REMOVE_GATEWAY = "Removing process is failed as unknown deivce id";
74 private static final String PORT_NAME = "portName";
75
76 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
77 protected CoreService coreService;
78
79 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
80 protected NetworkConfigService configService;
81
82 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
83 protected NetworkConfigRegistry configRegistry;
84
85 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
86 protected DeviceService deviceService;
87
Kyuhwi Choib0718212016-06-01 11:33:27 +090088 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
89 protected DriverService driverService;
90
91 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
92 protected GroupService groupService;
93
Kyuhwi Choidc2973b2016-05-13 14:54:31 +090094 private GatewayNodeConfig config;
Kyuhwi Choib0718212016-06-01 11:33:27 +090095 private SelectGroupHandler selectGroupHandler;
Kyuhwi Choidc2973b2016-05-13 14:54:31 +090096
97 private final NetworkConfigListener configListener = new InternalConfigListener();
98
99 private final ConfigFactory configFactory =
100 new ConfigFactory(SubjectFactories.APP_SUBJECT_FACTORY, GatewayNodeConfig.class, APP_NAME) {
101 @Override
102 public GatewayNodeConfig createConfig() {
103 return new GatewayNodeConfig();
104 }
105 };
106 private Map<DeviceId, GatewayNode> gatewayNodeMap = Maps.newHashMap(); // Map<GatewayNode`s Id, GatewayNode object>
107
108 @Activate
109 protected void activate() {
110 appId = coreService.registerApplication(APP_ID);
111 configRegistry.registerConfigFactory(configFactory);
112 configService.addListener(configListener);
113
Kyuhwi Choib0718212016-06-01 11:33:27 +0900114 selectGroupHandler = new SelectGroupHandler(groupService, deviceService, driverService, appId);
Kyuhwi Choidc2973b2016-05-13 14:54:31 +0900115 readConfiguration();
116
117 log.info("started");
118 }
119
120 @Deactivate
121 protected void deactivate() {
122 gatewayNodeMap.clear();
123
124 configService.removeListener(configListener);
125
126 log.info("stopped");
127 }
Kyuhwi Choic5b33ea2016-04-26 11:45:32 +0900128
129 @Override
130 public GatewayNode getGatewayNode(DeviceId deviceId) {
Kyuhwi Choidc2973b2016-05-13 14:54:31 +0900131 return checkNotNull(gatewayNodeMap.get(deviceId), GATEWAYNODE_CAN_NOT_BE_NULL);
Kyuhwi Choic5b33ea2016-04-26 11:45:32 +0900132 }
133
134 @Override
135 public List<PortNumber> getGatewayExternalPorts(DeviceId deviceId) {
Kyuhwi Choidc2973b2016-05-13 14:54:31 +0900136 GatewayNode gatewayNode = checkNotNull(gatewayNodeMap.get(deviceId), GATEWAYNODE_CAN_NOT_BE_NULL);
137 List<PortNumber> portNumbers = Lists.newArrayList();
138 gatewayNode.getGatewayExternalInterfaceNames()
139 .stream()
140 .forEach(name -> portNumbers.add(findPortNumFromPortName(gatewayNode.getGatewayDeviceId(), name)));
141 return portNumbers;
142 }
143
144 private PortNumber findPortNumFromPortName(DeviceId gatewayDeviceId, String name) {
145 Port port = deviceService.getPorts(gatewayDeviceId)
146 .stream()
147 .filter(p -> p.annotations().value(PORT_NAME).equals(name))
148 .iterator()
149 .next();
150 return checkNotNull(port, PORT_CAN_NOT_BE_NULL).number();
151
Kyuhwi Choic5b33ea2016-04-26 11:45:32 +0900152 }
153
154 @Override
155 public GroupId getGroupIdForGatewayLoadBalance(DeviceId srcDeviceId) {
Kyuhwi Choib0718212016-06-01 11:33:27 +0900156 GroupDescription description = selectGroupHandler.createSelectGroupInVxlan(srcDeviceId, getGatewayNodes());
157 groupService.addGroup(description);
158 Group group = groupService.getGroup(description.deviceId(), description.appCookie());
159 return group != null ? group.id() : null;
Kyuhwi Choic5b33ea2016-04-26 11:45:32 +0900160 }
161
162 @Override
163 public List<GatewayNode> getGatewayNodes() {
Kyuhwi Choidc2973b2016-05-13 14:54:31 +0900164 List<GatewayNode> gatewayNodeList = Lists.newArrayList();
165 gatewayNodeMap.values()
166 .stream()
167 .forEach(gatewayNode -> gatewayNodeList.add(gatewayNode));
168 return gatewayNodeList;
169
Kyuhwi Choic5b33ea2016-04-26 11:45:32 +0900170 }
171
172 @Override
173 public List<DeviceId> getGatewayDeviceIds() {
Kyuhwi Choidc2973b2016-05-13 14:54:31 +0900174 List<DeviceId> deviceIdList = Lists.newArrayList();
175 gatewayNodeMap.values()
176 .stream()
177 .forEach(gatewayNode -> deviceIdList.add(gatewayNode.getGatewayDeviceId()));
178 return deviceIdList;
179
Kyuhwi Choic5b33ea2016-04-26 11:45:32 +0900180 }
181
182 @Override
183 public boolean addGatewayNode(GatewayNode gatewayNode) {
Kyuhwi Choidc2973b2016-05-13 14:54:31 +0900184 gatewayNodeMap.putIfAbsent(gatewayNode.getGatewayDeviceId(), gatewayNode);
185 return true;
Kyuhwi Choic5b33ea2016-04-26 11:45:32 +0900186 }
187
188 @Override
189 public boolean deleteGatewayNode(GatewayNode gatewayNode) {
Kyuhwi Choidc2973b2016-05-13 14:54:31 +0900190 return gatewayNodeMap.remove(gatewayNode.getGatewayDeviceId(), gatewayNode);
191 }
192
193 private class InternalConfigListener implements NetworkConfigListener {
194 @Override
195 public void event(NetworkConfigEvent event) {
196 if (!event.configClass().equals(GatewayNodeConfig.class)) {
197 return;
198 }
199 switch (event.type()) {
200 case CONFIG_UPDATED:
201 gatewayNodeMap.clear();
202 readConfiguration();
203 break;
204 case CONFIG_ADDED:
205 readConfiguration();
206 break;
207 default:
208 log.debug("Unsupportable event type is occurred");
209 break;
210 }
211 }
212 }
213
214 private void readConfiguration() {
215 config = configService.getConfig(appId, GatewayNodeConfig.class);
216 if (config == null) {
217 log.error("No configuration found");
218 return;
219 }
220
221 config.gatewayNodes().forEach(gatewayNode -> addGatewayNode(gatewayNode));
222
223 log.info("ScalableGateway configured");
Kyuhwi Choic5b33ea2016-04-26 11:45:32 +0900224 }
225}