Hyunsun Moon

ONOS-4903, ONOS-4929 Fixed to load network config on application start-up

Also improved openstackInterface to create Jersey client once and
give better warnings. Fixed missing web context, too.

Change-Id: Ifc835b98f30d5daf566eb22dfe3af34f23634e09
...@@ -18,6 +18,7 @@ package org.onosproject.openstackinterface.impl; ...@@ -18,6 +18,7 @@ package org.onosproject.openstackinterface.impl;
18 import com.fasterxml.jackson.databind.ObjectMapper; 18 import com.fasterxml.jackson.databind.ObjectMapper;
19 import com.fasterxml.jackson.databind.node.ArrayNode; 19 import com.fasterxml.jackson.databind.node.ArrayNode;
20 import com.fasterxml.jackson.databind.node.ObjectNode; 20 import com.fasterxml.jackson.databind.node.ObjectNode;
21 +import com.google.common.base.Strings;
21 import com.google.common.collect.ImmutableSet; 22 import com.google.common.collect.ImmutableSet;
22 import com.google.common.collect.Lists; 23 import com.google.common.collect.Lists;
23 import org.apache.felix.scr.annotations.Activate; 24 import org.apache.felix.scr.annotations.Activate;
...@@ -26,6 +27,7 @@ import org.apache.felix.scr.annotations.Deactivate; ...@@ -26,6 +27,7 @@ import org.apache.felix.scr.annotations.Deactivate;
26 import org.apache.felix.scr.annotations.Reference; 27 import org.apache.felix.scr.annotations.Reference;
27 import org.apache.felix.scr.annotations.ReferenceCardinality; 28 import org.apache.felix.scr.annotations.ReferenceCardinality;
28 import org.apache.felix.scr.annotations.Service; 29 import org.apache.felix.scr.annotations.Service;
30 +import org.glassfish.jersey.client.ClientProperties;
29 import org.onosproject.core.ApplicationId; 31 import org.onosproject.core.ApplicationId;
30 import org.onosproject.core.CoreService; 32 import org.onosproject.core.CoreService;
31 import org.onosproject.net.Port; 33 import org.onosproject.net.Port;
...@@ -71,6 +73,7 @@ import java.util.stream.Collectors; ...@@ -71,6 +73,7 @@ import java.util.stream.Collectors;
71 import static com.google.common.base.Preconditions.checkNotNull; 73 import static com.google.common.base.Preconditions.checkNotNull;
72 import static com.google.common.net.MediaType.JSON_UTF_8; 74 import static com.google.common.net.MediaType.JSON_UTF_8;
73 import static org.onlab.util.Tools.groupedThreads; 75 import static org.onlab.util.Tools.groupedThreads;
76 +import static org.onosproject.net.AnnotationKeys.PORT_NAME;
74 import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY; 77 import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
75 import static org.slf4j.LoggerFactory.getLogger; 78 import static org.slf4j.LoggerFactory.getLogger;
76 79
...@@ -101,8 +104,11 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService { ...@@ -101,8 +104,11 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
101 104
102 private static final String HEADER_AUTH_TOKEN = "X-Auth-Token"; 105 private static final String HEADER_AUTH_TOKEN = "X-Auth-Token";
103 private static final String TOKEN_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'"; 106 private static final String TOKEN_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
107 + private static final int DEFAULT_TIMEOUT_MS = 2000;
104 108
105 private final Logger log = getLogger(getClass()); 109 private final Logger log = getLogger(getClass());
110 + private final Client client = ClientBuilder.newClient();
111 +
106 private String neutronUrl; 112 private String neutronUrl;
107 private String keystoneUrl; 113 private String keystoneUrl;
108 private String tokenId; 114 private String tokenId;
...@@ -110,8 +116,6 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService { ...@@ -110,8 +116,6 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
110 private String userName; 116 private String userName;
111 private String pass; 117 private String pass;
112 118
113 - private static final String PORT_NAME = "portName";
114 -
115 private ApplicationId appId; 119 private ApplicationId appId;
116 120
117 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 121 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
...@@ -135,7 +139,6 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService { ...@@ -135,7 +139,6 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
135 } 139 }
136 ); 140 );
137 141
138 -
139 @Activate 142 @Activate
140 protected void activate() { 143 protected void activate() {
141 appId = coreService 144 appId = coreService
...@@ -144,6 +147,10 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService { ...@@ -144,6 +147,10 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
144 factories.forEach(cfgService::registerConfigFactory); 147 factories.forEach(cfgService::registerConfigFactory);
145 cfgService.addListener(internalConfigListener); 148 cfgService.addListener(internalConfigListener);
146 149
150 + client.property(ClientProperties.CONNECT_TIMEOUT, DEFAULT_TIMEOUT_MS);
151 + client.property(ClientProperties.READ_TIMEOUT, DEFAULT_TIMEOUT_MS);
152 +
153 + configureNetwork();
147 log.info("started"); 154 log.info("started");
148 } 155 }
149 156
...@@ -160,11 +167,14 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService { ...@@ -160,11 +167,14 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
160 * @return List of OpenstackNetwork 167 * @return List of OpenstackNetwork
161 */ 168 */
162 public Collection<OpenstackNetwork> getNetworks() { 169 public Collection<OpenstackNetwork> getNetworks() {
170 + Invocation.Builder builder = getClientBuilder(neutronUrl, URI_NETWORKS);
171 + if (builder == null) {
172 + log.warn("Failed to get networks");
173 + return Collections.EMPTY_LIST;
174 + }
163 175
164 - Invocation.Builder builder = getClientBuilder(neutronUrl + URI_NETWORKS);
165 String response = builder.accept(MediaType.APPLICATION_JSON_TYPE). 176 String response = builder.accept(MediaType.APPLICATION_JSON_TYPE).
166 header(HEADER_AUTH_TOKEN, getToken()).get(String.class); 177 header(HEADER_AUTH_TOKEN, getToken()).get(String.class);
167 -
168 log.debug("networks response:" + response); 178 log.debug("networks response:" + response);
169 179
170 ObjectMapper mapper = new ObjectMapper(); 180 ObjectMapper mapper = new ObjectMapper();
...@@ -190,8 +200,12 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService { ...@@ -190,8 +200,12 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
190 * @return List of OpenstackPort 200 * @return List of OpenstackPort
191 */ 201 */
192 public Collection<OpenstackPort> getPorts() { 202 public Collection<OpenstackPort> getPorts() {
203 + Invocation.Builder builder = getClientBuilder(neutronUrl, URI_PORTS);
204 + if (builder == null) {
205 + log.warn("Failed to get ports");
206 + return Collections.EMPTY_LIST;
207 + }
193 208
194 - Invocation.Builder builder = getClientBuilder(neutronUrl + URI_PORTS);
195 String response = builder.accept(MediaType.APPLICATION_JSON_TYPE). 209 String response = builder.accept(MediaType.APPLICATION_JSON_TYPE).
196 header(HEADER_AUTH_TOKEN, getToken()).get(String.class); 210 header(HEADER_AUTH_TOKEN, getToken()).get(String.class);
197 211
...@@ -213,7 +227,12 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService { ...@@ -213,7 +227,12 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
213 } 227 }
214 228
215 public Collection<OpenstackRouter> getRouters() { 229 public Collection<OpenstackRouter> getRouters() {
216 - Invocation.Builder builder = getClientBuilder(neutronUrl + PATH_ROUTERS); 230 + Invocation.Builder builder = getClientBuilder(neutronUrl, PATH_ROUTERS);
231 + if (builder == null) {
232 + log.warn("Failed to get routers");
233 + return Collections.EMPTY_LIST;
234 + }
235 +
217 String response = builder.accept(MediaType.APPLICATION_JSON_TYPE). 236 String response = builder.accept(MediaType.APPLICATION_JSON_TYPE).
218 header(HEADER_AUTH_TOKEN, getToken()).get(String.class); 237 header(HEADER_AUTH_TOKEN, getToken()).get(String.class);
219 238
...@@ -242,7 +261,12 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService { ...@@ -242,7 +261,12 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
242 * @return List of OpenstackSubnet 261 * @return List of OpenstackSubnet
243 */ 262 */
244 public Collection<OpenstackSubnet> getSubnets() { 263 public Collection<OpenstackSubnet> getSubnets() {
245 - Invocation.Builder builder = getClientBuilder(neutronUrl + URI_SUBNETS); 264 + Invocation.Builder builder = getClientBuilder(neutronUrl, URI_SUBNETS);
265 + if (builder == null) {
266 + log.warn("Failed to get subnets");
267 + return Collections.EMPTY_LIST;
268 + }
269 +
246 String response = builder.accept(MediaType.APPLICATION_JSON_TYPE). 270 String response = builder.accept(MediaType.APPLICATION_JSON_TYPE).
247 header(HEADER_AUTH_TOKEN, getToken()).get(String.class); 271 header(HEADER_AUTH_TOKEN, getToken()).get(String.class);
248 272
...@@ -270,7 +294,12 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService { ...@@ -270,7 +294,12 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
270 * @return OpenstackSecurityGroup object or null if fails 294 * @return OpenstackSecurityGroup object or null if fails
271 */ 295 */
272 public OpenstackSecurityGroup securityGroup(String id) { 296 public OpenstackSecurityGroup securityGroup(String id) {
273 - Invocation.Builder builder = getClientBuilder(neutronUrl + URI_SECURITY_GROUPS + "/" + id); 297 + Invocation.Builder builder = getClientBuilder(neutronUrl, URI_SECURITY_GROUPS + "/" + id);
298 + if (builder == null) {
299 + log.warn("Failed to get security group {}", id);
300 + return null;
301 + }
302 +
274 String response = builder.accept(MediaType.APPLICATION_JSON_TYPE). 303 String response = builder.accept(MediaType.APPLICATION_JSON_TYPE).
275 header(HEADER_AUTH_TOKEN, getToken()).get(String.class); 304 header(HEADER_AUTH_TOKEN, getToken()).get(String.class);
276 305
...@@ -287,9 +316,13 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService { ...@@ -287,9 +316,13 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
287 return securityGroup; 316 return securityGroup;
288 } 317 }
289 318
290 - private Invocation.Builder getClientBuilder(String uri) { 319 + private Invocation.Builder getClientBuilder(String baseUrl, String path) {
291 - Client client = ClientBuilder.newClient(); 320 + if (Strings.isNullOrEmpty(baseUrl)) {
292 - WebTarget wt = client.target(uri); 321 + log.warn("Keystone or Neutron URL is not set");
322 + return null;
323 + }
324 +
325 + WebTarget wt = client.target(baseUrl + path);
293 return wt.request(JSON_UTF_8.toString()); 326 return wt.request(JSON_UTF_8.toString());
294 } 327 }
295 328
...@@ -298,9 +331,13 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService { ...@@ -298,9 +331,13 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
298 String request = "{\"auth\": {\"tenantName\": \"admin\", " + 331 String request = "{\"auth\": {\"tenantName\": \"admin\", " +
299 "\"passwordCredentials\": {\"username\": \"" + 332 "\"passwordCredentials\": {\"username\": \"" +
300 userName + "\",\"password\": \"" + pass + "\"}}}"; 333 userName + "\",\"password\": \"" + pass + "\"}}}";
301 - Invocation.Builder builder = getClientBuilder(keystoneUrl + URI_TOKENS); 334 + Invocation.Builder builder = getClientBuilder(keystoneUrl, URI_TOKENS);
302 - String response = builder.accept(MediaType.APPLICATION_JSON).post(Entity.json(request), String.class); 335 + if (builder == null) {
336 + log.warn("Failed to get token");
337 + return null;
338 + }
303 339
340 + String response = builder.accept(MediaType.APPLICATION_JSON).post(Entity.json(request), String.class);
304 ObjectMapper mapper = new ObjectMapper(); 341 ObjectMapper mapper = new ObjectMapper();
305 try { 342 try {
306 ObjectNode node = (ObjectNode) mapper.readTree(response); 343 ObjectNode node = (ObjectNode) mapper.readTree(response);
...@@ -420,7 +457,12 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService { ...@@ -420,7 +457,12 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
420 457
421 @Override 458 @Override
422 public Collection<OpenstackFloatingIP> floatingIps() { 459 public Collection<OpenstackFloatingIP> floatingIps() {
423 - Invocation.Builder builder = getClientBuilder(neutronUrl + URI_FLOATINGIPS); 460 + Invocation.Builder builder = getClientBuilder(neutronUrl, URI_FLOATINGIPS);
461 + if (builder == null) {
462 + log.warn("Failed to get floating IPs");
463 + return Collections.EMPTY_LIST;
464 + }
465 +
424 String response = builder.accept(MediaType.APPLICATION_JSON_TYPE). 466 String response = builder.accept(MediaType.APPLICATION_JSON_TYPE).
425 header(HEADER_AUTH_TOKEN, getToken()).get(String.class); 467 header(HEADER_AUTH_TOKEN, getToken()).get(String.class);
426 468
...@@ -442,21 +484,21 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService { ...@@ -442,21 +484,21 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
442 return openstackFloatingIPs; 484 return openstackFloatingIPs;
443 } 485 }
444 486
445 - private class InternalConfigListener implements NetworkConfigListener { 487 + private void configureNetwork() {
488 + OpenstackInterfaceConfig cfg =
489 + cfgService.getConfig(appId, OpenstackInterfaceConfig.class);
490 + if (cfg == null) {
491 + log.error("There is no openstack server information in config.");
492 + return;
493 + }
446 494
447 - public void configureNetwork() { 495 + neutronUrl = checkNotNull(cfg.neutronServer());
448 - OpenstackInterfaceConfig cfg = 496 + keystoneUrl = checkNotNull(cfg.keystoneServer());
449 - cfgService.getConfig(appId, OpenstackInterfaceConfig.class); 497 + userName = checkNotNull(cfg.userName());
450 - if (cfg == null) { 498 + pass = checkNotNull(cfg.password());
451 - log.error("There is no openstack server information in config."); 499 + }
452 - return;
453 - }
454 500
455 - neutronUrl = checkNotNull(cfg.neutronServer()); 501 + private class InternalConfigListener implements NetworkConfigListener {
456 - keystoneUrl = checkNotNull(cfg.keystoneServer());
457 - userName = checkNotNull(cfg.userName());
458 - pass = checkNotNull(cfg.password());
459 - }
460 502
461 @Override 503 @Override
462 public void event(NetworkConfigEvent event) { 504 public void event(NetworkConfigEvent event) {
...@@ -465,7 +507,7 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService { ...@@ -465,7 +507,7 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
465 event.configClass().equals(OpenstackInterfaceConfig.class)) { 507 event.configClass().equals(OpenstackInterfaceConfig.class)) {
466 508
467 log.info("Network configuration changed"); 509 log.info("Network configuration changed");
468 - networkEventExcutorService.execute(this::configureNetwork); 510 + networkEventExcutorService.execute(() -> configureNetwork());
469 } 511 }
470 } 512 }
471 } 513 }
......
...@@ -10,4 +10,5 @@ COMPILE_DEPS = [ ...@@ -10,4 +10,5 @@ COMPILE_DEPS = [
10 10
11 osgi_jar_with_tests ( 11 osgi_jar_with_tests (
12 deps = COMPILE_DEPS, 12 deps = COMPILE_DEPS,
13 + web_context = '/onos/openstackswitching'
13 ) 14 )
......
...@@ -184,6 +184,7 @@ public final class OpenstackNodeManager extends ListenerRegistry<OpenstackNodeEv ...@@ -184,6 +184,7 @@ public final class OpenstackNodeManager extends ListenerRegistry<OpenstackNodeEv
184 configRegistry.addListener(configListener); 184 configRegistry.addListener(configListener);
185 componentConfigService.registerProperties(getClass()); 185 componentConfigService.registerProperties(getClass());
186 186
187 + readConfiguration();
187 log.info("Started"); 188 log.info("Started");
188 } 189 }
189 190
......