Hyunsun Moon
Committed by Gerrit Code Review

CORD-380 Added host provider for cordvtn service

- Renamed CordVtnConfigManager to CordVtnNodeManager
- Moved all node bootstrap logic to CordVtnNodeManager
- CordVtnService now provides VM add/remove and service dependency create/remove
- Made CordVtn implement HostProvider so that it can inject/eject VM to the system

Change-Id: I0011ac692ecea240d2d7fe48b3e7a1db4973b76e
1 -/*
2 - * Copyright 2014-2015 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.cordvtn;
17 -
18 -import org.apache.felix.scr.annotations.Activate;
19 -import org.apache.felix.scr.annotations.Component;
20 -import org.apache.felix.scr.annotations.Deactivate;
21 -import org.apache.felix.scr.annotations.Reference;
22 -import org.apache.felix.scr.annotations.ReferenceCardinality;
23 -import org.onosproject.core.ApplicationId;
24 -import org.onosproject.core.CoreService;
25 -import org.onosproject.net.config.ConfigFactory;
26 -import org.onosproject.net.config.NetworkConfigEvent;
27 -import org.onosproject.net.config.NetworkConfigListener;
28 -import org.onosproject.net.config.NetworkConfigRegistry;
29 -import org.onosproject.net.config.NetworkConfigService;
30 -import org.onosproject.net.config.basics.SubjectFactories;
31 -import org.slf4j.Logger;
32 -
33 -import java.util.concurrent.ExecutorService;
34 -
35 -import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
36 -import static org.onlab.util.Tools.groupedThreads;
37 -import static org.slf4j.LoggerFactory.getLogger;
38 -
39 -/**
40 - * Reads node information from the network config file and handles the config
41 - * update events.
42 - * Only a leader controller performs the node addition or deletion.
43 - */
44 -@Component(immediate = true)
45 -public class CordVtnConfigManager {
46 -
47 - protected final Logger log = getLogger(getClass());
48 -
49 - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
50 - protected CoreService coreService;
51 -
52 - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
53 - protected NetworkConfigRegistry configRegistry;
54 -
55 - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
56 - protected NetworkConfigService configService;
57 -
58 - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
59 - protected CordVtnService cordVtnService;
60 -
61 - private final ConfigFactory configFactory =
62 - new ConfigFactory(SubjectFactories.APP_SUBJECT_FACTORY, CordVtnConfig.class, "cordvtn") {
63 - @Override
64 - public CordVtnConfig createConfig() {
65 - return new CordVtnConfig();
66 - }
67 - };
68 -
69 - private final NetworkConfigListener configListener = new InternalConfigListener();
70 - private ApplicationId appId;
71 - protected ExecutorService eventExecutor;
72 -
73 -
74 - @Activate
75 - protected void active() {
76 - appId = coreService.getAppId(CordVtnService.CORDVTN_APP_ID);
77 -
78 - eventExecutor = newSingleThreadScheduledExecutor(groupedThreads("onos/cordvtncfg", "event-handler"));
79 - configService.addListener(configListener);
80 - configRegistry.registerConfigFactory(configFactory);
81 - }
82 -
83 - @Deactivate
84 - protected void deactivate() {
85 - configRegistry.unregisterConfigFactory(configFactory);
86 - configService.removeListener(configListener);
87 - eventExecutor.shutdown();
88 - }
89 -
90 - private void readConfiguration() {
91 - CordVtnConfig config = configRegistry.getConfig(appId, CordVtnConfig.class);
92 -
93 - if (config == null) {
94 - log.warn("No configuration found");
95 - return;
96 - }
97 -
98 - config.cordVtnNodes().forEach(node -> {
99 - CordVtnNode cordVtnNode = new CordVtnNode(
100 - node.hostname(),
101 - node.ovsdbIp(),
102 - node.ovsdbPort(),
103 - node.bridgeId(),
104 - node.phyPortName(),
105 - node.localIp());
106 -
107 - cordVtnService.addNode(cordVtnNode);
108 - });
109 - }
110 -
111 - private class InternalConfigListener implements NetworkConfigListener {
112 -
113 - @Override
114 - public void event(NetworkConfigEvent event) {
115 - if (!event.configClass().equals(CordVtnConfig.class)) {
116 - return;
117 - }
118 -
119 - switch (event.type()) {
120 - case CONFIG_ADDED:
121 - log.info("Network configuration added");
122 - eventExecutor.execute(CordVtnConfigManager.this::readConfiguration);
123 - break;
124 - case CONFIG_UPDATED:
125 - log.info("Network configuration updated");
126 - eventExecutor.execute(CordVtnConfigManager.this::readConfiguration);
127 - break;
128 - default:
129 - break;
130 - }
131 - }
132 - }
133 -}
...@@ -165,13 +165,10 @@ public class CordVtnRuleInstaller { ...@@ -165,13 +165,10 @@ public class CordVtnRuleInstaller {
165 * Populates basic rules that connect a VM to the other VMs in the system. 165 * Populates basic rules that connect a VM to the other VMs in the system.
166 * 166 *
167 * @param host host 167 * @param host host
168 - * @param hostIp host ip
169 * @param tunnelIp tunnel ip 168 * @param tunnelIp tunnel ip
170 * @param vNet openstack network 169 * @param vNet openstack network
171 */ 170 */
172 - public void populateBasicConnectionRules(Host host, IpAddress hostIp, IpAddress tunnelIp, 171 + public void populateBasicConnectionRules(Host host, IpAddress tunnelIp, OpenstackNetwork vNet) {
173 - OpenstackNetwork vNet) {
174 - // TODO we can get host ip from host.ip() after applying NetworkConfig host provider
175 checkNotNull(host); 172 checkNotNull(host);
176 checkNotNull(vNet); 173 checkNotNull(vNet);
177 174
...@@ -182,6 +179,7 @@ public class CordVtnRuleInstaller { ...@@ -182,6 +179,7 @@ public class CordVtnRuleInstaller {
182 179
183 PortNumber inPort = host.location().port(); 180 PortNumber inPort = host.location().port();
184 MacAddress dstMac = host.mac(); 181 MacAddress dstMac = host.mac();
182 + IpAddress hostIp = host.ipAddresses().stream().findFirst().get();
185 long tunnelId = Long.parseLong(vNet.segmentId()); 183 long tunnelId = Long.parseLong(vNet.segmentId());
186 184
187 OpenstackSubnet subnet = vNet.subnets().stream() 185 OpenstackSubnet subnet = vNet.subnets().stream()
...@@ -352,7 +350,7 @@ public class CordVtnRuleInstaller { ...@@ -352,7 +350,7 @@ public class CordVtnRuleInstaller {
352 350
353 Group group = groupService.getGroup(deviceId, groupKey); 351 Group group = groupService.getGroup(deviceId, groupKey);
354 if (group == null) { 352 if (group == null) {
355 - log.debug("No group exists for service {} in {}", service.id(), deviceId); 353 + log.trace("No group exists for service {} in {}, do nothing.", service.id(), deviceId);
356 continue; 354 continue;
357 } 355 }
358 356
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
15 */ 15 */
16 package org.onosproject.cordvtn; 16 package org.onosproject.cordvtn;
17 17
18 -import java.util.List; 18 +import org.onosproject.net.ConnectPoint;
19 19
20 /** 20 /**
21 * Service for provisioning overlay virtual networks on compute nodes. 21 * Service for provisioning overlay virtual networks on compute nodes.
...@@ -23,61 +23,21 @@ import java.util.List; ...@@ -23,61 +23,21 @@ import java.util.List;
23 public interface CordVtnService { 23 public interface CordVtnService {
24 24
25 String CORDVTN_APP_ID = "org.onosproject.cordvtn"; 25 String CORDVTN_APP_ID = "org.onosproject.cordvtn";
26 - /**
27 - * Adds a new node to the service.
28 - *
29 - * @param node cordvtn node
30 - */
31 - void addNode(CordVtnNode node);
32 -
33 - /**
34 - * Deletes a node from the service.
35 - *
36 - * @param node cordvtn node
37 - */
38 - void deleteNode(CordVtnNode node);
39 -
40 - /**
41 - * Initiates node to serve virtual tenant network.
42 - *
43 - * @param node cordvtn node
44 - */
45 - void initNode(CordVtnNode node);
46 -
47 - /**
48 - * Returns the number of the nodes known to the service.
49 - *
50 - * @return number of nodes
51 - */
52 - int getNodeCount();
53 26
54 /** 27 /**
55 - * Returns node initialization state. 28 + * Adds a new VM on a given node and connect point.
56 - *
57 - * @param node cordvtn node
58 - * @return true if initial node setup is completed, otherwise false
59 - */
60 - boolean getNodeInitState(CordVtnNode node);
61 -
62 - /**
63 - * Returns detailed node initialization state.
64 - * Return string includes the following information.
65 - *
66 - * Integration bridge created/connected: OK or NO
67 - * VXLAN interface created: OK or NO
68 - * Physical interface added: OK or NO
69 * 29 *
70 * @param node cordvtn node 30 * @param node cordvtn node
71 - * @return string including detailed node init state 31 + * @param connectPoint connect point
72 */ 32 */
73 - String checkNodeInitState(CordVtnNode node); 33 + void addServiceVm(CordVtnNode node, ConnectPoint connectPoint);
74 34
75 /** 35 /**
76 - * Returns all nodes known to the service. 36 + * Removes a VM from a given node and connect point.
77 * 37 *
78 - * @return list of nodes 38 + * @param connectPoint connect point
79 */ 39 */
80 - List<CordVtnNode> getNodes(); 40 + void removeServiceVm(ConnectPoint connectPoint);
81 41
82 /** 42 /**
83 * Creates dependencies for a given tenant service. 43 * Creates dependencies for a given tenant service.
......
...@@ -21,7 +21,7 @@ import org.apache.karaf.shell.commands.Command; ...@@ -21,7 +21,7 @@ import org.apache.karaf.shell.commands.Command;
21 import org.onlab.packet.IpAddress; 21 import org.onlab.packet.IpAddress;
22 import org.onlab.packet.TpPort; 22 import org.onlab.packet.TpPort;
23 import org.onosproject.cli.AbstractShellCommand; 23 import org.onosproject.cli.AbstractShellCommand;
24 -import org.onosproject.cordvtn.CordVtnService; 24 +import org.onosproject.cordvtn.CordVtnNodeManager;
25 import org.onosproject.cordvtn.CordVtnNode; 25 import org.onosproject.cordvtn.CordVtnNode;
26 import org.onosproject.net.DeviceId; 26 import org.onosproject.net.DeviceId;
27 27
...@@ -63,7 +63,7 @@ public class CordVtnNodeAddCommand extends AbstractShellCommand { ...@@ -63,7 +63,7 @@ public class CordVtnNodeAddCommand extends AbstractShellCommand {
63 checkArgument(ovsdb.contains(":"), "OVSDB address should be ip:port format"); 63 checkArgument(ovsdb.contains(":"), "OVSDB address should be ip:port format");
64 checkArgument(bridgeId.startsWith("of:"), "bridgeId should be of:dpid format"); 64 checkArgument(bridgeId.startsWith("of:"), "bridgeId should be of:dpid format");
65 65
66 - CordVtnService service = AbstractShellCommand.get(CordVtnService.class); 66 + CordVtnNodeManager nodeManager = AbstractShellCommand.get(CordVtnNodeManager.class);
67 String[] ipPort = ovsdb.split(":"); 67 String[] ipPort = ovsdb.split(":");
68 CordVtnNode node = new CordVtnNode(hostname, 68 CordVtnNode node = new CordVtnNode(hostname,
69 IpAddress.valueOf(ipPort[0]), 69 IpAddress.valueOf(ipPort[0]),
...@@ -71,6 +71,6 @@ public class CordVtnNodeAddCommand extends AbstractShellCommand { ...@@ -71,6 +71,6 @@ public class CordVtnNodeAddCommand extends AbstractShellCommand {
71 DeviceId.deviceId(bridgeId), 71 DeviceId.deviceId(bridgeId),
72 phyPortName, 72 phyPortName,
73 IpAddress.valueOf(localIp)); 73 IpAddress.valueOf(localIp));
74 - service.addNode(node); 74 + nodeManager.addNode(node);
75 } 75 }
76 } 76 }
......
...@@ -20,7 +20,7 @@ import org.apache.karaf.shell.commands.Argument; ...@@ -20,7 +20,7 @@ import org.apache.karaf.shell.commands.Argument;
20 import org.apache.karaf.shell.commands.Command; 20 import org.apache.karaf.shell.commands.Command;
21 import org.onosproject.cli.AbstractShellCommand; 21 import org.onosproject.cli.AbstractShellCommand;
22 import org.onosproject.cordvtn.CordVtnNode; 22 import org.onosproject.cordvtn.CordVtnNode;
23 -import org.onosproject.cordvtn.CordVtnService; 23 +import org.onosproject.cordvtn.CordVtnNodeManager;
24 24
25 /** 25 /**
26 * Checks detailed node init state. 26 * Checks detailed node init state.
...@@ -35,8 +35,8 @@ public class CordVtnNodeCheckCommand extends AbstractShellCommand { ...@@ -35,8 +35,8 @@ public class CordVtnNodeCheckCommand extends AbstractShellCommand {
35 35
36 @Override 36 @Override
37 protected void execute() { 37 protected void execute() {
38 - CordVtnService service = AbstractShellCommand.get(CordVtnService.class); 38 + CordVtnNodeManager nodeManager = AbstractShellCommand.get(CordVtnNodeManager.class);
39 - CordVtnNode node = service.getNodes() 39 + CordVtnNode node = nodeManager.getNodes()
40 .stream() 40 .stream()
41 .filter(n -> n.hostname().equals(hostname)) 41 .filter(n -> n.hostname().equals(hostname))
42 .findFirst() 42 .findFirst()
...@@ -47,6 +47,6 @@ public class CordVtnNodeCheckCommand extends AbstractShellCommand { ...@@ -47,6 +47,6 @@ public class CordVtnNodeCheckCommand extends AbstractShellCommand {
47 return; 47 return;
48 } 48 }
49 49
50 - print(service.checkNodeInitState(node)); 50 + print(nodeManager.checkNodeInitState(node));
51 } 51 }
52 } 52 }
......
...@@ -19,7 +19,7 @@ package org.onosproject.cordvtn.cli; ...@@ -19,7 +19,7 @@ package org.onosproject.cordvtn.cli;
19 import org.apache.karaf.shell.commands.Argument; 19 import org.apache.karaf.shell.commands.Argument;
20 import org.apache.karaf.shell.commands.Command; 20 import org.apache.karaf.shell.commands.Command;
21 import org.onosproject.cli.AbstractShellCommand; 21 import org.onosproject.cli.AbstractShellCommand;
22 -import org.onosproject.cordvtn.CordVtnService; 22 +import org.onosproject.cordvtn.CordVtnNodeManager;
23 import org.onosproject.cordvtn.CordVtnNode; 23 import org.onosproject.cordvtn.CordVtnNode;
24 24
25 import java.util.NoSuchElementException; 25 import java.util.NoSuchElementException;
...@@ -37,12 +37,12 @@ public class CordVtnNodeDeleteCommand extends AbstractShellCommand { ...@@ -37,12 +37,12 @@ public class CordVtnNodeDeleteCommand extends AbstractShellCommand {
37 37
38 @Override 38 @Override
39 protected void execute() { 39 protected void execute() {
40 - CordVtnService service = AbstractShellCommand.get(CordVtnService.class); 40 + CordVtnNodeManager nodeManager = AbstractShellCommand.get(CordVtnNodeManager.class);
41 41
42 for (String hostname : hostnames) { 42 for (String hostname : hostnames) {
43 CordVtnNode node; 43 CordVtnNode node;
44 try { 44 try {
45 - node = service.getNodes() 45 + node = nodeManager.getNodes()
46 .stream() 46 .stream()
47 .filter(n -> n.hostname().equals(hostname)) 47 .filter(n -> n.hostname().equals(hostname))
48 .findFirst().get(); 48 .findFirst().get();
...@@ -51,7 +51,7 @@ public class CordVtnNodeDeleteCommand extends AbstractShellCommand { ...@@ -51,7 +51,7 @@ public class CordVtnNodeDeleteCommand extends AbstractShellCommand {
51 continue; 51 continue;
52 } 52 }
53 53
54 - service.deleteNode(node); 54 + nodeManager.deleteNode(node);
55 } 55 }
56 } 56 }
57 } 57 }
......
...@@ -19,7 +19,7 @@ package org.onosproject.cordvtn.cli; ...@@ -19,7 +19,7 @@ package org.onosproject.cordvtn.cli;
19 import org.apache.karaf.shell.commands.Argument; 19 import org.apache.karaf.shell.commands.Argument;
20 import org.apache.karaf.shell.commands.Command; 20 import org.apache.karaf.shell.commands.Command;
21 import org.onosproject.cli.AbstractShellCommand; 21 import org.onosproject.cli.AbstractShellCommand;
22 -import org.onosproject.cordvtn.CordVtnService; 22 +import org.onosproject.cordvtn.CordVtnNodeManager;
23 import org.onosproject.cordvtn.CordVtnNode; 23 import org.onosproject.cordvtn.CordVtnNode;
24 24
25 import java.util.NoSuchElementException; 25 import java.util.NoSuchElementException;
...@@ -37,12 +37,12 @@ public class CordVtnNodeInitCommand extends AbstractShellCommand { ...@@ -37,12 +37,12 @@ public class CordVtnNodeInitCommand extends AbstractShellCommand {
37 37
38 @Override 38 @Override
39 protected void execute() { 39 protected void execute() {
40 - CordVtnService service = AbstractShellCommand.get(CordVtnService.class); 40 + CordVtnNodeManager nodeManager = AbstractShellCommand.get(CordVtnNodeManager.class);
41 41
42 for (String hostname : hostnames) { 42 for (String hostname : hostnames) {
43 CordVtnNode node; 43 CordVtnNode node;
44 try { 44 try {
45 - node = service.getNodes() 45 + node = nodeManager.getNodes()
46 .stream() 46 .stream()
47 .filter(n -> n.hostname().equals(hostname)) 47 .filter(n -> n.hostname().equals(hostname))
48 .findFirst().get(); 48 .findFirst().get();
...@@ -51,7 +51,7 @@ public class CordVtnNodeInitCommand extends AbstractShellCommand { ...@@ -51,7 +51,7 @@ public class CordVtnNodeInitCommand extends AbstractShellCommand {
51 continue; 51 continue;
52 } 52 }
53 53
54 - service.initNode(node); 54 + nodeManager.initNode(node);
55 } 55 }
56 } 56 }
57 } 57 }
......
...@@ -21,7 +21,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; ...@@ -21,7 +21,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
21 import com.fasterxml.jackson.databind.node.ArrayNode; 21 import com.fasterxml.jackson.databind.node.ArrayNode;
22 import org.apache.karaf.shell.commands.Command; 22 import org.apache.karaf.shell.commands.Command;
23 import org.onosproject.cli.AbstractShellCommand; 23 import org.onosproject.cli.AbstractShellCommand;
24 -import org.onosproject.cordvtn.CordVtnService; 24 +import org.onosproject.cordvtn.CordVtnNodeManager;
25 import org.onosproject.cordvtn.CordVtnNode; 25 import org.onosproject.cordvtn.CordVtnNode;
26 26
27 import java.util.Collections; 27 import java.util.Collections;
...@@ -36,12 +36,12 @@ public class CordVtnNodeListCommand extends AbstractShellCommand { ...@@ -36,12 +36,12 @@ public class CordVtnNodeListCommand extends AbstractShellCommand {
36 36
37 @Override 37 @Override
38 protected void execute() { 38 protected void execute() {
39 - CordVtnService service = AbstractShellCommand.get(CordVtnService.class); 39 + CordVtnNodeManager nodeManager = AbstractShellCommand.get(CordVtnNodeManager.class);
40 - List<CordVtnNode> nodes = service.getNodes(); 40 + List<CordVtnNode> nodes = nodeManager.getNodes();
41 Collections.sort(nodes, CordVtnNode.CORDVTN_NODE_COMPARATOR); 41 Collections.sort(nodes, CordVtnNode.CORDVTN_NODE_COMPARATOR);
42 42
43 if (outputJson()) { 43 if (outputJson()) {
44 - print("%s", json(service, nodes)); 44 + print("%s", json(nodeManager, nodes));
45 } else { 45 } else {
46 for (CordVtnNode node : nodes) { 46 for (CordVtnNode node : nodes) {
47 print("hostname=%s, ovsdb=%s, br-int=%s, phyPort=%s, localIp=%s, init=%s", 47 print("hostname=%s, ovsdb=%s, br-int=%s, phyPort=%s, localIp=%s, init=%s",
...@@ -50,13 +50,13 @@ public class CordVtnNodeListCommand extends AbstractShellCommand { ...@@ -50,13 +50,13 @@ public class CordVtnNodeListCommand extends AbstractShellCommand {
50 node.intBrId().toString(), 50 node.intBrId().toString(),
51 node.phyPortName(), 51 node.phyPortName(),
52 node.localIp().toString(), 52 node.localIp().toString(),
53 - getState(service, node)); 53 + getState(nodeManager, node));
54 } 54 }
55 - print("Total %s nodes", service.getNodeCount()); 55 + print("Total %s nodes", nodeManager.getNodeCount());
56 } 56 }
57 } 57 }
58 58
59 - private JsonNode json(CordVtnService service, List<CordVtnNode> nodes) { 59 + private JsonNode json(CordVtnNodeManager nodeManager, List<CordVtnNode> nodes) {
60 ObjectMapper mapper = new ObjectMapper(); 60 ObjectMapper mapper = new ObjectMapper();
61 ArrayNode result = mapper.createArrayNode(); 61 ArrayNode result = mapper.createArrayNode();
62 for (CordVtnNode node : nodes) { 62 for (CordVtnNode node : nodes) {
...@@ -67,12 +67,12 @@ public class CordVtnNodeListCommand extends AbstractShellCommand { ...@@ -67,12 +67,12 @@ public class CordVtnNodeListCommand extends AbstractShellCommand {
67 .put("brInt", node.intBrId().toString()) 67 .put("brInt", node.intBrId().toString())
68 .put("phyPort", node.phyPortName()) 68 .put("phyPort", node.phyPortName())
69 .put("localIp", node.localIp().toString()) 69 .put("localIp", node.localIp().toString())
70 - .put("init", getState(service, node))); 70 + .put("init", getState(nodeManager, node)));
71 } 71 }
72 return result; 72 return result;
73 } 73 }
74 74
75 - private String getState(CordVtnService service, CordVtnNode node) { 75 + private String getState(CordVtnNodeManager nodeManager, CordVtnNode node) {
76 - return service.getNodeInitState(node) ? "COMPLETE" : "INCOMPLETE"; 76 + return nodeManager.getNodeInitState(node) ? "COMPLETE" : "INCOMPLETE";
77 } 77 }
78 } 78 }
......