Changed to use XOS client to get service and port information
XOS client still gets these information from OpenStack temporarily until XOS provides these APIs Change-Id: I1ef9302f719a18a7377221f63b84431c2cdface8
Showing
18 changed files
with
546 additions
and
633 deletions
... | @@ -6,13 +6,9 @@ COMPILE_DEPS = [ | ... | @@ -6,13 +6,9 @@ COMPILE_DEPS = [ |
6 | '//lib:org.apache.karaf.shell.console', | 6 | '//lib:org.apache.karaf.shell.console', |
7 | '//lib:javax.ws.rs-api', | 7 | '//lib:javax.ws.rs-api', |
8 | '//lib:jsch', | 8 | '//lib:jsch', |
9 | - '//lib:openstack4j-core', | ||
10 | - '//lib:openstack4j-http-connector', | ||
11 | - '//lib:openstack4j-httpclient', | ||
12 | '//utils/rest:onlab-rest', | 9 | '//utils/rest:onlab-rest', |
13 | '//cli:onos-cli', | 10 | '//cli:onos-cli', |
14 | '//core/store/serializers:onos-core-serializers', | 11 | '//core/store/serializers:onos-core-serializers', |
15 | - '//apps/openstackinterface/api:onos-apps-openstackinterface-api', | ||
16 | '//apps/dhcp/api:onos-apps-dhcp-api', | 12 | '//apps/dhcp/api:onos-apps-dhcp-api', |
17 | '//apps/xosclient:onos-apps-xosclient', | 13 | '//apps/xosclient:onos-apps-xosclient', |
18 | '//protocols/ovsdb/api:onos-protocols-ovsdb-api', | 14 | '//protocols/ovsdb/api:onos-protocols-ovsdb-api', |
... | @@ -20,11 +16,7 @@ COMPILE_DEPS = [ | ... | @@ -20,11 +16,7 @@ COMPILE_DEPS = [ |
20 | ] | 16 | ] |
21 | 17 | ||
22 | BUNDLES = [ | 18 | BUNDLES = [ |
23 | - '//apps/openstackinterface/api:onos-apps-openstackinterface-api', | ||
24 | '//apps/cordvtn:onos-apps-cordvtn', | 19 | '//apps/cordvtn:onos-apps-cordvtn', |
25 | - '//lib:openstack4j-core', | ||
26 | - '//lib:openstack4j-http-connector', | ||
27 | - '//lib:openstack4j-httpclient', | ||
28 | ] | 20 | ] |
29 | 21 | ||
30 | EXCLUDED_BUNDLES = [ | 22 | EXCLUDED_BUNDLES = [ |
... | @@ -43,5 +35,5 @@ onos_app ( | ... | @@ -43,5 +35,5 @@ onos_app ( |
43 | included_bundles = BUNDLES, | 35 | included_bundles = BUNDLES, |
44 | excluded_bundles = EXCLUDED_BUNDLES, | 36 | excluded_bundles = EXCLUDED_BUNDLES, |
45 | description = 'APIs for interacting with the CORD VTN application.', | 37 | description = 'APIs for interacting with the CORD VTN application.', |
46 | - required_apps = [ 'org.onosproject.xosclient', 'org.onosproject.dhcp', 'org.onosproject.ovsdb', 'org.onosproject.openstackinterface' ], | 38 | + required_apps = [ 'org.onosproject.xosclient', 'org.onosproject.dhcp', 'org.onosproject.ovsdb' ], |
47 | ) | 39 | ) | ... | ... |
... | @@ -112,21 +112,6 @@ | ... | @@ -112,21 +112,6 @@ |
112 | <artifactId>jsch</artifactId> | 112 | <artifactId>jsch</artifactId> |
113 | <version>0.1.53</version> | 113 | <version>0.1.53</version> |
114 | </dependency> | 114 | </dependency> |
115 | - <dependency> | ||
116 | - <groupId>org.pacesys</groupId> | ||
117 | - <artifactId>openstack4j-core</artifactId> | ||
118 | - <version>2.11</version> | ||
119 | - </dependency> | ||
120 | - <dependency> | ||
121 | - <groupId>org.pacesys.openstack4j.connectors</groupId> | ||
122 | - <artifactId>openstack4j-http-connector</artifactId> | ||
123 | - <version>2.11</version> | ||
124 | - </dependency> | ||
125 | - <dependency> | ||
126 | - <groupId>org.pacesys.openstack4j.connectors</groupId> | ||
127 | - <artifactId>openstack4j-httpclient</artifactId> | ||
128 | - <version>2.11</version> | ||
129 | - </dependency> | ||
130 | </dependencies> | 115 | </dependencies> |
131 | 116 | ||
132 | <build> | 117 | <build> |
... | @@ -146,15 +131,8 @@ | ... | @@ -146,15 +131,8 @@ |
146 | ${project.groupId}.${project.artifactId} | 131 | ${project.groupId}.${project.artifactId} |
147 | </Bundle-SymbolicName> | 132 | </Bundle-SymbolicName> |
148 | <Import-Package> | 133 | <Import-Package> |
149 | - !org.apache.http.*, | ||
150 | - !com.fasterxml.jackson.dataformat.*, | ||
151 | *,org.glassfish.jersey.servlet | 134 | *,org.glassfish.jersey.servlet |
152 | </Import-Package> | 135 | </Import-Package> |
153 | - <Embed-Dependency> | ||
154 | - openstack4j-core, | ||
155 | - openstack4j-http-connector, | ||
156 | - openstack4j-httpclient | ||
157 | - </Embed-Dependency> | ||
158 | <Web-ContextPath>${web.context}</Web-ContextPath> | 136 | <Web-ContextPath>${web.context}</Web-ContextPath> |
159 | </instructions> | 137 | </instructions> |
160 | </configuration> | 138 | </configuration> | ... | ... |
1 | -/* | ||
2 | - * Copyright 2015-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.cordvtn.api; | ||
17 | - | ||
18 | -import com.google.common.base.MoreObjects; | ||
19 | -import org.onlab.packet.IpAddress; | ||
20 | -import org.onlab.packet.IpPrefix; | ||
21 | -import org.onosproject.net.Host; | ||
22 | -import org.openstack4j.model.network.Network; | ||
23 | -import org.openstack4j.model.network.Subnet; | ||
24 | - | ||
25 | -import java.util.Map; | ||
26 | -import java.util.Objects; | ||
27 | -import java.util.Set; | ||
28 | - | ||
29 | -import static com.google.common.base.Preconditions.checkNotNull; | ||
30 | - | ||
31 | -public final class CordService { | ||
32 | - | ||
33 | - public enum ServiceType { | ||
34 | - PRIVATE, | ||
35 | - PUBLIC, | ||
36 | - MANAGEMENT | ||
37 | - } | ||
38 | - | ||
39 | - private final CordServiceId id; | ||
40 | - private final long segmentationId; | ||
41 | - private final ServiceType serviceType; | ||
42 | - private final IpPrefix serviceIpRange; | ||
43 | - private final IpAddress serviceIp; | ||
44 | - private final Map<Host, IpAddress> hosts; | ||
45 | - private final Set<CordServiceId> tenantServices; | ||
46 | - private final Set<CordServiceId> providerServices; | ||
47 | - | ||
48 | - /** | ||
49 | - * Default constructor. | ||
50 | - * | ||
51 | - * @param osNet OpenStack network | ||
52 | - * @param osSubnet OpenStack subnet | ||
53 | - * @param hosts host and tunnel ip map | ||
54 | - * @param tenantServices list of tenant service ids | ||
55 | - * @param providerServices list of provider service ids | ||
56 | - */ | ||
57 | - public CordService(Network osNet, Subnet osSubnet, | ||
58 | - Map<Host, IpAddress> hosts, Set<CordServiceId> tenantServices, | ||
59 | - Set<CordServiceId> providerServices) { | ||
60 | - this.id = CordServiceId.of(osNet.getId()); | ||
61 | - this.segmentationId = Long.parseLong(osNet.getProviderSegID()); | ||
62 | - this.serviceType = getServiceType(osNet.getName()); | ||
63 | - this.serviceIpRange = IpPrefix.valueOf(osSubnet.getCidr()); | ||
64 | - this.serviceIp = IpAddress.valueOf(osSubnet.getGateway()); | ||
65 | - this.hosts = hosts; | ||
66 | - this.tenantServices = tenantServices; | ||
67 | - this.providerServices = providerServices; | ||
68 | - } | ||
69 | - | ||
70 | - /** | ||
71 | - * Returns service ID. | ||
72 | - * | ||
73 | - * @return service id | ||
74 | - */ | ||
75 | - public CordServiceId id() { | ||
76 | - return id; | ||
77 | - } | ||
78 | - | ||
79 | - /** | ||
80 | - * Returns segmentation ID of this service. | ||
81 | - * | ||
82 | - * @return segmentation id | ||
83 | - */ | ||
84 | - public long segmentationId() { | ||
85 | - return segmentationId; | ||
86 | - } | ||
87 | - | ||
88 | - /** | ||
89 | - * Returns service type. | ||
90 | - * | ||
91 | - * @return service type | ||
92 | - */ | ||
93 | - public ServiceType serviceType() { | ||
94 | - return serviceType; | ||
95 | - } | ||
96 | - | ||
97 | - /** | ||
98 | - * Returns service IP range. | ||
99 | - * | ||
100 | - * @return CIDR | ||
101 | - */ | ||
102 | - public IpPrefix serviceIpRange() { | ||
103 | - return serviceIpRange; | ||
104 | - } | ||
105 | - | ||
106 | - /** | ||
107 | - * Returns service IP address. | ||
108 | - * | ||
109 | - * @return ip address | ||
110 | - */ | ||
111 | - public IpAddress serviceIp() { | ||
112 | - return serviceIp; | ||
113 | - } | ||
114 | - | ||
115 | - /** | ||
116 | - * Returns hosts associated with this service. | ||
117 | - * | ||
118 | - * @return list of hosts | ||
119 | - */ | ||
120 | - public Map<Host, IpAddress> hosts() { | ||
121 | - return hosts; | ||
122 | - } | ||
123 | - | ||
124 | - /** | ||
125 | - * Returns tenant service IDs. | ||
126 | - * | ||
127 | - * @return list of tenant service id | ||
128 | - */ | ||
129 | - public Set<CordServiceId> tenantServices() { | ||
130 | - return tenantServices; | ||
131 | - } | ||
132 | - | ||
133 | - /** | ||
134 | - * Returns provider service IDs. | ||
135 | - * | ||
136 | - * @return list of provider service id | ||
137 | - */ | ||
138 | - public Set<CordServiceId> providerServices() { | ||
139 | - return providerServices; | ||
140 | - } | ||
141 | - | ||
142 | - @Override | ||
143 | - public int hashCode() { | ||
144 | - return Objects.hash(id); | ||
145 | - } | ||
146 | - | ||
147 | - @Override | ||
148 | - public boolean equals(Object obj) { | ||
149 | - if (this == obj) { | ||
150 | - return true; | ||
151 | - } | ||
152 | - if (!(obj instanceof CordService)) { | ||
153 | - return false; | ||
154 | - } | ||
155 | - final CordService other = (CordService) obj; | ||
156 | - return Objects.equals(this.id, other.id); | ||
157 | - } | ||
158 | - | ||
159 | - @Override | ||
160 | - public String toString() { | ||
161 | - return MoreObjects.toStringHelper(this) | ||
162 | - .add("id", id) | ||
163 | - .add("segmentationId", segmentationId) | ||
164 | - .add("serviceType", serviceType) | ||
165 | - .add("serviceIpRange", serviceIpRange) | ||
166 | - .add("serviceIp", serviceIp) | ||
167 | - .add("tenantServices", tenantServices) | ||
168 | - .add("providerServices", providerServices) | ||
169 | - .toString(); | ||
170 | - } | ||
171 | - | ||
172 | - /** | ||
173 | - * Returns network type from network name. | ||
174 | - * It assumes that network name contains network type. | ||
175 | - * | ||
176 | - * @param netName network name | ||
177 | - * @return network type, or PRIVATE if it doesn't match any type | ||
178 | - */ | ||
179 | - private ServiceType getServiceType(String netName) { | ||
180 | - checkNotNull(netName); | ||
181 | - | ||
182 | - String name = netName.toUpperCase(); | ||
183 | - if (name.contains(ServiceType.PUBLIC.toString())) { | ||
184 | - return ServiceType.PUBLIC; | ||
185 | - } else if (name.contains(ServiceType.MANAGEMENT.toString())) { | ||
186 | - return ServiceType.MANAGEMENT; | ||
187 | - } else { | ||
188 | - return ServiceType.PRIVATE; | ||
189 | - } | ||
190 | - } | ||
191 | -} |
1 | -/* | ||
2 | - * Copyright 2015-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.cordvtn.api; | ||
17 | - | ||
18 | -import org.onlab.util.Identifier; | ||
19 | - | ||
20 | -import static com.google.common.base.Preconditions.checkNotNull; | ||
21 | - | ||
22 | -/** | ||
23 | - * Representation of service identifier. | ||
24 | - */ | ||
25 | -public final class CordServiceId extends Identifier<String> { | ||
26 | - /** | ||
27 | - * Default constructor. | ||
28 | - * | ||
29 | - * @param id service identifier | ||
30 | - */ | ||
31 | - private CordServiceId(String id) { | ||
32 | - super(id); | ||
33 | - } | ||
34 | - | ||
35 | - /** | ||
36 | - * Returns the CordServiceId with value. | ||
37 | - * | ||
38 | - * @param id service id | ||
39 | - * @return CordServiceId | ||
40 | - */ | ||
41 | - public static CordServiceId of(String id) { | ||
42 | - checkNotNull(id); | ||
43 | - return new CordServiceId(id); | ||
44 | - } | ||
45 | -} |
... | @@ -25,6 +25,7 @@ import org.onlab.packet.TpPort; | ... | @@ -25,6 +25,7 @@ import org.onlab.packet.TpPort; |
25 | import org.onosproject.core.ApplicationId; | 25 | import org.onosproject.core.ApplicationId; |
26 | import org.onosproject.net.DeviceId; | 26 | import org.onosproject.net.DeviceId; |
27 | import org.onosproject.net.config.Config; | 27 | import org.onosproject.net.config.Config; |
28 | +import org.onosproject.xosclient.api.OpenStackAccess; | ||
28 | import org.onosproject.xosclient.api.XosAccess; | 29 | import org.onosproject.xosclient.api.XosAccess; |
29 | import org.slf4j.Logger; | 30 | import org.slf4j.Logger; |
30 | 31 | ||
... | @@ -209,9 +210,9 @@ public class CordVtnConfig extends Config<ApplicationId> { | ... | @@ -209,9 +210,9 @@ public class CordVtnConfig extends Config<ApplicationId> { |
209 | /** | 210 | /** |
210 | * Returns OpenStack API access information. | 211 | * Returns OpenStack API access information. |
211 | * | 212 | * |
212 | - * @return openstack config | 213 | + * @return openstack access |
213 | */ | 214 | */ |
214 | - public OpenStackConfig openstackConfig() { | 215 | + public OpenStackAccess openstackAccess() { |
215 | JsonNode jsonNode = object.get(OPENSTACK); | 216 | JsonNode jsonNode = object.get(OPENSTACK); |
216 | if (jsonNode == null) { | 217 | if (jsonNode == null) { |
217 | log.error("Failed to get OpenStack configurations"); | 218 | log.error("Failed to get OpenStack configurations"); |
... | @@ -219,7 +220,7 @@ public class CordVtnConfig extends Config<ApplicationId> { | ... | @@ -219,7 +220,7 @@ public class CordVtnConfig extends Config<ApplicationId> { |
219 | } | 220 | } |
220 | 221 | ||
221 | try { | 222 | try { |
222 | - return new OpenStackConfig( | 223 | + return new OpenStackAccess( |
223 | jsonNode.path(ENDPOINT).asText(), | 224 | jsonNode.path(ENDPOINT).asText(), |
224 | jsonNode.path(TENANT).asText(), | 225 | jsonNode.path(TENANT).asText(), |
225 | jsonNode.path(USER).asText(), | 226 | jsonNode.path(USER).asText(), |
... | @@ -229,66 +230,4 @@ public class CordVtnConfig extends Config<ApplicationId> { | ... | @@ -229,66 +230,4 @@ public class CordVtnConfig extends Config<ApplicationId> { |
229 | return null; | 230 | return null; |
230 | } | 231 | } |
231 | } | 232 | } |
232 | - | ||
233 | - /** | ||
234 | - * Configuration for OpenStack API access. | ||
235 | - */ | ||
236 | - public static class OpenStackConfig { | ||
237 | - | ||
238 | - private final String endpoint; | ||
239 | - private final String tenant; | ||
240 | - private final String user; | ||
241 | - private final String password; | ||
242 | - | ||
243 | - /** | ||
244 | - * Default constructor. | ||
245 | - * | ||
246 | - * @param endpoint Keystone endpoint | ||
247 | - * @param tenant tenant name | ||
248 | - * @param user user name | ||
249 | - * @param password passwowrd | ||
250 | - */ | ||
251 | - public OpenStackConfig(String endpoint, String tenant, String user, String password) { | ||
252 | - this.endpoint = endpoint; | ||
253 | - this.tenant = tenant; | ||
254 | - this.user = user; | ||
255 | - this.password = password; | ||
256 | - } | ||
257 | - | ||
258 | - /** | ||
259 | - * Returns OpenStack API endpoint. | ||
260 | - * | ||
261 | - * @return endpoint | ||
262 | - */ | ||
263 | - public String endpoint() { | ||
264 | - return this.endpoint; | ||
265 | - } | ||
266 | - | ||
267 | - /** | ||
268 | - * Returns OpenStack tenant name. | ||
269 | - * | ||
270 | - * @return tenant name | ||
271 | - */ | ||
272 | - public String tenant() { | ||
273 | - return this.tenant; | ||
274 | - } | ||
275 | - | ||
276 | - /** | ||
277 | - * Returns OpenStack user. | ||
278 | - * | ||
279 | - * @return user name | ||
280 | - */ | ||
281 | - public String user() { | ||
282 | - return this.user; | ||
283 | - } | ||
284 | - | ||
285 | - /** | ||
286 | - * Returns OpenStack password for the user. | ||
287 | - * | ||
288 | - * @return password | ||
289 | - */ | ||
290 | - public String password() { | ||
291 | - return this.password; | ||
292 | - } | ||
293 | - } | ||
294 | } | 233 | } | ... | ... |
... | @@ -19,6 +19,7 @@ import org.onlab.packet.IpAddress; | ... | @@ -19,6 +19,7 @@ import org.onlab.packet.IpAddress; |
19 | import org.onlab.packet.MacAddress; | 19 | import org.onlab.packet.MacAddress; |
20 | import org.onosproject.net.ConnectPoint; | 20 | import org.onosproject.net.ConnectPoint; |
21 | import org.onosproject.net.HostId; | 21 | import org.onosproject.net.HostId; |
22 | +import org.onosproject.xosclient.api.VtnServiceId; | ||
22 | 23 | ||
23 | import java.util.Map; | 24 | import java.util.Map; |
24 | 25 | ||
... | @@ -51,8 +52,7 @@ public interface CordVtnService { | ... | @@ -51,8 +52,7 @@ public interface CordVtnService { |
51 | * @param pServiceId id of the service which provide dependency | 52 | * @param pServiceId id of the service which provide dependency |
52 | * @param isBidirectional true to enable bidirectional connectivity between two services | 53 | * @param isBidirectional true to enable bidirectional connectivity between two services |
53 | */ | 54 | */ |
54 | - void createServiceDependency(CordServiceId tServiceId, | 55 | + void createServiceDependency(VtnServiceId tServiceId, VtnServiceId pServiceId, |
55 | - CordServiceId pServiceId, | ||
56 | boolean isBidirectional); | 56 | boolean isBidirectional); |
57 | 57 | ||
58 | /** | 58 | /** |
... | @@ -61,7 +61,7 @@ public interface CordVtnService { | ... | @@ -61,7 +61,7 @@ public interface CordVtnService { |
61 | * @param tServiceId id of the service which has a dependency | 61 | * @param tServiceId id of the service which has a dependency |
62 | * @param pServiceId id of the service which provide dependency | 62 | * @param pServiceId id of the service which provide dependency |
63 | */ | 63 | */ |
64 | - void removeServiceDependency(CordServiceId tServiceId, CordServiceId pServiceId); | 64 | + void removeServiceDependency(VtnServiceId tServiceId, VtnServiceId pServiceId); |
65 | 65 | ||
66 | /** | 66 | /** |
67 | * Updates virtual service gateways. | 67 | * Updates virtual service gateways. | ... | ... |
... | @@ -15,6 +15,7 @@ | ... | @@ -15,6 +15,7 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.cordvtn.impl; | 16 | package org.onosproject.cordvtn.impl; |
17 | 17 | ||
18 | +import com.google.common.base.Strings; | ||
18 | import com.google.common.collect.Lists; | 19 | import com.google.common.collect.Lists; |
19 | import com.google.common.collect.Maps; | 20 | import com.google.common.collect.Maps; |
20 | import com.google.common.collect.Sets; | 21 | import com.google.common.collect.Sets; |
... | @@ -29,8 +30,6 @@ import org.onlab.packet.Ip4Address; | ... | @@ -29,8 +30,6 @@ import org.onlab.packet.Ip4Address; |
29 | import org.onlab.packet.IpAddress; | 30 | import org.onlab.packet.IpAddress; |
30 | import org.onlab.packet.MacAddress; | 31 | import org.onlab.packet.MacAddress; |
31 | import org.onlab.packet.VlanId; | 32 | import org.onlab.packet.VlanId; |
32 | -import org.onosproject.cordvtn.api.CordService; | ||
33 | -import org.onosproject.cordvtn.api.CordServiceId; | ||
34 | import org.onosproject.cordvtn.api.CordVtnConfig; | 33 | import org.onosproject.cordvtn.api.CordVtnConfig; |
35 | import org.onosproject.cordvtn.api.CordVtnNode; | 34 | import org.onosproject.cordvtn.api.CordVtnNode; |
36 | import org.onosproject.cordvtn.api.CordVtnService; | 35 | import org.onosproject.cordvtn.api.CordVtnService; |
... | @@ -48,7 +47,6 @@ import org.onosproject.net.config.ConfigFactory; | ... | @@ -48,7 +47,6 @@ import org.onosproject.net.config.ConfigFactory; |
48 | import org.onosproject.net.config.NetworkConfigEvent; | 47 | import org.onosproject.net.config.NetworkConfigEvent; |
49 | import org.onosproject.net.config.NetworkConfigListener; | 48 | import org.onosproject.net.config.NetworkConfigListener; |
50 | import org.onosproject.net.config.NetworkConfigRegistry; | 49 | import org.onosproject.net.config.NetworkConfigRegistry; |
51 | -import org.onosproject.net.config.NetworkConfigService; | ||
52 | import org.onosproject.net.config.basics.SubjectFactories; | 50 | import org.onosproject.net.config.basics.SubjectFactories; |
53 | import org.onosproject.net.device.DeviceService; | 51 | import org.onosproject.net.device.DeviceService; |
54 | import org.onosproject.net.flow.FlowRuleService; | 52 | import org.onosproject.net.flow.FlowRuleService; |
... | @@ -66,16 +64,15 @@ import org.onosproject.net.packet.PacketProcessor; | ... | @@ -66,16 +64,15 @@ import org.onosproject.net.packet.PacketProcessor; |
66 | import org.onosproject.net.packet.PacketService; | 64 | import org.onosproject.net.packet.PacketService; |
67 | import org.onosproject.net.provider.AbstractProvider; | 65 | import org.onosproject.net.provider.AbstractProvider; |
68 | import org.onosproject.net.provider.ProviderId; | 66 | import org.onosproject.net.provider.ProviderId; |
67 | +import org.onosproject.xosclient.api.OpenStackAccess; | ||
68 | +import org.onosproject.xosclient.api.VtnPort; | ||
69 | +import org.onosproject.xosclient.api.VtnPortApi; | ||
70 | +import org.onosproject.xosclient.api.VtnPortId; | ||
71 | +import org.onosproject.xosclient.api.VtnService; | ||
69 | import org.onosproject.xosclient.api.VtnServiceApi; | 72 | import org.onosproject.xosclient.api.VtnServiceApi; |
70 | import org.onosproject.xosclient.api.VtnServiceId; | 73 | import org.onosproject.xosclient.api.VtnServiceId; |
71 | import org.onosproject.xosclient.api.XosAccess; | 74 | import org.onosproject.xosclient.api.XosAccess; |
72 | import org.onosproject.xosclient.api.XosClientService; | 75 | import org.onosproject.xosclient.api.XosClientService; |
73 | -import org.openstack4j.api.OSClient; | ||
74 | -import org.openstack4j.api.exceptions.AuthenticationException; | ||
75 | -import org.openstack4j.model.identity.Access; | ||
76 | -import org.openstack4j.model.network.Network; | ||
77 | -import org.openstack4j.model.network.Subnet; | ||
78 | -import org.openstack4j.openstack.OSFactory; | ||
79 | import org.slf4j.Logger; | 76 | import org.slf4j.Logger; |
80 | 77 | ||
81 | import java.util.List; | 78 | import java.util.List; |
... | @@ -108,9 +105,6 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -108,9 +105,6 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
108 | protected NetworkConfigRegistry configRegistry; | 105 | protected NetworkConfigRegistry configRegistry; |
109 | 106 | ||
110 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 107 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
111 | - protected NetworkConfigService configService; | ||
112 | - | ||
113 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
114 | protected HostProviderRegistry hostProviderRegistry; | 108 | protected HostProviderRegistry hostProviderRegistry; |
115 | 109 | ||
116 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 110 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
... | @@ -145,14 +139,17 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -145,14 +139,17 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
145 | } | 139 | } |
146 | }; | 140 | }; |
147 | 141 | ||
142 | + private static final String XOS_ACCESS_ERROR = "XOS access is not configured"; | ||
143 | + private static final String OPENSTACK_ACCESS_ERROR = "OpenStack access is not configured"; | ||
144 | + | ||
148 | private static final String DEFAULT_TUNNEL = "vxlan"; | 145 | private static final String DEFAULT_TUNNEL = "vxlan"; |
149 | private static final String SERVICE_ID = "serviceId"; | 146 | private static final String SERVICE_ID = "serviceId"; |
150 | - private static final String OPENSTACK_PORT_ID = "openstackPortId"; | 147 | + private static final String PORT_ID = "vtnPortId"; |
151 | private static final String DATA_PLANE_IP = "dataPlaneIp"; | 148 | private static final String DATA_PLANE_IP = "dataPlaneIp"; |
152 | private static final String DATA_PLANE_INTF = "dataPlaneIntf"; | 149 | private static final String DATA_PLANE_INTF = "dataPlaneIntf"; |
153 | private static final String S_TAG = "stag"; | 150 | private static final String S_TAG = "stag"; |
154 | private static final String VSG_HOST_ID = "vsgHostId"; | 151 | private static final String VSG_HOST_ID = "vsgHostId"; |
155 | - private static final String CREATED_TIME = "createdTime"; | 152 | + private static final String CREATE_TIME = "createTime"; |
156 | 153 | ||
157 | private static final Ip4Address DEFAULT_DNS = Ip4Address.valueOf("8.8.8.8"); | 154 | private static final Ip4Address DEFAULT_DNS = Ip4Address.valueOf("8.8.8.8"); |
158 | 155 | ||
... | @@ -169,7 +166,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -169,7 +166,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
169 | private CordVtnArpProxy arpProxy; | 166 | private CordVtnArpProxy arpProxy; |
170 | 167 | ||
171 | private volatile XosAccess xosAccess = null; | 168 | private volatile XosAccess xosAccess = null; |
172 | - private volatile Access osAccess = null; | 169 | + private volatile OpenStackAccess osAccess = null; |
173 | private volatile MacAddress privateGatewayMac = MacAddress.NONE; | 170 | private volatile MacAddress privateGatewayMac = MacAddress.NONE; |
174 | 171 | ||
175 | /** | 172 | /** |
... | @@ -185,6 +182,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -185,6 +182,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
185 | ruleInstaller = new CordVtnRuleInstaller(appId, flowRuleService, | 182 | ruleInstaller = new CordVtnRuleInstaller(appId, flowRuleService, |
186 | deviceService, | 183 | deviceService, |
187 | groupService, | 184 | groupService, |
185 | + hostService, | ||
188 | configRegistry, | 186 | configRegistry, |
189 | DEFAULT_TUNNEL); | 187 | DEFAULT_TUNNEL); |
190 | 188 | ||
... | @@ -196,7 +194,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -196,7 +194,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
196 | hostProvider = hostProviderRegistry.register(this); | 194 | hostProvider = hostProviderRegistry.register(this); |
197 | 195 | ||
198 | configRegistry.registerConfigFactory(configFactory); | 196 | configRegistry.registerConfigFactory(configFactory); |
199 | - configService.addListener(configListener); | 197 | + configRegistry.addListener(configListener); |
200 | 198 | ||
201 | log.info("Started"); | 199 | log.info("Started"); |
202 | } | 200 | } |
... | @@ -209,7 +207,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -209,7 +207,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
209 | packetService.removeProcessor(packetProcessor); | 207 | packetService.removeProcessor(packetProcessor); |
210 | 208 | ||
211 | configRegistry.unregisterConfigFactory(configFactory); | 209 | configRegistry.unregisterConfigFactory(configFactory); |
212 | - configService.removeListener(configListener); | 210 | + configRegistry.removeListener(configListener); |
213 | 211 | ||
214 | eventExecutor.shutdown(); | 212 | eventExecutor.shutdown(); |
215 | log.info("Stopped"); | 213 | log.info("Stopped"); |
... | @@ -224,88 +222,85 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -224,88 +222,85 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
224 | } | 222 | } |
225 | 223 | ||
226 | @Override | 224 | @Override |
227 | - public void createServiceDependency(CordServiceId tServiceId, CordServiceId pServiceId, | 225 | + public void createServiceDependency(VtnServiceId tServiceId, VtnServiceId pServiceId, |
228 | boolean isBidirectional) { | 226 | boolean isBidirectional) { |
229 | - CordService tService = getCordService(tServiceId); | 227 | + checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR); |
230 | - CordService pService = getCordService(pServiceId); | 228 | + checkNotNull(xosAccess, XOS_ACCESS_ERROR); |
229 | + | ||
230 | + // TODO remove openstack access when XOS provides all information | ||
231 | + VtnServiceApi serviceApi = xosClient.getClient(xosAccess).vtnService(); | ||
232 | + VtnService tService = serviceApi.service(tServiceId, osAccess); | ||
233 | + VtnService pService = serviceApi.service(pServiceId, osAccess); | ||
231 | 234 | ||
232 | if (tService == null || pService == null) { | 235 | if (tService == null || pService == null) { |
233 | - log.error("Failed to create CordService for {}", tServiceId.id()); | 236 | + log.error("Failed to create dependency between {} and {}", |
237 | + tServiceId, pServiceId); | ||
234 | return; | 238 | return; |
235 | } | 239 | } |
236 | 240 | ||
237 | - log.info("Service dependency from {} to {} created.", tService.id().id(), pService.id().id()); | 241 | + log.info("Created dependency between {} and {}", tService.name(), pService.name()); |
238 | ruleInstaller.populateServiceDependencyRules(tService, pService, isBidirectional, true); | 242 | ruleInstaller.populateServiceDependencyRules(tService, pService, isBidirectional, true); |
239 | } | 243 | } |
240 | 244 | ||
241 | @Override | 245 | @Override |
242 | - public void removeServiceDependency(CordServiceId tServiceId, CordServiceId pServiceId) { | 246 | + public void removeServiceDependency(VtnServiceId tServiceId, VtnServiceId pServiceId) { |
243 | - CordService tService = getCordService(tServiceId); | 247 | + checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR); |
244 | - CordService pService = getCordService(pServiceId); | 248 | + checkNotNull(xosAccess, XOS_ACCESS_ERROR); |
249 | + | ||
250 | + // TODO remove openstack access when XOS provides all information | ||
251 | + VtnServiceApi serviceApi = xosClient.getClient(xosAccess).vtnService(); | ||
252 | + VtnService tService = serviceApi.service(tServiceId, osAccess); | ||
253 | + VtnService pService = serviceApi.service(pServiceId, osAccess); | ||
245 | 254 | ||
246 | if (tService == null || pService == null) { | 255 | if (tService == null || pService == null) { |
247 | - log.error("Failed to create CordService for {}", tServiceId.id()); | 256 | + log.error("Failed to remove dependency between {} and {}", |
257 | + tServiceId, pServiceId); | ||
248 | return; | 258 | return; |
249 | } | 259 | } |
250 | 260 | ||
251 | - log.info("Service dependency from {} to {} removed.", tService.id().id(), pService.id().id()); | 261 | + log.info("Removed dependency between {} and {}", tService.name(), pService.name()); |
252 | ruleInstaller.populateServiceDependencyRules(tService, pService, true, false); | 262 | ruleInstaller.populateServiceDependencyRules(tService, pService, true, false); |
253 | } | 263 | } |
254 | 264 | ||
255 | @Override | 265 | @Override |
256 | public void addServiceVm(CordVtnNode node, ConnectPoint connectPoint) { | 266 | public void addServiceVm(CordVtnNode node, ConnectPoint connectPoint) { |
257 | - checkNotNull(osAccess, "OpenStack access is not set"); | 267 | + checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR); |
268 | + checkNotNull(xosAccess, XOS_ACCESS_ERROR); | ||
258 | 269 | ||
259 | - OSClient osClient = OSFactory.clientFromAccess(osAccess); | ||
260 | Port port = deviceService.getPort(connectPoint.deviceId(), connectPoint.port()); | 270 | Port port = deviceService.getPort(connectPoint.deviceId(), connectPoint.port()); |
261 | - org.openstack4j.model.network.Port osPort = osClient.networking().port().list() | 271 | + String portName = port.annotations().value("portName"); |
262 | - .stream() | ||
263 | - .filter(p -> p.getId().contains(getPortName(port).substring(3))) | ||
264 | - .findFirst().orElse(null); | ||
265 | - if (osPort == null) { | ||
266 | - log.warn("Failed to get OpenStack port for {}", getPortName(port)); | ||
267 | - return; | ||
268 | - } | ||
269 | - | ||
270 | - MacAddress mac = MacAddress.valueOf(osPort.getMacAddress()); | ||
271 | - HostId hostId = HostId.hostId(mac); | ||
272 | 272 | ||
273 | - Host existingHost = hostService.getHost(hostId); | 273 | + // TODO remove openstack access when XOS provides all information |
274 | - if (existingHost != null) { | 274 | + VtnPortApi portApi = xosClient.getClient(xosAccess).vtnPort(); |
275 | - String serviceId = existingHost.annotations().value(SERVICE_ID); | 275 | + VtnPort vtnPort = portApi.vtnPort(portName, osAccess); |
276 | - if (serviceId == null || !serviceId.equals(osPort.getNetworkId())) { | 276 | + if (vtnPort == null) { |
277 | - // this host is not injected by cordvtn or a stale host, remove it | 277 | + log.warn("Failed to get port information of {}", portName); |
278 | - hostProvider.hostVanished(existingHost.id()); | 278 | + return; |
279 | - } | ||
280 | } | 279 | } |
281 | 280 | ||
282 | - // Included CREATED_TIME to annotation intentionally to trigger HOST_UPDATED | 281 | + // Added CREATE_TIME intentionally to trigger HOST_UPDATED event for the |
283 | - // event so that the flow rule population for this host can happen. | 282 | + // existing instances. |
284 | - // This ensures refreshing data plane by pushing network config always make | ||
285 | - // the data plane synced. | ||
286 | - Set<IpAddress> fixedIps = osPort.getFixedIps().stream() | ||
287 | - .map(ip -> IpAddress.valueOf(ip.getIpAddress())) | ||
288 | - .collect(Collectors.toSet()); | ||
289 | - | ||
290 | DefaultAnnotations.Builder annotations = DefaultAnnotations.builder() | 283 | DefaultAnnotations.Builder annotations = DefaultAnnotations.builder() |
291 | - .set(SERVICE_ID, osPort.getNetworkId()) | 284 | + .set(SERVICE_ID, vtnPort.serviceId().id()) |
292 | - .set(OPENSTACK_PORT_ID, osPort.getId()) | 285 | + .set(PORT_ID, vtnPort.id().id()) |
293 | .set(DATA_PLANE_IP, node.dpIp().ip().toString()) | 286 | .set(DATA_PLANE_IP, node.dpIp().ip().toString()) |
294 | .set(DATA_PLANE_INTF, node.dpIntf()) | 287 | .set(DATA_PLANE_INTF, node.dpIntf()) |
295 | - .set(CREATED_TIME, String.valueOf(System.currentTimeMillis())); | 288 | + .set(CREATE_TIME, String.valueOf(System.currentTimeMillis())); |
296 | 289 | ||
297 | - String serviceVlan = getServiceVlan(osPort); | 290 | + // TODO address service specific task in a separate package |
298 | - if (serviceVlan != null) { | 291 | + String serviceVlan = getServiceVlan(vtnPort); |
292 | + if (!Strings.isNullOrEmpty(serviceVlan)) { | ||
299 | annotations.set(S_TAG, serviceVlan); | 293 | annotations.set(S_TAG, serviceVlan); |
300 | } | 294 | } |
301 | 295 | ||
302 | HostDescription hostDesc = new DefaultHostDescription( | 296 | HostDescription hostDesc = new DefaultHostDescription( |
303 | - mac, | 297 | + vtnPort.mac(), |
304 | VlanId.NONE, | 298 | VlanId.NONE, |
305 | new HostLocation(connectPoint, System.currentTimeMillis()), | 299 | new HostLocation(connectPoint, System.currentTimeMillis()), |
306 | - fixedIps, | 300 | + Sets.newHashSet(vtnPort.ip()), |
307 | annotations.build()); | 301 | annotations.build()); |
308 | 302 | ||
303 | + HostId hostId = HostId.hostId(vtnPort.mac()); | ||
309 | hostProvider.hostDetected(hostId, hostDesc, false); | 304 | hostProvider.hostDetected(hostId, hostDesc, false); |
310 | } | 305 | } |
311 | 306 | ||
... | @@ -317,6 +312,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -317,6 +312,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
317 | } | 312 | } |
318 | 313 | ||
319 | @Override | 314 | @Override |
315 | + // TODO address service specific task in a separate package | ||
320 | public void updateVirtualSubscriberGateways(HostId vSgHostId, String serviceVlan, | 316 | public void updateVirtualSubscriberGateways(HostId vSgHostId, String serviceVlan, |
321 | Map<IpAddress, MacAddress> vSgs) { | 317 | Map<IpAddress, MacAddress> vSgs) { |
322 | Host vSgHost = hostService.getHost(vSgHostId); | 318 | Host vSgHost = hostService.getHost(vSgHostId); |
... | @@ -351,6 +347,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -351,6 +347,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
351 | * @param vSgMac vSG mac address | 347 | * @param vSgMac vSG mac address |
352 | * @param serviceVlan service vlan | 348 | * @param serviceVlan service vlan |
353 | */ | 349 | */ |
350 | + // TODO address service specific task in a separate package | ||
354 | private void addVirtualSubscriberGateway(Host vSgHost, IpAddress vSgIp, MacAddress vSgMac, | 351 | private void addVirtualSubscriberGateway(Host vSgHost, IpAddress vSgIp, MacAddress vSgMac, |
355 | String serviceVlan) { | 352 | String serviceVlan) { |
356 | log.info("vSG with IP({}) MAC({}) added", vSgIp.toString(), vSgMac.toString()); | 353 | log.info("vSG with IP({}) MAC({}) added", vSgIp.toString(), vSgMac.toString()); |
... | @@ -359,7 +356,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -359,7 +356,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
359 | DefaultAnnotations.Builder annotations = DefaultAnnotations.builder() | 356 | DefaultAnnotations.Builder annotations = DefaultAnnotations.builder() |
360 | .set(S_TAG, serviceVlan) | 357 | .set(S_TAG, serviceVlan) |
361 | .set(VSG_HOST_ID, vSgHost.id().toString()) | 358 | .set(VSG_HOST_ID, vSgHost.id().toString()) |
362 | - .set(CREATED_TIME, String.valueOf(System.currentTimeMillis())); | 359 | + .set(CREATE_TIME, String.valueOf(System.currentTimeMillis())); |
363 | 360 | ||
364 | HostDescription hostDesc = new DefaultHostDescription( | 361 | HostDescription hostDesc = new DefaultHostDescription( |
365 | vSgMac, | 362 | vSgMac, |
... | @@ -377,125 +374,45 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -377,125 +374,45 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
377 | * @param vSgHost vSG host | 374 | * @param vSgHost vSG host |
378 | * @return map of ip and mac address, or empty map | 375 | * @return map of ip and mac address, or empty map |
379 | */ | 376 | */ |
377 | + // TODO address service specific task in a separate package | ||
380 | private Map<IpAddress, MacAddress> getSubscriberGateways(Host vSgHost) { | 378 | private Map<IpAddress, MacAddress> getSubscriberGateways(Host vSgHost) { |
381 | - checkNotNull(osAccess, "OpenStack access is not set"); | 379 | + checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR); |
380 | + checkNotNull(xosAccess, XOS_ACCESS_ERROR); | ||
382 | 381 | ||
383 | - String osPortId = vSgHost.annotations().value(OPENSTACK_PORT_ID); | 382 | + String vtnPortId = vSgHost.annotations().value(PORT_ID); |
384 | - String serviceVlan = vSgHost.annotations().value(S_TAG); | 383 | + String sTag = vSgHost.annotations().value(S_TAG); |
385 | 384 | ||
386 | - OSClient osClient = OSFactory.clientFromAccess(osAccess); | 385 | + if (Strings.isNullOrEmpty(vtnPortId) || Strings.isNullOrEmpty(sTag)) { |
387 | - org.openstack4j.model.network.Port osPort = osClient.networking().port().get(osPortId); | 386 | + log.warn("PORT_ID and S_TAG is not set, ignore {}", vSgHost); |
388 | - if (osPort == null) { | ||
389 | - log.warn("Failed to get OpenStack port {} for VM {}", osPortId, vSgHost.id()); | ||
390 | return Maps.newHashMap(); | 387 | return Maps.newHashMap(); |
391 | } | 388 | } |
392 | 389 | ||
393 | - if (!serviceVlan.equals(getServiceVlan(osPort))) { | 390 | + // TODO remove openstack access when XOS provides all information |
394 | - log.error("Host({}) s-tag does not match with OpenStack port s-tag", vSgHost.id()); | 391 | + VtnPortApi portApi = xosClient.getClient(xosAccess).vtnPort(); |
392 | + VtnPort vtnPort = portApi.vtnPort(VtnPortId.of(vtnPortId), osAccess); | ||
393 | + if (vtnPort == null) { | ||
394 | + log.warn("Failed to get port information of {}", vSgHost); | ||
395 | return Maps.newHashMap(); | 395 | return Maps.newHashMap(); |
396 | } | 396 | } |
397 | 397 | ||
398 | - Map<IpAddress, MacAddress> addressPairs = Maps.newHashMap(); | 398 | + if (!sTag.equals(getServiceVlan(vtnPort))) { |
399 | - osPort.getAllowedAddressPairs() | 399 | + log.error("Host({}) s-tag does not match with VTN port s-tag", vSgHost); |
400 | - .stream().forEach(p -> addressPairs.put( | 400 | + return Maps.newHashMap(); |
401 | - IpAddress.valueOf(p.getIpAddress()), | ||
402 | - MacAddress.valueOf(p.getMacAddress()))); | ||
403 | - | ||
404 | - return addressPairs; | ||
405 | - } | ||
406 | - | ||
407 | - /** | ||
408 | - * Returns CordService by service ID. | ||
409 | - * | ||
410 | - * @param serviceId service id | ||
411 | - * @return cord service, or null if it fails to get network from OpenStack | ||
412 | - */ | ||
413 | - private CordService getCordService(CordServiceId serviceId) { | ||
414 | - checkNotNull(osAccess, "OpenStack access is not set"); | ||
415 | - | ||
416 | - OSClient osClient = OSFactory.clientFromAccess(osAccess); | ||
417 | - Network osNet = osClient.networking().network().get(serviceId.id()); | ||
418 | - if (osNet == null) { | ||
419 | - log.warn("Couldn't find OpenStack network for service {}", serviceId.id()); | ||
420 | - return null; | ||
421 | - } | ||
422 | - | ||
423 | - return getCordService(osNet); | ||
424 | - } | ||
425 | - | ||
426 | - /** | ||
427 | - * Returns CordService by OpenStack network. | ||
428 | - * | ||
429 | - * @param osNet OpenStack network | ||
430 | - * @return cord service | ||
431 | - */ | ||
432 | - private CordService getCordService(Network osNet) { | ||
433 | - checkNotNull(osNet); | ||
434 | - | ||
435 | - CordServiceId serviceId = CordServiceId.of(osNet.getId()); | ||
436 | - // here it assumes all cord service networks has only one subnet | ||
437 | - Subnet osSubnet = osNet.getNeutronSubnets().stream() | ||
438 | - .findFirst().orElse(null); | ||
439 | - if (osSubnet == null) { | ||
440 | - log.warn("Couldn't find OpenStack subnet for network {}", serviceId.id()); | ||
441 | - return null; | ||
442 | - } | ||
443 | - | ||
444 | - Map<Host, IpAddress> hosts = getHostsWithOpenstackNetwork(osNet) | ||
445 | - .stream() | ||
446 | - .collect(Collectors.toMap(host -> host, this::getTunnelIp)); | ||
447 | - | ||
448 | - // allows working without XOS for now | ||
449 | - Set<CordServiceId> tServices = Sets.newHashSet(); | ||
450 | - Set<CordServiceId> pServices = Sets.newHashSet(); | ||
451 | - | ||
452 | - if (xosAccess != null) { | ||
453 | - VtnServiceApi vtnServiceApi = xosClient.getClient(xosAccess).vtnService(); | ||
454 | - tServices = vtnServiceApi.tenantServices(VtnServiceId.of(serviceId.id())) | ||
455 | - .stream() | ||
456 | - .map(id -> CordServiceId.of(id.id())) | ||
457 | - .collect(Collectors.toSet()); | ||
458 | - | ||
459 | - pServices = vtnServiceApi.providerServices(VtnServiceId.of(serviceId.id())) | ||
460 | - .stream() | ||
461 | - .map(id -> CordServiceId.of(id.id())) | ||
462 | - .collect(Collectors.toSet()); | ||
463 | - } | ||
464 | - | ||
465 | - return new CordService(osNet, osSubnet, hosts, tServices, pServices); | ||
466 | - } | ||
467 | - | ||
468 | - /** | ||
469 | - * Returns IP address for tunneling for a given host. | ||
470 | - * | ||
471 | - * @param host host | ||
472 | - * @return ip address, or null | ||
473 | - */ | ||
474 | - private IpAddress getTunnelIp(Host host) { | ||
475 | - String ip = host.annotations().value(DATA_PLANE_IP); | ||
476 | - return ip == null ? null : IpAddress.valueOf(ip); | ||
477 | } | 401 | } |
478 | - | 402 | + return vtnPort.addressPairs(); |
479 | - /** | ||
480 | - * Returns port name. | ||
481 | - * | ||
482 | - * @param port port | ||
483 | - * @return port name | ||
484 | - */ | ||
485 | - private String getPortName(Port port) { | ||
486 | - return port.annotations().value("portName"); | ||
487 | } | 403 | } |
488 | 404 | ||
489 | /** | 405 | /** |
490 | - * Returns s-tag from a given OpenStack port. | 406 | + * Returns s-tag from a given VTN port. |
491 | * | 407 | * |
492 | - * @param osPort openstack port | 408 | + * @param vtnPort vtn port |
493 | * @return s-tag string | 409 | * @return s-tag string |
494 | */ | 410 | */ |
495 | - private String getServiceVlan(org.openstack4j.model.network.Port osPort) { | 411 | + // TODO address service specific task in a separate package |
496 | - checkNotNull(osPort); | 412 | + private String getServiceVlan(VtnPort vtnPort) { |
413 | + checkNotNull(vtnPort); | ||
497 | 414 | ||
498 | - String portName = osPort.getName(); | 415 | + String portName = vtnPort.name(); |
499 | if (portName != null && portName.startsWith(S_TAG)) { | 416 | if (portName != null && portName.startsWith(S_TAG)) { |
500 | return portName.split("-")[1]; | 417 | return portName.split("-")[1]; |
501 | } else { | 418 | } else { |
... | @@ -504,27 +421,16 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -504,27 +421,16 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
504 | } | 421 | } |
505 | 422 | ||
506 | /** | 423 | /** |
507 | - * Returns service ID of this host. | 424 | + * Returns instances with a given network service. |
508 | - * | ||
509 | - * @param host host | ||
510 | - * @return service id, or null if not found | ||
511 | - */ | ||
512 | - private String getServiceId(Host host) { | ||
513 | - return host.annotations().value(SERVICE_ID); | ||
514 | - } | ||
515 | - | ||
516 | - /** | ||
517 | - * Returns hosts associated with a given OpenStack network. | ||
518 | * | 425 | * |
519 | - * @param osNet openstack network | 426 | + * @param serviceId service id |
520 | * @return set of hosts | 427 | * @return set of hosts |
521 | */ | 428 | */ |
522 | - private Set<Host> getHostsWithOpenstackNetwork(Network osNet) { | 429 | + private Set<Host> getInstances(VtnServiceId serviceId) { |
523 | - checkNotNull(osNet); | ||
524 | - | ||
525 | - String osNetId = osNet.getId(); | ||
526 | return StreamSupport.stream(hostService.getHosts().spliterator(), false) | 430 | return StreamSupport.stream(hostService.getHosts().spliterator(), false) |
527 | - .filter(host -> Objects.equals(osNetId, getServiceId(host))) | 431 | + .filter(host -> Objects.equals( |
432 | + serviceId.id(), | ||
433 | + host.annotations().value(SERVICE_ID))) | ||
528 | .collect(Collectors.toSet()); | 434 | .collect(Collectors.toSet()); |
529 | } | 435 | } |
530 | 436 | ||
... | @@ -534,9 +440,9 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -534,9 +440,9 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
534 | * @param host host | 440 | * @param host host |
535 | * @param service cord service | 441 | * @param service cord service |
536 | */ | 442 | */ |
537 | - private void registerDhcpLease(Host host, CordService service) { | 443 | + private void registerDhcpLease(Host host, VtnService service) { |
538 | List<Ip4Address> options = Lists.newArrayList(); | 444 | List<Ip4Address> options = Lists.newArrayList(); |
539 | - options.add(Ip4Address.makeMaskPrefix(service.serviceIpRange().prefixLength())); | 445 | + options.add(Ip4Address.makeMaskPrefix(service.subnet().prefixLength())); |
540 | options.add(service.serviceIp().getIp4Address()); | 446 | options.add(service.serviceIp().getIp4Address()); |
541 | options.add(service.serviceIp().getIp4Address()); | 447 | options.add(service.serviceIp().getIp4Address()); |
542 | options.add(DEFAULT_DNS); | 448 | options.add(DEFAULT_DNS); |
... | @@ -554,28 +460,32 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -554,28 +460,32 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
554 | * @param host host | 460 | * @param host host |
555 | */ | 461 | */ |
556 | private void serviceVmAdded(Host host) { | 462 | private void serviceVmAdded(Host host) { |
557 | - checkNotNull(osAccess, "OpenStack access is not set"); | 463 | + checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR); |
464 | + checkNotNull(xosAccess, XOS_ACCESS_ERROR); | ||
558 | 465 | ||
466 | + // TODO address service specific task in a separate package | ||
559 | String serviceVlan = host.annotations().value(S_TAG); | 467 | String serviceVlan = host.annotations().value(S_TAG); |
560 | if (serviceVlan != null) { | 468 | if (serviceVlan != null) { |
561 | virtualSubscriberGatewayAdded(host, serviceVlan); | 469 | virtualSubscriberGatewayAdded(host, serviceVlan); |
562 | } | 470 | } |
563 | 471 | ||
564 | String serviceId = host.annotations().value(SERVICE_ID); | 472 | String serviceId = host.annotations().value(SERVICE_ID); |
565 | - if (serviceId == null) { | 473 | + if (Strings.isNullOrEmpty(serviceId)) { |
566 | - // ignore this host, it is not a service VM | 474 | + // ignore this host, it is not a service instance |
567 | return; | 475 | return; |
568 | } | 476 | } |
569 | 477 | ||
570 | - log.info("VM is detected, MAC: {} IP: {}", host.mac(), host.ipAddresses()); | 478 | + log.info("Instance is detected {}", host); |
571 | 479 | ||
572 | - CordService service = getCordService(CordServiceId.of(serviceId)); | 480 | + // TODO remove openstack access when XOS provides all information |
481 | + VtnServiceApi serviceApi = xosClient.getClient(xosAccess).vtnService(); | ||
482 | + VtnService service = serviceApi.service(VtnServiceId.of(serviceId), osAccess); | ||
573 | if (service == null) { | 483 | if (service == null) { |
574 | - log.warn("Failed to get CordService for {}", serviceId); | 484 | + log.warn("Failed to get VtnService for {}", serviceId); |
575 | return; | 485 | return; |
576 | } | 486 | } |
577 | 487 | ||
578 | - switch (service.serviceType()) { | 488 | + switch (service.networkType()) { |
579 | case MANAGEMENT: | 489 | case MANAGEMENT: |
580 | ruleInstaller.populateManagementNetworkRules(host, service); | 490 | ruleInstaller.populateManagementNetworkRules(host, service); |
581 | break; | 491 | break; |
... | @@ -606,32 +516,36 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -606,32 +516,36 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
606 | * @param host host | 516 | * @param host host |
607 | */ | 517 | */ |
608 | private void serviceVmRemoved(Host host) { | 518 | private void serviceVmRemoved(Host host) { |
609 | - checkNotNull(osAccess, "OpenStack access is not set"); | 519 | + checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR); |
520 | + checkNotNull(xosAccess, XOS_ACCESS_ERROR); | ||
610 | 521 | ||
522 | + // TODO address service specific task in a separate package | ||
611 | if (host.annotations().value(S_TAG) != null) { | 523 | if (host.annotations().value(S_TAG) != null) { |
612 | virtualSubscriberGatewayRemoved(host); | 524 | virtualSubscriberGatewayRemoved(host); |
613 | } | 525 | } |
614 | 526 | ||
615 | String serviceId = host.annotations().value(SERVICE_ID); | 527 | String serviceId = host.annotations().value(SERVICE_ID); |
616 | - if (serviceId == null) { | 528 | + if (Strings.isNullOrEmpty(serviceId)) { |
617 | - // ignore it, it's not a service VM | 529 | + // ignore this host, it is not a service instance |
618 | return; | 530 | return; |
619 | } | 531 | } |
620 | 532 | ||
621 | - log.info("VM is vanished, MAC: {} IP: {}", host.mac(), host.ipAddresses()); | 533 | + log.info("Instance is vanished {}", host); |
622 | 534 | ||
623 | - CordService service = getCordService(CordServiceId.of(serviceId)); | 535 | + // TODO remove openstack access when XOS provides all information |
536 | + VtnServiceApi vtnServiceApi = xosClient.getClient(xosAccess).vtnService(); | ||
537 | + VtnService service = vtnServiceApi.service(VtnServiceId.of(serviceId), osAccess); | ||
624 | if (service == null) { | 538 | if (service == null) { |
625 | - log.warn("Failed to get CORD service for {}", serviceId); | 539 | + log.warn("Failed to get VtnService for {}", serviceId); |
626 | return; | 540 | return; |
627 | } | 541 | } |
628 | - // TODO need to consider the case that the network is removed also | ||
629 | 542 | ||
630 | - switch (service.serviceType()) { | 543 | + // TODO need to consider the case that the service is removed also |
544 | + switch (service.networkType()) { | ||
631 | case MANAGEMENT: | 545 | case MANAGEMENT: |
632 | break; | 546 | break; |
633 | case PRIVATE: | 547 | case PRIVATE: |
634 | - if (service.hosts().isEmpty()) { | 548 | + if (getInstances(VtnServiceId.of(serviceId)).isEmpty()) { |
635 | arpProxy.removeGateway(service.serviceIp()); | 549 | arpProxy.removeGateway(service.serviceIp()); |
636 | } | 550 | } |
637 | case PUBLIC: | 551 | case PUBLIC: |
... | @@ -656,13 +570,14 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -656,13 +570,14 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
656 | * @param host new host with stag, it can be vsg VM or vsg | 570 | * @param host new host with stag, it can be vsg VM or vsg |
657 | * @param serviceVlan service vlan | 571 | * @param serviceVlan service vlan |
658 | */ | 572 | */ |
573 | + // TODO address service specific task in a separate package | ||
659 | private void virtualSubscriberGatewayAdded(Host host, String serviceVlan) { | 574 | private void virtualSubscriberGatewayAdded(Host host, String serviceVlan) { |
660 | Map<IpAddress, MacAddress> vSgs; | 575 | Map<IpAddress, MacAddress> vSgs; |
661 | Host vSgHost; | 576 | Host vSgHost; |
662 | 577 | ||
663 | String vSgHostId = host.annotations().value(VSG_HOST_ID); | 578 | String vSgHostId = host.annotations().value(VSG_HOST_ID); |
664 | if (vSgHostId == null) { | 579 | if (vSgHostId == null) { |
665 | - log.debug("vSG VM detected {}", host.id()); | 580 | + log.info("vSG VM detected {}", host.id()); |
666 | 581 | ||
667 | vSgHost = host; | 582 | vSgHost = host; |
668 | vSgs = getSubscriberGateways(vSgHost); | 583 | vSgs = getSubscriberGateways(vSgHost); |
... | @@ -677,7 +592,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -677,7 +592,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
677 | return; | 592 | return; |
678 | } | 593 | } |
679 | 594 | ||
680 | - log.debug("vSG detected {}", host.id()); | 595 | + log.info("vSG detected {}", host.id()); |
681 | vSgs = getSubscriberGateways(vSgHost); | 596 | vSgs = getSubscriberGateways(vSgHost); |
682 | } | 597 | } |
683 | 598 | ||
... | @@ -689,6 +604,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -689,6 +604,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
689 | * | 604 | * |
690 | * @param vSg vsg host to remove | 605 | * @param vSg vsg host to remove |
691 | */ | 606 | */ |
607 | + // TODO address service specific task in a separate package | ||
692 | private void virtualSubscriberGatewayRemoved(Host vSg) { | 608 | private void virtualSubscriberGatewayRemoved(Host vSg) { |
693 | String vSgHostId = vSg.annotations().value(VSG_HOST_ID); | 609 | String vSgHostId = vSg.annotations().value(VSG_HOST_ID); |
694 | if (vSgHostId == null) { | 610 | if (vSgHostId == null) { |
... | @@ -712,7 +628,8 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -712,7 +628,8 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
712 | * @param newMac mac address to update | 628 | * @param newMac mac address to update |
713 | */ | 629 | */ |
714 | private void setPrivateGatewayMac(MacAddress newMac) { | 630 | private void setPrivateGatewayMac(MacAddress newMac) { |
715 | - checkNotNull(osAccess, "OpenStack access is not set"); | 631 | + checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR); |
632 | + checkNotNull(xosAccess, XOS_ACCESS_ERROR); | ||
716 | 633 | ||
717 | if (newMac == null || newMac.equals(privateGatewayMac)) { | 634 | if (newMac == null || newMac.equals(privateGatewayMac)) { |
718 | // no updates, do nothing | 635 | // no updates, do nothing |
... | @@ -722,14 +639,12 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -722,14 +639,12 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
722 | privateGatewayMac = newMac; | 639 | privateGatewayMac = newMac; |
723 | log.debug("Set service gateway MAC address to {}", privateGatewayMac.toString()); | 640 | log.debug("Set service gateway MAC address to {}", privateGatewayMac.toString()); |
724 | 641 | ||
725 | - OSClient osClient = OSFactory.clientFromAccess(osAccess); | 642 | + VtnServiceApi vtnServiceApi = xosClient.getClient(xosAccess).vtnService(); |
726 | - List<Network> vNets = Lists.newArrayList(osClient.networking().network().list().iterator()); | 643 | + vtnServiceApi.services().stream().forEach(serviceId -> { |
727 | - | 644 | + VtnService service = vtnServiceApi.service(serviceId, osAccess); |
728 | - vNets.stream().forEach(vNet -> { | ||
729 | - CordService service = getCordService(vNet); | ||
730 | if (service != null) { | 645 | if (service != null) { |
731 | arpProxy.addGateway(service.serviceIp(), privateGatewayMac); | 646 | arpProxy.addGateway(service.serviceIp(), privateGatewayMac); |
732 | - arpProxy.sendGratuitousArpForGateway(service.serviceIp(), service.hosts().keySet()); | 647 | + arpProxy.sendGratuitousArpForGateway(service.serviceIp(), getInstances(serviceId)); |
733 | } | 648 | } |
734 | }); | 649 | }); |
735 | } | 650 | } |
... | @@ -751,51 +666,6 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -751,51 +666,6 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
751 | } | 666 | } |
752 | 667 | ||
753 | /** | 668 | /** |
754 | - * Sets OpenStack access information. | ||
755 | - * Access is the entity returned when authenticated and provides a singleton client | ||
756 | - * between multiple threads. | ||
757 | - * | ||
758 | - * @param osConfig openstack config | ||
759 | - */ | ||
760 | - private void setOpenstackAccess(CordVtnConfig.OpenStackConfig osConfig) { | ||
761 | - checkNotNull(osConfig, "OpenStack access is not configured"); | ||
762 | - | ||
763 | - log.debug("Get OpenStack access with Endpoint: {} Tenant: {} User: {} Passwd: {}", | ||
764 | - osConfig.endpoint(), | ||
765 | - osConfig.tenant(), | ||
766 | - osConfig.user(), | ||
767 | - osConfig.password()); | ||
768 | - try { | ||
769 | - osAccess = OSFactory.builder() | ||
770 | - .endpoint(osConfig.endpoint()) | ||
771 | - .credentials(osConfig.user(), osConfig.password()) | ||
772 | - .tenantName(osConfig.tenant()) | ||
773 | - .authenticate() | ||
774 | - .getAccess(); | ||
775 | - } catch (AuthenticationException e) { | ||
776 | - log.error("Failed to get OpenStack Access"); | ||
777 | - } | ||
778 | - } | ||
779 | - | ||
780 | - /** | ||
781 | - * Sets XOS access information. | ||
782 | - * | ||
783 | - * @param xosAccess xos access | ||
784 | - */ | ||
785 | - private void setXosAccess(XosAccess xosAccess) { | ||
786 | - if (xosAccess == null) { | ||
787 | - log.warn("XOS access is not configured"); | ||
788 | - return; | ||
789 | - } | ||
790 | - | ||
791 | - log.debug("Set XOS access with Endpoint: {} User: {} Passwd: {}", | ||
792 | - xosAccess.endpoint(), | ||
793 | - xosAccess.username(), | ||
794 | - xosAccess.password()); | ||
795 | - this.xosAccess = xosAccess; | ||
796 | - } | ||
797 | - | ||
798 | - /** | ||
799 | * Updates configurations. | 669 | * Updates configurations. |
800 | */ | 670 | */ |
801 | private void readConfiguration() { | 671 | private void readConfiguration() { |
... | @@ -805,8 +675,9 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -805,8 +675,9 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
805 | return; | 675 | return; |
806 | } | 676 | } |
807 | 677 | ||
808 | - setXosAccess(config.xosAccess()); | 678 | + xosAccess = config.xosAccess(); |
809 | - setOpenstackAccess(config.openstackConfig()); | 679 | + osAccess = config.openstackAccess(); |
680 | + | ||
810 | setPrivateGatewayMac(config.privateGatewayMac()); | 681 | setPrivateGatewayMac(config.privateGatewayMac()); |
811 | setPublicGatewayMac(config.publicGateways()); | 682 | setPublicGatewayMac(config.publicGateways()); |
812 | } | 683 | } |
... | @@ -824,10 +695,10 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -824,10 +695,10 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
824 | switch (event.type()) { | 695 | switch (event.type()) { |
825 | case HOST_UPDATED: | 696 | case HOST_UPDATED: |
826 | case HOST_ADDED: | 697 | case HOST_ADDED: |
827 | - eventExecutor.submit(() -> serviceVmAdded(host)); | 698 | + eventExecutor.execute(() -> serviceVmAdded(host)); |
828 | break; | 699 | break; |
829 | case HOST_REMOVED: | 700 | case HOST_REMOVED: |
830 | - eventExecutor.submit(() -> serviceVmRemoved(host)); | 701 | + eventExecutor.execute(() -> serviceVmRemoved(host)); |
831 | break; | 702 | break; |
832 | default: | 703 | default: |
833 | break; | 704 | break; | ... | ... |
... | @@ -237,6 +237,7 @@ public class CordVtnNodeManager { | ... | @@ -237,6 +237,7 @@ public class CordVtnNodeManager { |
237 | ruleInstaller = new CordVtnRuleInstaller(appId, flowRuleService, | 237 | ruleInstaller = new CordVtnRuleInstaller(appId, flowRuleService, |
238 | deviceService, | 238 | deviceService, |
239 | groupService, | 239 | groupService, |
240 | + hostService, | ||
240 | configRegistry, | 241 | configRegistry, |
241 | DEFAULT_TUNNEL); | 242 | DEFAULT_TUNNEL); |
242 | 243 | ... | ... |
... | @@ -28,8 +28,6 @@ import org.onlab.packet.MacAddress; | ... | @@ -28,8 +28,6 @@ import org.onlab.packet.MacAddress; |
28 | import org.onlab.packet.TpPort; | 28 | import org.onlab.packet.TpPort; |
29 | import org.onlab.packet.VlanId; | 29 | import org.onlab.packet.VlanId; |
30 | import org.onlab.util.ItemNotFoundException; | 30 | import org.onlab.util.ItemNotFoundException; |
31 | -import org.onosproject.cordvtn.api.CordService; | ||
32 | -import org.onosproject.cordvtn.api.CordServiceId; | ||
33 | import org.onosproject.cordvtn.api.CordVtnConfig; | 31 | import org.onosproject.cordvtn.api.CordVtnConfig; |
34 | import org.onosproject.cordvtn.api.CordVtnNode; | 32 | import org.onosproject.cordvtn.api.CordVtnNode; |
35 | import org.onosproject.core.ApplicationId; | 33 | import org.onosproject.core.ApplicationId; |
... | @@ -68,6 +66,9 @@ import org.onosproject.net.group.GroupBuckets; | ... | @@ -68,6 +66,9 @@ import org.onosproject.net.group.GroupBuckets; |
68 | import org.onosproject.net.group.GroupDescription; | 66 | import org.onosproject.net.group.GroupDescription; |
69 | import org.onosproject.net.group.GroupKey; | 67 | import org.onosproject.net.group.GroupKey; |
70 | import org.onosproject.net.group.GroupService; | 68 | import org.onosproject.net.group.GroupService; |
69 | +import org.onosproject.net.host.HostService; | ||
70 | +import org.onosproject.xosclient.api.VtnService; | ||
71 | +import org.onosproject.xosclient.api.VtnServiceId; | ||
71 | import org.slf4j.Logger; | 72 | import org.slf4j.Logger; |
72 | 73 | ||
73 | import java.util.ArrayList; | 74 | import java.util.ArrayList; |
... | @@ -76,6 +77,7 @@ import java.util.Map; | ... | @@ -76,6 +77,7 @@ import java.util.Map; |
76 | import java.util.Objects; | 77 | import java.util.Objects; |
77 | import java.util.Set; | 78 | import java.util.Set; |
78 | import java.util.stream.Collectors; | 79 | import java.util.stream.Collectors; |
80 | +import java.util.stream.StreamSupport; | ||
79 | 81 | ||
80 | import static com.google.common.base.Preconditions.checkNotNull; | 82 | import static com.google.common.base.Preconditions.checkNotNull; |
81 | import static org.onosproject.net.flow.criteria.Criterion.Type.IPV4_DST; | 83 | import static org.onosproject.net.flow.criteria.Criterion.Type.IPV4_DST; |
... | @@ -112,11 +114,13 @@ public class CordVtnRuleInstaller { | ... | @@ -112,11 +114,13 @@ public class CordVtnRuleInstaller { |
112 | private static final String DATA_PLANE_INTF = "dataPlaneIntf"; | 114 | private static final String DATA_PLANE_INTF = "dataPlaneIntf"; |
113 | private static final String DATA_PLANE_IP = "dataPlaneIp"; | 115 | private static final String DATA_PLANE_IP = "dataPlaneIp"; |
114 | private static final String S_TAG = "stag"; | 116 | private static final String S_TAG = "stag"; |
117 | + private static final String SERVICE_ID = "serviceId"; | ||
115 | 118 | ||
116 | private final ApplicationId appId; | 119 | private final ApplicationId appId; |
117 | private final FlowRuleService flowRuleService; | 120 | private final FlowRuleService flowRuleService; |
118 | private final DeviceService deviceService; | 121 | private final DeviceService deviceService; |
119 | private final GroupService groupService; | 122 | private final GroupService groupService; |
123 | + private final HostService hostService; | ||
120 | private final NetworkConfigRegistry configRegistry; | 124 | private final NetworkConfigRegistry configRegistry; |
121 | private final String tunnelType; | 125 | private final String tunnelType; |
122 | 126 | ||
... | @@ -134,12 +138,14 @@ public class CordVtnRuleInstaller { | ... | @@ -134,12 +138,14 @@ public class CordVtnRuleInstaller { |
134 | FlowRuleService flowRuleService, | 138 | FlowRuleService flowRuleService, |
135 | DeviceService deviceService, | 139 | DeviceService deviceService, |
136 | GroupService groupService, | 140 | GroupService groupService, |
141 | + HostService hostService, | ||
137 | NetworkConfigRegistry configRegistry, | 142 | NetworkConfigRegistry configRegistry, |
138 | String tunnelType) { | 143 | String tunnelType) { |
139 | this.appId = appId; | 144 | this.appId = appId; |
140 | this.flowRuleService = flowRuleService; | 145 | this.flowRuleService = flowRuleService; |
141 | this.deviceService = deviceService; | 146 | this.deviceService = deviceService; |
142 | this.groupService = groupService; | 147 | this.groupService = groupService; |
148 | + this.hostService = hostService; | ||
143 | this.configRegistry = configRegistry; | 149 | this.configRegistry = configRegistry; |
144 | this.tunnelType = checkNotNull(tunnelType); | 150 | this.tunnelType = checkNotNull(tunnelType); |
145 | } | 151 | } |
... | @@ -177,7 +183,7 @@ public class CordVtnRuleInstaller { | ... | @@ -177,7 +183,7 @@ public class CordVtnRuleInstaller { |
177 | * @param service cord service | 183 | * @param service cord service |
178 | * @param install true to install or false to remove | 184 | * @param install true to install or false to remove |
179 | */ | 185 | */ |
180 | - public void populateBasicConnectionRules(Host host, CordService service, boolean install) { | 186 | + public void populateBasicConnectionRules(Host host, VtnService service, boolean install) { |
181 | checkNotNull(host); | 187 | checkNotNull(host); |
182 | checkNotNull(service); | 188 | checkNotNull(service); |
183 | 189 | ||
... | @@ -186,8 +192,8 @@ public class CordVtnRuleInstaller { | ... | @@ -186,8 +192,8 @@ public class CordVtnRuleInstaller { |
186 | MacAddress dstMac = host.mac(); | 192 | MacAddress dstMac = host.mac(); |
187 | IpAddress hostIp = host.ipAddresses().stream().findFirst().get(); | 193 | IpAddress hostIp = host.ipAddresses().stream().findFirst().get(); |
188 | 194 | ||
189 | - long tunnelId = service.segmentationId(); | 195 | + long tunnelId = service.vni(); |
190 | - Ip4Prefix serviceIpRange = service.serviceIpRange().getIp4Prefix(); | 196 | + Ip4Prefix serviceIpRange = service.subnet().getIp4Prefix(); |
191 | 197 | ||
192 | populateLocalInPortRule(deviceId, inPort, hostIp, install); | 198 | populateLocalInPortRule(deviceId, inPort, hostIp, install); |
193 | populateDstIpRule(deviceId, inPort, dstMac, hostIp, tunnelId, getTunnelIp(host), install); | 199 | populateDstIpRule(deviceId, inPort, dstMac, hostIp, tunnelId, getTunnelIp(host), install); |
... | @@ -196,7 +202,7 @@ public class CordVtnRuleInstaller { | ... | @@ -196,7 +202,7 @@ public class CordVtnRuleInstaller { |
196 | if (install) { | 202 | if (install) { |
197 | populateDirectAccessRule(serviceIpRange, serviceIpRange, true); | 203 | populateDirectAccessRule(serviceIpRange, serviceIpRange, true); |
198 | populateServiceIsolationRule(serviceIpRange, true); | 204 | populateServiceIsolationRule(serviceIpRange, true); |
199 | - } else if (service.hosts().isEmpty()) { | 205 | + } else if (getInstances(service.id()).isEmpty()) { |
200 | // removes network related rules only if there's no hosts left in this network | 206 | // removes network related rules only if there's no hosts left in this network |
201 | populateDirectAccessRule(serviceIpRange, serviceIpRange, false); | 207 | populateDirectAccessRule(serviceIpRange, serviceIpRange, false); |
202 | populateServiceIsolationRule(serviceIpRange, false); | 208 | populateServiceIsolationRule(serviceIpRange, false); |
... | @@ -211,13 +217,13 @@ public class CordVtnRuleInstaller { | ... | @@ -211,13 +217,13 @@ public class CordVtnRuleInstaller { |
211 | * @param isBidirectional true to enable bidirectional connection between two services | 217 | * @param isBidirectional true to enable bidirectional connection between two services |
212 | * @param install true to install or false to remove | 218 | * @param install true to install or false to remove |
213 | */ | 219 | */ |
214 | - public void populateServiceDependencyRules(CordService tService, CordService pService, | 220 | + public void populateServiceDependencyRules(VtnService tService, VtnService pService, |
215 | boolean isBidirectional, boolean install) { | 221 | boolean isBidirectional, boolean install) { |
216 | checkNotNull(tService); | 222 | checkNotNull(tService); |
217 | checkNotNull(pService); | 223 | checkNotNull(pService); |
218 | 224 | ||
219 | - Ip4Prefix srcRange = tService.serviceIpRange().getIp4Prefix(); | 225 | + Ip4Prefix srcRange = tService.subnet().getIp4Prefix(); |
220 | - Ip4Prefix dstRange = pService.serviceIpRange().getIp4Prefix(); | 226 | + Ip4Prefix dstRange = pService.subnet().getIp4Prefix(); |
221 | Ip4Address serviceIp = pService.serviceIp().getIp4Address(); | 227 | Ip4Address serviceIp = pService.serviceIp().getIp4Address(); |
222 | 228 | ||
223 | Map<DeviceId, GroupId> outGroups = Maps.newHashMap(); | 229 | Map<DeviceId, GroupId> outGroups = Maps.newHashMap(); |
... | @@ -227,7 +233,7 @@ public class CordVtnRuleInstaller { | ... | @@ -227,7 +233,7 @@ public class CordVtnRuleInstaller { |
227 | GroupId groupId = createServiceGroup(deviceId, pService); | 233 | GroupId groupId = createServiceGroup(deviceId, pService); |
228 | outGroups.put(deviceId, groupId); | 234 | outGroups.put(deviceId, groupId); |
229 | 235 | ||
230 | - Set<PortNumber> tServiceVms = tService.hosts().keySet() | 236 | + Set<PortNumber> tServiceVms = getInstances(tService.id()) |
231 | .stream() | 237 | .stream() |
232 | .filter(host -> host.location().deviceId().equals(deviceId)) | 238 | .filter(host -> host.location().deviceId().equals(deviceId)) |
233 | .map(host -> host.location().port()) | 239 | .map(host -> host.location().port()) |
... | @@ -248,7 +254,7 @@ public class CordVtnRuleInstaller { | ... | @@ -248,7 +254,7 @@ public class CordVtnRuleInstaller { |
248 | * | 254 | * |
249 | * @param service cord service | 255 | * @param service cord service |
250 | */ | 256 | */ |
251 | - public void updateProviderServiceGroup(CordService service) { | 257 | + public void updateProviderServiceGroup(VtnService service) { |
252 | checkNotNull(service); | 258 | checkNotNull(service); |
253 | 259 | ||
254 | GroupKey groupKey = getGroupKey(service.id()); | 260 | GroupKey groupKey = getGroupKey(service.id()); |
... | @@ -262,7 +268,7 @@ public class CordVtnRuleInstaller { | ... | @@ -262,7 +268,7 @@ public class CordVtnRuleInstaller { |
262 | 268 | ||
263 | List<GroupBucket> oldBuckets = group.buckets().buckets(); | 269 | List<GroupBucket> oldBuckets = group.buckets().buckets(); |
264 | List<GroupBucket> newBuckets = getServiceGroupBuckets( | 270 | List<GroupBucket> newBuckets = getServiceGroupBuckets( |
265 | - deviceId, service.segmentationId(), service.hosts()).buckets(); | 271 | + deviceId, service.vni(), getInstances(service.id())).buckets(); |
266 | 272 | ||
267 | if (oldBuckets.equals(newBuckets)) { | 273 | if (oldBuckets.equals(newBuckets)) { |
268 | continue; | 274 | continue; |
... | @@ -296,7 +302,7 @@ public class CordVtnRuleInstaller { | ... | @@ -296,7 +302,7 @@ public class CordVtnRuleInstaller { |
296 | * @param host removed vm | 302 | * @param host removed vm |
297 | * @param service tenant service | 303 | * @param service tenant service |
298 | */ | 304 | */ |
299 | - public void updateTenantServiceVm(Host host, CordService service) { | 305 | + public void updateTenantServiceVm(Host host, VtnService service) { |
300 | checkNotNull(host); | 306 | checkNotNull(host); |
301 | checkNotNull(service); | 307 | checkNotNull(service); |
302 | 308 | ||
... | @@ -320,7 +326,7 @@ public class CordVtnRuleInstaller { | ... | @@ -320,7 +326,7 @@ public class CordVtnRuleInstaller { |
320 | * @param host host which has management network interface | 326 | * @param host host which has management network interface |
321 | * @param mService management network service | 327 | * @param mService management network service |
322 | */ | 328 | */ |
323 | - public void populateManagementNetworkRules(Host host, CordService mService) { | 329 | + public void populateManagementNetworkRules(Host host, VtnService mService) { |
324 | checkNotNull(mService); | 330 | checkNotNull(mService); |
325 | 331 | ||
326 | DeviceId deviceId = host.location().deviceId(); | 332 | DeviceId deviceId = host.location().deviceId(); |
... | @@ -372,7 +378,7 @@ public class CordVtnRuleInstaller { | ... | @@ -372,7 +378,7 @@ public class CordVtnRuleInstaller { |
372 | selector = DefaultTrafficSelector.builder() | 378 | selector = DefaultTrafficSelector.builder() |
373 | .matchInPort(PortNumber.LOCAL) | 379 | .matchInPort(PortNumber.LOCAL) |
374 | .matchEthType(Ethernet.TYPE_IPV4) | 380 | .matchEthType(Ethernet.TYPE_IPV4) |
375 | - .matchIPDst(mService.serviceIpRange()) | 381 | + .matchIPDst(mService.subnet()) |
376 | .build(); | 382 | .build(); |
377 | 383 | ||
378 | treatment = DefaultTrafficTreatment.builder() | 384 | treatment = DefaultTrafficTreatment.builder() |
... | @@ -1237,7 +1243,7 @@ public class CordVtnRuleInstaller { | ... | @@ -1237,7 +1243,7 @@ public class CordVtnRuleInstaller { |
1237 | * @param service cord service | 1243 | * @param service cord service |
1238 | * @return group id, or null if it fails to create | 1244 | * @return group id, or null if it fails to create |
1239 | */ | 1245 | */ |
1240 | - private GroupId createServiceGroup(DeviceId deviceId, CordService service) { | 1246 | + private GroupId createServiceGroup(DeviceId deviceId, VtnService service) { |
1241 | checkNotNull(service); | 1247 | checkNotNull(service); |
1242 | 1248 | ||
1243 | GroupKey groupKey = getGroupKey(service.id()); | 1249 | GroupKey groupKey = getGroupKey(service.id()); |
... | @@ -1250,7 +1256,7 @@ public class CordVtnRuleInstaller { | ... | @@ -1250,7 +1256,7 @@ public class CordVtnRuleInstaller { |
1250 | } | 1256 | } |
1251 | 1257 | ||
1252 | GroupBuckets buckets = getServiceGroupBuckets( | 1258 | GroupBuckets buckets = getServiceGroupBuckets( |
1253 | - deviceId, service.segmentationId(), service.hosts()); | 1259 | + deviceId, service.vni(), getInstances(service.id())); |
1254 | GroupDescription groupDescription = new DefaultGroupDescription( | 1260 | GroupDescription groupDescription = new DefaultGroupDescription( |
1255 | deviceId, | 1261 | deviceId, |
1256 | GroupDescription.Type.SELECT, | 1262 | GroupDescription.Type.SELECT, |
... | @@ -1273,33 +1279,26 @@ public class CordVtnRuleInstaller { | ... | @@ -1273,33 +1279,26 @@ public class CordVtnRuleInstaller { |
1273 | * @return group buckets | 1279 | * @return group buckets |
1274 | */ | 1280 | */ |
1275 | private GroupBuckets getServiceGroupBuckets(DeviceId deviceId, long tunnelId, | 1281 | private GroupBuckets getServiceGroupBuckets(DeviceId deviceId, long tunnelId, |
1276 | - Map<Host, IpAddress> hosts) { | 1282 | + Set<Host> hosts) { |
1277 | List<GroupBucket> buckets = Lists.newArrayList(); | 1283 | List<GroupBucket> buckets = Lists.newArrayList(); |
1278 | 1284 | ||
1279 | - for (Map.Entry<Host, IpAddress> entry : hosts.entrySet()) { | 1285 | + hosts.stream().forEach(host -> { |
1280 | - Host host = entry.getKey(); | 1286 | + Ip4Address tunnelIp = getTunnelIp(host).getIp4Address(); |
1281 | - Ip4Address remoteIp = entry.getValue().getIp4Address(); | ||
1282 | DeviceId hostDevice = host.location().deviceId(); | 1287 | DeviceId hostDevice = host.location().deviceId(); |
1283 | 1288 | ||
1284 | TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment | 1289 | TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment |
1285 | .builder() | 1290 | .builder() |
1286 | .setEthDst(host.mac()); | 1291 | .setEthDst(host.mac()); |
1287 | - | ||
1288 | if (deviceId.equals(hostDevice)) { | 1292 | if (deviceId.equals(hostDevice)) { |
1289 | tBuilder.setOutput(host.location().port()); | 1293 | tBuilder.setOutput(host.location().port()); |
1290 | } else { | 1294 | } else { |
1291 | - ExtensionTreatment tunnelDst = getTunnelDst(deviceId, remoteIp); | 1295 | + ExtensionTreatment tunnelDst = getTunnelDst(deviceId, tunnelIp); |
1292 | - if (tunnelDst == null) { | ||
1293 | - continue; | ||
1294 | - } | ||
1295 | - | ||
1296 | tBuilder.extension(tunnelDst, deviceId) | 1296 | tBuilder.extension(tunnelDst, deviceId) |
1297 | .setTunnelId(tunnelId) | 1297 | .setTunnelId(tunnelId) |
1298 | .setOutput(getTunnelPort(hostDevice)); | 1298 | .setOutput(getTunnelPort(hostDevice)); |
1299 | } | 1299 | } |
1300 | - | ||
1301 | buckets.add(DefaultGroupBucket.createSelectGroupBucket(tBuilder.build())); | 1300 | buckets.add(DefaultGroupBucket.createSelectGroupBucket(tBuilder.build())); |
1302 | - } | 1301 | + }); |
1303 | 1302 | ||
1304 | return new GroupBuckets(buckets); | 1303 | return new GroupBuckets(buckets); |
1305 | } | 1304 | } |
... | @@ -1311,7 +1310,7 @@ public class CordVtnRuleInstaller { | ... | @@ -1311,7 +1310,7 @@ public class CordVtnRuleInstaller { |
1311 | * @param deviceId device id | 1310 | * @param deviceId device id |
1312 | * @return group id | 1311 | * @return group id |
1313 | */ | 1312 | */ |
1314 | - private GroupId getGroupId(CordServiceId serviceId, DeviceId deviceId) { | 1313 | + private GroupId getGroupId(VtnServiceId serviceId, DeviceId deviceId) { |
1315 | return new DefaultGroupId(Objects.hash(serviceId, deviceId)); | 1314 | return new DefaultGroupId(Objects.hash(serviceId, deviceId)); |
1316 | } | 1315 | } |
1317 | 1316 | ||
... | @@ -1321,7 +1320,7 @@ public class CordVtnRuleInstaller { | ... | @@ -1321,7 +1320,7 @@ public class CordVtnRuleInstaller { |
1321 | * @param serviceId service id | 1320 | * @param serviceId service id |
1322 | * @return group key | 1321 | * @return group key |
1323 | */ | 1322 | */ |
1324 | - private GroupKey getGroupKey(CordServiceId serviceId) { | 1323 | + private GroupKey getGroupKey(VtnServiceId serviceId) { |
1325 | return new DefaultGroupKey(serviceId.id().getBytes()); | 1324 | return new DefaultGroupKey(serviceId.id().getBytes()); |
1326 | } | 1325 | } |
1327 | 1326 | ||
... | @@ -1370,5 +1369,19 @@ public class CordVtnRuleInstaller { | ... | @@ -1370,5 +1369,19 @@ public class CordVtnRuleInstaller { |
1370 | return config.cordVtnNodes().stream() | 1369 | return config.cordVtnNodes().stream() |
1371 | .map(CordVtnNode::intBrId).collect(Collectors.toSet()); | 1370 | .map(CordVtnNode::intBrId).collect(Collectors.toSet()); |
1372 | } | 1371 | } |
1372 | + | ||
1373 | + /** | ||
1374 | + * Returns instances with a given network service. | ||
1375 | + * | ||
1376 | + * @param serviceId service id | ||
1377 | + * @return set of hosts | ||
1378 | + */ | ||
1379 | + private Set<Host> getInstances(VtnServiceId serviceId) { | ||
1380 | + return StreamSupport.stream(hostService.getHosts().spliterator(), false) | ||
1381 | + .filter(host -> Objects.equals( | ||
1382 | + serviceId.id(), | ||
1383 | + host.annotations().value(SERVICE_ID))) | ||
1384 | + .collect(Collectors.toSet()); | ||
1385 | + } | ||
1373 | } | 1386 | } |
1374 | 1387 | ... | ... |
... | @@ -16,8 +16,8 @@ | ... | @@ -16,8 +16,8 @@ |
16 | package org.onosproject.cordvtn.rest; | 16 | package org.onosproject.cordvtn.rest; |
17 | 17 | ||
18 | import org.onosproject.cordvtn.api.CordVtnService; | 18 | import org.onosproject.cordvtn.api.CordVtnService; |
19 | -import org.onosproject.cordvtn.api.CordServiceId; | ||
20 | import org.onosproject.rest.AbstractWebResource; | 19 | import org.onosproject.rest.AbstractWebResource; |
20 | +import org.onosproject.xosclient.api.VtnServiceId; | ||
21 | 21 | ||
22 | import javax.ws.rs.DELETE; | 22 | import javax.ws.rs.DELETE; |
23 | import javax.ws.rs.POST; | 23 | import javax.ws.rs.POST; |
... | @@ -48,8 +48,8 @@ public class ServiceDependencyWebResource extends AbstractWebResource { | ... | @@ -48,8 +48,8 @@ public class ServiceDependencyWebResource extends AbstractWebResource { |
48 | @Produces(MediaType.APPLICATION_JSON) | 48 | @Produces(MediaType.APPLICATION_JSON) |
49 | public Response createServiceDependency(@PathParam("tenantServiceId") String tServiceId, | 49 | public Response createServiceDependency(@PathParam("tenantServiceId") String tServiceId, |
50 | @PathParam("providerServiceId") String pServiceId) { | 50 | @PathParam("providerServiceId") String pServiceId) { |
51 | - service.createServiceDependency(CordServiceId.of(tServiceId), | 51 | + service.createServiceDependency(VtnServiceId.of(tServiceId), |
52 | - CordServiceId.of(pServiceId), | 52 | + VtnServiceId.of(pServiceId), |
53 | false); | 53 | false); |
54 | return Response.status(Response.Status.OK).build(); | 54 | return Response.status(Response.Status.OK).build(); |
55 | } | 55 | } |
... | @@ -68,8 +68,8 @@ public class ServiceDependencyWebResource extends AbstractWebResource { | ... | @@ -68,8 +68,8 @@ public class ServiceDependencyWebResource extends AbstractWebResource { |
68 | public Response createServiceDependency(@PathParam("tenantServiceId") String tServiceId, | 68 | public Response createServiceDependency(@PathParam("tenantServiceId") String tServiceId, |
69 | @PathParam("providerServiceId") String pServiceId, | 69 | @PathParam("providerServiceId") String pServiceId, |
70 | @PathParam("direction") String direction) { | 70 | @PathParam("direction") String direction) { |
71 | - service.createServiceDependency(CordServiceId.of(tServiceId), | 71 | + service.createServiceDependency(VtnServiceId.of(tServiceId), |
72 | - CordServiceId.of(pServiceId), | 72 | + VtnServiceId.of(pServiceId), |
73 | direction.equals(BIDIRECTION)); | 73 | direction.equals(BIDIRECTION)); |
74 | return Response.status(Response.Status.OK).build(); | 74 | return Response.status(Response.Status.OK).build(); |
75 | } | 75 | } |
... | @@ -85,7 +85,7 @@ public class ServiceDependencyWebResource extends AbstractWebResource { | ... | @@ -85,7 +85,7 @@ public class ServiceDependencyWebResource extends AbstractWebResource { |
85 | @Path("{tenantServiceId}/{providerServiceId}") | 85 | @Path("{tenantServiceId}/{providerServiceId}") |
86 | public Response removeServiceDependency(@PathParam("tenantServiceId") String tServiceId, | 86 | public Response removeServiceDependency(@PathParam("tenantServiceId") String tServiceId, |
87 | @PathParam("providerServiceId") String pServiceId) { | 87 | @PathParam("providerServiceId") String pServiceId) { |
88 | - service.removeServiceDependency(CordServiceId.of(tServiceId), CordServiceId.of(pServiceId)); | 88 | + service.removeServiceDependency(VtnServiceId.of(tServiceId), VtnServiceId.of(pServiceId)); |
89 | return Response.noContent().build(); | 89 | return Response.noContent().build(); |
90 | } | 90 | } |
91 | } | 91 | } | ... | ... |
1 | COMPILE_DEPS = [ | 1 | COMPILE_DEPS = [ |
2 | '//lib:CORE_DEPS', | 2 | '//lib:CORE_DEPS', |
3 | '//lib:javax.ws.rs-api', | 3 | '//lib:javax.ws.rs-api', |
4 | + '//lib:openstack4j-core', | ||
5 | + '//lib:openstack4j-http-connector', | ||
6 | + '//lib:openstack4j-httpclient', | ||
4 | ] | 7 | ] |
5 | 8 | ||
6 | osgi_jar_with_tests ( | 9 | osgi_jar_with_tests ( | ... | ... |
... | @@ -49,6 +49,45 @@ | ... | @@ -49,6 +49,45 @@ |
49 | <artifactId>onlab-misc</artifactId> | 49 | <artifactId>onlab-misc</artifactId> |
50 | <version>${project.version}</version> | 50 | <version>${project.version}</version> |
51 | </dependency> | 51 | </dependency> |
52 | + <dependency> | ||
53 | + <groupId>org.pacesys</groupId> | ||
54 | + <artifactId>openstack4j-core</artifactId> | ||
55 | + <version>2.11</version> | ||
56 | + </dependency> | ||
57 | + <dependency> | ||
58 | + <groupId>org.pacesys.openstack4j.connectors</groupId> | ||
59 | + <artifactId>openstack4j-http-connector</artifactId> | ||
60 | + <version>2.11</version> | ||
61 | + </dependency> | ||
62 | + <dependency> | ||
63 | + <groupId>org.pacesys.openstack4j.connectors</groupId> | ||
64 | + <artifactId>openstack4j-httpclient</artifactId> | ||
65 | + <version>2.11</version> | ||
66 | + </dependency> | ||
52 | </dependencies> | 67 | </dependencies> |
53 | 68 | ||
69 | + <build> | ||
70 | + <plugins> | ||
71 | + <plugin> | ||
72 | + <groupId>org.apache.felix</groupId> | ||
73 | + <artifactId>maven-bundle-plugin</artifactId> | ||
74 | + <extensions>true</extensions> | ||
75 | + <configuration> | ||
76 | + <instructions> | ||
77 | + <Import-Package> | ||
78 | + !org.apache.http.*, | ||
79 | + !com.fasterxml.jackson.dataformat.*, | ||
80 | + !javax.annotation,* | ||
81 | + </Import-Package> | ||
82 | + <Embed-Dependency> | ||
83 | + openstack4j-core, | ||
84 | + openstack4j-http-connector, | ||
85 | + openstack4j-httpclient | ||
86 | + </Embed-Dependency> | ||
87 | + </instructions> | ||
88 | + </configuration> | ||
89 | + </plugin> | ||
90 | + </plugins> | ||
91 | + </build> | ||
92 | + | ||
54 | </project> | 93 | </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.xosclient.api; | ||
17 | + | ||
18 | +import com.google.common.base.MoreObjects; | ||
19 | + | ||
20 | +import java.util.Objects; | ||
21 | + | ||
22 | +/** | ||
23 | + * Object holding OpenStack API access information. | ||
24 | + */ | ||
25 | +// TODO remove this when XOS provides this information | ||
26 | +public class OpenStackAccess { | ||
27 | + | ||
28 | + private final String endpoint; | ||
29 | + private final String tenant; | ||
30 | + private final String user; | ||
31 | + private final String password; | ||
32 | + | ||
33 | + /** | ||
34 | + * Default constructor. | ||
35 | + * | ||
36 | + * @param endpoint Keystone endpoint | ||
37 | + * @param tenant tenant name | ||
38 | + * @param user user name | ||
39 | + * @param password password | ||
40 | + */ | ||
41 | + public OpenStackAccess(String endpoint, String tenant, String user, String password) { | ||
42 | + this.endpoint = endpoint; | ||
43 | + this.tenant = tenant; | ||
44 | + this.user = user; | ||
45 | + this.password = password; | ||
46 | + } | ||
47 | + | ||
48 | + /** | ||
49 | + * Returns OpenStack API endpoint. | ||
50 | + * | ||
51 | + * @return endpoint | ||
52 | + */ | ||
53 | + public String endpoint() { | ||
54 | + return this.endpoint; | ||
55 | + } | ||
56 | + | ||
57 | + /** | ||
58 | + * Returns OpenStack tenant name. | ||
59 | + * | ||
60 | + * @return tenant name | ||
61 | + */ | ||
62 | + public String tenant() { | ||
63 | + return this.tenant; | ||
64 | + } | ||
65 | + | ||
66 | + /** | ||
67 | + * Returns OpenStack user. | ||
68 | + * | ||
69 | + * @return user name | ||
70 | + */ | ||
71 | + public String user() { | ||
72 | + return this.user; | ||
73 | + } | ||
74 | + | ||
75 | + /** | ||
76 | + * Returns OpenStack password for the user. | ||
77 | + * | ||
78 | + * @return password | ||
79 | + */ | ||
80 | + public String password() { | ||
81 | + return this.password; | ||
82 | + } | ||
83 | + | ||
84 | + @Override | ||
85 | + public int hashCode() { | ||
86 | + return Objects.hash(endpoint, tenant, user, password); | ||
87 | + } | ||
88 | + | ||
89 | + @Override | ||
90 | + public boolean equals(Object obj) { | ||
91 | + if (this == obj) { | ||
92 | + return true; | ||
93 | + } | ||
94 | + if ((obj instanceof OpenStackAccess)) { | ||
95 | + OpenStackAccess that = (OpenStackAccess) obj; | ||
96 | + if (Objects.equals(endpoint, that.endpoint) && | ||
97 | + Objects.equals(tenant, that.tenant) && | ||
98 | + Objects.equals(user, that.user) && | ||
99 | + Objects.equals(password, that.password)) { | ||
100 | + return true; | ||
101 | + } | ||
102 | + } | ||
103 | + return false; | ||
104 | + } | ||
105 | + | ||
106 | + @Override | ||
107 | + public String toString() { | ||
108 | + return MoreObjects.toStringHelper(getClass()) | ||
109 | + .add("endpoint", endpoint) | ||
110 | + .add("tenant", tenant) | ||
111 | + .add("user", user) | ||
112 | + .add("password", password) | ||
113 | + .toString(); | ||
114 | + } | ||
115 | +} |
... | @@ -44,4 +44,22 @@ public interface VtnPortApi { | ... | @@ -44,4 +44,22 @@ public interface VtnPortApi { |
44 | * @return vtn port; null if it fails to get port information | 44 | * @return vtn port; null if it fails to get port information |
45 | */ | 45 | */ |
46 | VtnPort vtnPort(VtnPortId portId); | 46 | VtnPort vtnPort(VtnPortId portId); |
47 | + | ||
48 | + /** | ||
49 | + * Returns port information from OpenStack with port id. | ||
50 | + * | ||
51 | + * @param portId port id | ||
52 | + * @return vtn port; null if it fails to get port information | ||
53 | + */ | ||
54 | + // TODO remove this when XOS provides port information | ||
55 | + VtnPort vtnPort(VtnPortId portId, OpenStackAccess osAccess); | ||
56 | + | ||
57 | + /** | ||
58 | + * Returns port information from OpenStack with port name. | ||
59 | + * | ||
60 | + * @param portName port name | ||
61 | + * @return vtn port; null if it fails to get port information | ||
62 | + */ | ||
63 | + // TODO remove this when XOS provides port information | ||
64 | + VtnPort vtnPort(String portName, OpenStackAccess osAccess); | ||
47 | } | 65 | } | ... | ... |
... | @@ -52,4 +52,14 @@ public interface VtnServiceApi { | ... | @@ -52,4 +52,14 @@ public interface VtnServiceApi { |
52 | * @return set of service ids | 52 | * @return set of service ids |
53 | */ | 53 | */ |
54 | Set<VtnServiceId> providerServices(VtnServiceId tServiceId); | 54 | Set<VtnServiceId> providerServices(VtnServiceId tServiceId); |
55 | + | ||
56 | + /** | ||
57 | + * Returns VTN service from OpenStack. | ||
58 | + * | ||
59 | + * @param serviceId service id | ||
60 | + * @param osAccess openstack access | ||
61 | + * @return vtn service | ||
62 | + */ | ||
63 | + // TODO remove this when XOS provides service information | ||
64 | + VtnService service(VtnServiceId serviceId, OpenStackAccess osAccess); | ||
55 | } | 65 | } | ... | ... |
... | @@ -15,18 +15,33 @@ | ... | @@ -15,18 +15,33 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.xosclient.impl; | 16 | package org.onosproject.xosclient.impl; |
17 | 17 | ||
18 | +import com.google.common.collect.Maps; | ||
19 | +import org.onlab.packet.IpAddress; | ||
20 | +import org.onlab.packet.MacAddress; | ||
21 | +import org.onosproject.xosclient.api.OpenStackAccess; | ||
18 | import org.onosproject.xosclient.api.VtnPort; | 22 | import org.onosproject.xosclient.api.VtnPort; |
19 | import org.onosproject.xosclient.api.VtnPortApi; | 23 | import org.onosproject.xosclient.api.VtnPortApi; |
20 | import org.onosproject.xosclient.api.VtnPortId; | 24 | import org.onosproject.xosclient.api.VtnPortId; |
21 | import org.onosproject.xosclient.api.VtnServiceId; | 25 | import org.onosproject.xosclient.api.VtnServiceId; |
22 | import org.onosproject.xosclient.api.XosAccess; | 26 | import org.onosproject.xosclient.api.XosAccess; |
27 | +import org.openstack4j.api.OSClient; | ||
28 | +import org.openstack4j.model.network.IP; | ||
29 | +import org.openstack4j.model.network.Port; | ||
30 | +import org.openstack4j.openstack.OSFactory; | ||
31 | +import org.slf4j.Logger; | ||
32 | +import org.slf4j.LoggerFactory; | ||
23 | 33 | ||
34 | +import java.util.Map; | ||
24 | import java.util.Set; | 35 | import java.util.Set; |
25 | 36 | ||
37 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
38 | + | ||
26 | /** | 39 | /** |
27 | * Provides CORD VTN port APIs. | 40 | * Provides CORD VTN port APIs. |
28 | */ | 41 | */ |
29 | -public class DefaultVtnPortApi extends XosApi implements VtnPortApi { | 42 | +public final class DefaultVtnPortApi extends XosApi implements VtnPortApi { |
43 | + | ||
44 | + private final Logger log = LoggerFactory.getLogger(getClass()); | ||
30 | 45 | ||
31 | /** | 46 | /** |
32 | * Default constructor. | 47 | * Default constructor. |
... | @@ -55,4 +70,72 @@ public class DefaultVtnPortApi extends XosApi implements VtnPortApi { | ... | @@ -55,4 +70,72 @@ public class DefaultVtnPortApi extends XosApi implements VtnPortApi { |
55 | // TODO implement this when XOS provides this information | 70 | // TODO implement this when XOS provides this information |
56 | return null; | 71 | return null; |
57 | } | 72 | } |
73 | + | ||
74 | + @Override | ||
75 | + // TODO remove this when XOS provides this information | ||
76 | + public VtnPort vtnPort(String portName, OpenStackAccess osAccess) { | ||
77 | + checkNotNull(osAccess); | ||
78 | + | ||
79 | + OSClient osClient = getOpenStackClient(osAccess); | ||
80 | + Port osPort = osClient.networking().port().list() | ||
81 | + .stream() | ||
82 | + .filter(p -> p.getId().contains(portName.substring(3))) | ||
83 | + .findFirst().orElse(null); | ||
84 | + if (osPort == null) { | ||
85 | + log.warn("Failed to get OpenStack port for {}", portName); | ||
86 | + return null; | ||
87 | + } | ||
88 | + return getVtnPort(osPort); | ||
89 | + } | ||
90 | + | ||
91 | + @Override | ||
92 | + // TODO remove this when XOS provides this information | ||
93 | + public VtnPort vtnPort(VtnPortId portId, OpenStackAccess osAccess) { | ||
94 | + checkNotNull(osAccess); | ||
95 | + | ||
96 | + OSClient osClient = getOpenStackClient(osAccess); | ||
97 | + Port osPort = osClient.networking().port().get(portId.id()); | ||
98 | + if (osPort == null) { | ||
99 | + log.warn("Failed to get OpenStack port {}", portId); | ||
100 | + return null; | ||
101 | + } | ||
102 | + return getVtnPort(osPort); | ||
103 | + } | ||
104 | + | ||
105 | + // TODO remove this when XOS provides this information | ||
106 | + private VtnPort getVtnPort(Port osPort) { | ||
107 | + checkNotNull(osPort); | ||
108 | + | ||
109 | + // assumes all vtn port has single IP address | ||
110 | + IP ipAddr = osPort.getFixedIps().stream().findFirst().orElse(null); | ||
111 | + if (ipAddr == null) { | ||
112 | + log.warn("Failed to get IP address for {}", osPort); | ||
113 | + return null; | ||
114 | + } | ||
115 | + | ||
116 | + Map<IpAddress, MacAddress> addressPairs = Maps.newHashMap(); | ||
117 | + osPort.getAllowedAddressPairs().stream().forEach( | ||
118 | + pair -> addressPairs.put(IpAddress.valueOf(pair.getIpAddress()), | ||
119 | + MacAddress.valueOf(pair.getMacAddress()))); | ||
120 | + | ||
121 | + return new VtnPort(VtnPortId.of(osPort.getId()), | ||
122 | + osPort.getName(), | ||
123 | + VtnServiceId.of(osPort.getNetworkId()), | ||
124 | + MacAddress.valueOf(osPort.getMacAddress()), | ||
125 | + IpAddress.valueOf(ipAddr.getIpAddress()), | ||
126 | + addressPairs); | ||
127 | + } | ||
128 | + | ||
129 | + // TODO remove this when XOS provides this information | ||
130 | + private OSClient getOpenStackClient(OpenStackAccess osAccess) { | ||
131 | + checkNotNull(osAccess); | ||
132 | + | ||
133 | + // creating a client every time must be inefficient, but this method | ||
134 | + // will be removed once XOS provides equivalent APIs | ||
135 | + return OSFactory.builder() | ||
136 | + .endpoint(osAccess.endpoint()) | ||
137 | + .credentials(osAccess.user(), osAccess.password()) | ||
138 | + .tenantName(osAccess.tenant()) | ||
139 | + .authenticate(); | ||
140 | + } | ||
58 | } | 141 | } | ... | ... |
... | @@ -17,12 +17,22 @@ package org.onosproject.xosclient.impl; | ... | @@ -17,12 +17,22 @@ package org.onosproject.xosclient.impl; |
17 | 17 | ||
18 | import com.fasterxml.jackson.databind.JsonNode; | 18 | import com.fasterxml.jackson.databind.JsonNode; |
19 | import com.fasterxml.jackson.databind.ObjectMapper; | 19 | import com.fasterxml.jackson.databind.ObjectMapper; |
20 | +import com.google.common.base.Strings; | ||
20 | import com.google.common.collect.Sets; | 21 | import com.google.common.collect.Sets; |
22 | +import org.onlab.packet.IpAddress; | ||
23 | +import org.onlab.packet.IpPrefix; | ||
24 | +import org.onosproject.xosclient.api.OpenStackAccess; | ||
25 | +import org.onosproject.xosclient.api.VtnService.NetworkType; | ||
26 | +import org.onosproject.xosclient.api.VtnService.ServiceType; | ||
21 | import org.onosproject.xosclient.api.VtnServiceApi; | 27 | import org.onosproject.xosclient.api.VtnServiceApi; |
22 | import org.onosproject.xosclient.api.XosAccess; | 28 | import org.onosproject.xosclient.api.XosAccess; |
23 | import org.onosproject.xosclient.api.VtnService; | 29 | import org.onosproject.xosclient.api.VtnService; |
24 | import org.onosproject.xosclient.api.VtnServiceId; | 30 | import org.onosproject.xosclient.api.VtnServiceId; |
25 | 31 | ||
32 | +import org.openstack4j.api.OSClient; | ||
33 | +import org.openstack4j.model.network.Network; | ||
34 | +import org.openstack4j.model.network.Subnet; | ||
35 | +import org.openstack4j.openstack.OSFactory; | ||
26 | import org.slf4j.Logger; | 36 | import org.slf4j.Logger; |
27 | import org.slf4j.LoggerFactory; | 37 | import org.slf4j.LoggerFactory; |
28 | 38 | ||
... | @@ -30,6 +40,9 @@ import java.io.IOException; | ... | @@ -30,6 +40,9 @@ import java.io.IOException; |
30 | import java.util.Set; | 40 | import java.util.Set; |
31 | 41 | ||
32 | import static com.google.common.base.Preconditions.checkNotNull; | 42 | import static com.google.common.base.Preconditions.checkNotNull; |
43 | +import static com.google.common.base.Preconditions.checkArgument; | ||
44 | +import static org.onosproject.xosclient.api.VtnService.NetworkType.*; | ||
45 | +import static org.onosproject.xosclient.api.VtnService.ServiceType.*; | ||
33 | 46 | ||
34 | /** | 47 | /** |
35 | * Provides CORD VTN service and service dependency APIs. | 48 | * Provides CORD VTN service and service dependency APIs. |
... | @@ -113,4 +126,76 @@ public final class DefaultVtnServiceApi extends XosApi implements VtnServiceApi | ... | @@ -113,4 +126,76 @@ public final class DefaultVtnServiceApi extends XosApi implements VtnServiceApi |
113 | } | 126 | } |
114 | return tServices; | 127 | return tServices; |
115 | } | 128 | } |
129 | + | ||
130 | + @Override | ||
131 | + // TODO remove this when XOS provides this information | ||
132 | + public VtnService service(VtnServiceId serviceId, OpenStackAccess osAccess) { | ||
133 | + checkNotNull(osAccess); | ||
134 | + | ||
135 | + OSClient osClient = getOpenStackClient(osAccess); | ||
136 | + Network osNet = osClient.networking().network().get(serviceId.id()); | ||
137 | + if (osNet == null) { | ||
138 | + log.warn("Failed to get OpenStack network {}", serviceId); | ||
139 | + return null; | ||
140 | + } | ||
141 | + | ||
142 | + // assumes all cord service networks has single subnet | ||
143 | + Subnet osSubnet = osNet.getNeutronSubnets().stream() | ||
144 | + .findFirst().orElse(null); | ||
145 | + if (osSubnet == null) { | ||
146 | + log.warn("Failed to get OpenStack subnet of network {}", serviceId); | ||
147 | + return null; | ||
148 | + } | ||
149 | + | ||
150 | + return new VtnService(serviceId, | ||
151 | + osNet.getName(), | ||
152 | + serviceType(osNet.getName()), | ||
153 | + networkType(osNet.getName()), | ||
154 | + Long.parseLong(osNet.getProviderSegID()), | ||
155 | + IpPrefix.valueOf(osSubnet.getCidr()), | ||
156 | + IpAddress.valueOf(osSubnet.getGateway()), | ||
157 | + providerServices(serviceId), | ||
158 | + tenantServices(serviceId)); | ||
159 | + } | ||
160 | + | ||
161 | + // TODO remove this when XOS provides this information | ||
162 | + private OSClient getOpenStackClient(OpenStackAccess osAccess) { | ||
163 | + checkNotNull(osAccess); | ||
164 | + | ||
165 | + // creating a client every time must be inefficient, but this method | ||
166 | + // will be removed once XOS provides equivalent APIs | ||
167 | + return OSFactory.builder() | ||
168 | + .endpoint(osAccess.endpoint()) | ||
169 | + .credentials(osAccess.user(), osAccess.password()) | ||
170 | + .tenantName(osAccess.tenant()) | ||
171 | + .authenticate(); | ||
172 | + } | ||
173 | + | ||
174 | + // TODO remove this when XOS provides this information | ||
175 | + private NetworkType networkType(String netName) { | ||
176 | + checkArgument(!Strings.isNullOrEmpty(netName)); | ||
177 | + | ||
178 | + String name = netName.toUpperCase(); | ||
179 | + if (name.contains(PUBLIC.toString())) { | ||
180 | + return PUBLIC; | ||
181 | + } else if (name.contains(MANAGEMENT.toString())) { | ||
182 | + return MANAGEMENT; | ||
183 | + } else { | ||
184 | + return PRIVATE; | ||
185 | + } | ||
186 | + } | ||
187 | + | ||
188 | + // TODO remove this when XOS provides this information | ||
189 | + private ServiceType serviceType(String netName) { | ||
190 | + checkArgument(!Strings.isNullOrEmpty(netName)); | ||
191 | + | ||
192 | + String name = netName.toUpperCase(); | ||
193 | + if (name.contains(VSG.toString())) { | ||
194 | + return VSG; | ||
195 | + } else if (name.contains(OLT_AGENT.toString())) { | ||
196 | + return OLT_AGENT; | ||
197 | + } else { | ||
198 | + return DUMMY; | ||
199 | + } | ||
200 | + } | ||
116 | } | 201 | } | ... | ... |
... | @@ -81,13 +81,15 @@ public class XosApi { | ... | @@ -81,13 +81,15 @@ public class XosApi { |
81 | public String restGet(String path) { | 81 | public String restGet(String path) { |
82 | WebTarget wt = client.target(access.endpoint() + baseUrl).path(path); | 82 | WebTarget wt = client.target(access.endpoint() + baseUrl).path(path); |
83 | Invocation.Builder builder = wt.request(JSON_UTF_8.toString()); | 83 | Invocation.Builder builder = wt.request(JSON_UTF_8.toString()); |
84 | - | 84 | + try { |
85 | Response response = builder.get(); | 85 | Response response = builder.get(); |
86 | if (response.getStatus() != HTTP_OK) { | 86 | if (response.getStatus() != HTTP_OK) { |
87 | log.warn("Failed to get resource {}", access.endpoint() + baseUrl + path); | 87 | log.warn("Failed to get resource {}", access.endpoint() + baseUrl + path); |
88 | return EMPTY_JSON_STRING; | 88 | return EMPTY_JSON_STRING; |
89 | } | 89 | } |
90 | - | 90 | + } catch (javax.ws.rs.ProcessingException e) { |
91 | + return EMPTY_JSON_STRING; | ||
92 | + } | ||
91 | return builder.get(String.class); | 93 | return builder.get(String.class); |
92 | } | 94 | } |
93 | } | 95 | } | ... | ... |
-
Please register or login to post a comment