Kyuhwi Choi
Committed by Jonathan Hart

[ONOS-4478][ONOS-4479] Implement scalable gateway get methods and gateway node management

 - Implements scalable gateway interface methods
 - Implements gateway node management

Change-Id: Ie5eb400b52df49dc36aef951e356e04b6238d59d
...@@ -47,6 +47,12 @@ ...@@ -47,6 +47,12 @@
47 <dependency> 47 <dependency>
48 <groupId>org.onosproject</groupId> 48 <groupId>org.onosproject</groupId>
49 <artifactId>onos-api</artifactId> 49 <artifactId>onos-api</artifactId>
50 + <version>${project.version}</version>
51 + </dependency>
52 + <dependency>
53 + <groupId>org.onosproject</groupId>
54 + <artifactId>onos-core-serializers</artifactId>
55 + <version>${project.version}</version>
50 </dependency> 56 </dependency>
51 </dependencies> 57 </dependencies>
52 </project> 58 </project>
......
1 +/*
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 +package org.onosproject.scalablegateway.api;
17 +
18 +
19 +import com.fasterxml.jackson.databind.JsonNode;
20 +import com.google.common.collect.Lists;
21 +import com.google.common.collect.Sets;
22 +import org.onlab.packet.Ip4Address;
23 +import org.onosproject.core.ApplicationId;
24 +import org.onosproject.net.DeviceId;
25 +import org.onosproject.net.config.Config;
26 +import org.slf4j.Logger;
27 +
28 +import java.util.Collections;
29 +import java.util.List;
30 +import java.util.Set;
31 +
32 +import static org.slf4j.LoggerFactory.getLogger;
33 +import static org.onosproject.net.config.Config.FieldPresence.MANDATORY;
34 +
35 +/**
36 + * Configuration object for OpensatckNode service.
37 + */
38 +public class GatewayNodeConfig extends Config<ApplicationId> {
39 +
40 + protected final Logger log = getLogger(getClass());
41 +
42 + public static final String NODES = "nodes";
43 + public static final String BRIDGE_ID = "bridgeId";
44 + public static final String DATAPLANE_IP = "dataPlaneIp";
45 + public static final String EXTERNAL_INTERFACE_NAME = "gatewayExternalInterfaceName";
46 +
47 + /**
48 + * Returns the set of nodes read from network config.
49 + *
50 + * @return set of OpensatckNodeConfig or null
51 + */
52 + public Set<GatewayNode> gatewayNodes() {
53 +
54 + Set<GatewayNode> nodes = Sets.newHashSet();
55 +
56 + JsonNode jsonNodes = object.get(NODES);
57 + if (jsonNodes == null) {
58 + return null;
59 + }
60 +
61 + jsonNodes.forEach(jsonNode -> {
62 + try {
63 + nodes.add(new GatewayNode.Builder()
64 + .gatewayDeviceId(DeviceId.deviceId(jsonNode.path(BRIDGE_ID).asText()))
65 + .gatewayExternalInterfaceNames(
66 + getExternalInterfaceName(jsonNode.path(EXTERNAL_INTERFACE_NAME).asText()))
67 + .dataIpAddress(Ip4Address.valueOf(jsonNode.path(DATAPLANE_IP).asText())).build());
68 + } catch (IllegalArgumentException | NullPointerException e) {
69 + log.error("Failed to read {}", e.toString());
70 + }
71 + });
72 + return nodes;
73 + }
74 +
75 + private List<String> getExternalInterfaceName(String s) {
76 + List<String> list = Lists.newArrayList();
77 + return Collections.addAll(list, s.split(",")) ? list : null;
78 + }
79 +
80 + @Override
81 + public boolean isValid() {
82 + return hasOnlyFields(NODES, BRIDGE_ID, DATAPLANE_IP, EXTERNAL_INTERFACE_NAME) &&
83 + isIpAddress(DATAPLANE_IP, MANDATORY) && isString(BRIDGE_ID, MANDATORY) &&
84 + isString(EXTERNAL_INTERFACE_NAME, MANDATORY);
85 + }
86 +
87 +}
...@@ -15,6 +15,6 @@ ...@@ -15,6 +15,6 @@
15 */ 15 */
16 16
17 /** 17 /**
18 - * Application for ScaleableGateway management. 18 + * Application api for Scaleable Gateway management.
19 */ 19 */
20 package org.onosproject.scalablegateway.api; 20 package org.onosproject.scalablegateway.api;
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -16,51 +16,196 @@ ...@@ -16,51 +16,196 @@
16 16
17 package org.onosproject.scalablegateway.impl; 17 package org.onosproject.scalablegateway.impl;
18 18
19 +import com.google.common.collect.Lists;
20 +import com.google.common.collect.Maps;
21 +import org.apache.felix.scr.annotations.Activate;
22 +import org.apache.felix.scr.annotations.Component;
23 +import org.apache.felix.scr.annotations.Deactivate;
24 +
25 +import org.apache.felix.scr.annotations.Reference;
26 +import org.apache.felix.scr.annotations.ReferenceCardinality;
27 +import org.apache.felix.scr.annotations.Service;
28 +import org.onosproject.core.ApplicationId;
29 +import org.onosproject.core.CoreService;
30 +
19 import org.onosproject.core.GroupId; 31 import org.onosproject.core.GroupId;
20 import org.onosproject.net.DeviceId; 32 import org.onosproject.net.DeviceId;
33 +import org.onosproject.net.Port;
21 import org.onosproject.net.PortNumber; 34 import org.onosproject.net.PortNumber;
35 +import org.onosproject.net.config.ConfigFactory;
36 +import org.onosproject.net.config.NetworkConfigEvent;
37 +import org.onosproject.net.config.NetworkConfigListener;
38 +import org.onosproject.net.config.NetworkConfigRegistry;
39 +import org.onosproject.net.config.NetworkConfigService;
40 +import org.onosproject.net.config.basics.SubjectFactories;
41 +import org.onosproject.net.device.DeviceService;
22 import org.onosproject.scalablegateway.api.GatewayNode; 42 import org.onosproject.scalablegateway.api.GatewayNode;
43 +import org.onosproject.scalablegateway.api.GatewayNodeConfig;
23 import org.onosproject.scalablegateway.api.ScalableGatewayService; 44 import org.onosproject.scalablegateway.api.ScalableGatewayService;
24 45
25 import java.util.List; 46 import java.util.List;
47 +import java.util.Map;
48 +
49 +import org.slf4j.Logger;
50 +import org.slf4j.LoggerFactory;
51 +
52 +import static com.google.common.base.Preconditions.checkNotNull;
26 53
27 /** 54 /**
28 * Manages gateway node for gateway scalability. 55 * Manages gateway node for gateway scalability.
29 */ 56 */
57 +
58 +@Service
59 +@Component(immediate = true)
30 public class ScalableGatewayManager implements ScalableGatewayService { 60 public class ScalableGatewayManager implements ScalableGatewayService {
61 + private final Logger log = LoggerFactory.getLogger(getClass());
62 +
63 + private ApplicationId appId;
64 + private static final String APP_ID = "org.onosproject.scalablegateway";
65 + private static final String APP_NAME = "scalablegateway";
66 + private static final String GATEWAYNODE_CAN_NOT_BE_NULL = "The gateway node can not be null";
67 + private static final String PORT_CAN_NOT_BE_NULL = "The port can not be null";
68 + private static final String FAIL_ADD_GATEWAY = "Adding process is failed as existing deivce id";
69 + private static final String FAIL_REMOVE_GATEWAY = "Removing process is failed as unknown deivce id";
70 + private static final String PORT_NAME = "portName";
71 +
72 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
73 + protected CoreService coreService;
74 +
75 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
76 + protected NetworkConfigService configService;
77 +
78 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
79 + protected NetworkConfigRegistry configRegistry;
80 +
81 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
82 + protected DeviceService deviceService;
83 +
84 + private GatewayNodeConfig config;
85 +
86 + private final NetworkConfigListener configListener = new InternalConfigListener();
87 +
88 + private final ConfigFactory configFactory =
89 + new ConfigFactory(SubjectFactories.APP_SUBJECT_FACTORY, GatewayNodeConfig.class, APP_NAME) {
90 + @Override
91 + public GatewayNodeConfig createConfig() {
92 + return new GatewayNodeConfig();
93 + }
94 + };
95 + private Map<DeviceId, GatewayNode> gatewayNodeMap = Maps.newHashMap(); // Map<GatewayNode`s Id, GatewayNode object>
96 +
97 + @Activate
98 + protected void activate() {
99 + appId = coreService.registerApplication(APP_ID);
100 + configRegistry.registerConfigFactory(configFactory);
101 + configService.addListener(configListener);
102 +
103 + readConfiguration();
104 +
105 + log.info("started");
106 + }
107 +
108 + @Deactivate
109 + protected void deactivate() {
110 + gatewayNodeMap.clear();
111 +
112 + configService.removeListener(configListener);
113 +
114 + log.info("stopped");
115 + }
31 116
32 @Override 117 @Override
33 public GatewayNode getGatewayNode(DeviceId deviceId) { 118 public GatewayNode getGatewayNode(DeviceId deviceId) {
34 - return null; 119 + return checkNotNull(gatewayNodeMap.get(deviceId), GATEWAYNODE_CAN_NOT_BE_NULL);
35 } 120 }
36 121
37 @Override 122 @Override
38 public List<PortNumber> getGatewayExternalPorts(DeviceId deviceId) { 123 public List<PortNumber> getGatewayExternalPorts(DeviceId deviceId) {
39 - return null; 124 + GatewayNode gatewayNode = checkNotNull(gatewayNodeMap.get(deviceId), GATEWAYNODE_CAN_NOT_BE_NULL);
125 + List<PortNumber> portNumbers = Lists.newArrayList();
126 + gatewayNode.getGatewayExternalInterfaceNames()
127 + .stream()
128 + .forEach(name -> portNumbers.add(findPortNumFromPortName(gatewayNode.getGatewayDeviceId(), name)));
129 + return portNumbers;
130 + }
131 +
132 + private PortNumber findPortNumFromPortName(DeviceId gatewayDeviceId, String name) {
133 + Port port = deviceService.getPorts(gatewayDeviceId)
134 + .stream()
135 + .filter(p -> p.annotations().value(PORT_NAME).equals(name))
136 + .iterator()
137 + .next();
138 + return checkNotNull(port, PORT_CAN_NOT_BE_NULL).number();
139 +
40 } 140 }
41 141
42 @Override 142 @Override
43 public GroupId getGroupIdForGatewayLoadBalance(DeviceId srcDeviceId) { 143 public GroupId getGroupIdForGatewayLoadBalance(DeviceId srcDeviceId) {
144 + //TODO: Implement group generation method by handler
44 return null; 145 return null;
45 } 146 }
46 147
47 @Override 148 @Override
48 public List<GatewayNode> getGatewayNodes() { 149 public List<GatewayNode> getGatewayNodes() {
49 - return null; 150 + List<GatewayNode> gatewayNodeList = Lists.newArrayList();
151 + gatewayNodeMap.values()
152 + .stream()
153 + .forEach(gatewayNode -> gatewayNodeList.add(gatewayNode));
154 + return gatewayNodeList;
155 +
50 } 156 }
51 157
52 @Override 158 @Override
53 public List<DeviceId> getGatewayDeviceIds() { 159 public List<DeviceId> getGatewayDeviceIds() {
54 - return null; 160 + List<DeviceId> deviceIdList = Lists.newArrayList();
161 + gatewayNodeMap.values()
162 + .stream()
163 + .forEach(gatewayNode -> deviceIdList.add(gatewayNode.getGatewayDeviceId()));
164 + return deviceIdList;
165 +
55 } 166 }
56 167
57 @Override 168 @Override
58 public boolean addGatewayNode(GatewayNode gatewayNode) { 169 public boolean addGatewayNode(GatewayNode gatewayNode) {
59 - return false; 170 + gatewayNodeMap.putIfAbsent(gatewayNode.getGatewayDeviceId(), gatewayNode);
171 + return true;
60 } 172 }
61 173
62 @Override 174 @Override
63 public boolean deleteGatewayNode(GatewayNode gatewayNode) { 175 public boolean deleteGatewayNode(GatewayNode gatewayNode) {
64 - return false; 176 + return gatewayNodeMap.remove(gatewayNode.getGatewayDeviceId(), gatewayNode);
177 + }
178 +
179 + private class InternalConfigListener implements NetworkConfigListener {
180 + @Override
181 + public void event(NetworkConfigEvent event) {
182 + if (!event.configClass().equals(GatewayNodeConfig.class)) {
183 + return;
184 + }
185 + switch (event.type()) {
186 + case CONFIG_UPDATED:
187 + gatewayNodeMap.clear();
188 + readConfiguration();
189 + break;
190 + case CONFIG_ADDED:
191 + readConfiguration();
192 + break;
193 + default:
194 + log.debug("Unsupportable event type is occurred");
195 + break;
196 + }
197 + }
198 + }
199 +
200 + private void readConfiguration() {
201 + config = configService.getConfig(appId, GatewayNodeConfig.class);
202 + if (config == null) {
203 + log.error("No configuration found");
204 + return;
205 + }
206 +
207 + config.gatewayNodes().forEach(gatewayNode -> addGatewayNode(gatewayNode));
208 +
209 + log.info("ScalableGateway configured");
65 } 210 }
66 } 211 }
......
...@@ -15,6 +15,6 @@ ...@@ -15,6 +15,6 @@
15 */ 15 */
16 16
17 /** 17 /**
18 - * Application for ScaleableGateway management. 18 + * Application for Scaleable Gateway management.
19 */ 19 */
20 package org.onosproject.scalablegateway.impl; 20 package org.onosproject.scalablegateway.impl;
...\ No newline at end of file ...\ No newline at end of file
......