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;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import org.apache.felix.scr.annotations.Activate;
......@@ -26,6 +27,7 @@ import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.glassfish.jersey.client.ClientProperties;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.net.Port;
......@@ -71,6 +73,7 @@ import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.net.MediaType.JSON_UTF_8;
import static org.onlab.util.Tools.groupedThreads;
import static org.onosproject.net.AnnotationKeys.PORT_NAME;
import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
import static org.slf4j.LoggerFactory.getLogger;
......@@ -101,8 +104,11 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
private static final String HEADER_AUTH_TOKEN = "X-Auth-Token";
private static final String TOKEN_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
private static final int DEFAULT_TIMEOUT_MS = 2000;
private final Logger log = getLogger(getClass());
private final Client client = ClientBuilder.newClient();
private String neutronUrl;
private String keystoneUrl;
private String tokenId;
......@@ -110,8 +116,6 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
private String userName;
private String pass;
private static final String PORT_NAME = "portName";
private ApplicationId appId;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
......@@ -135,7 +139,6 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
}
);
@Activate
protected void activate() {
appId = coreService
......@@ -144,6 +147,10 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
factories.forEach(cfgService::registerConfigFactory);
cfgService.addListener(internalConfigListener);
client.property(ClientProperties.CONNECT_TIMEOUT, DEFAULT_TIMEOUT_MS);
client.property(ClientProperties.READ_TIMEOUT, DEFAULT_TIMEOUT_MS);
configureNetwork();
log.info("started");
}
......@@ -160,11 +167,14 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
* @return List of OpenstackNetwork
*/
public Collection<OpenstackNetwork> getNetworks() {
Invocation.Builder builder = getClientBuilder(neutronUrl, URI_NETWORKS);
if (builder == null) {
log.warn("Failed to get networks");
return Collections.EMPTY_LIST;
}
Invocation.Builder builder = getClientBuilder(neutronUrl + URI_NETWORKS);
String response = builder.accept(MediaType.APPLICATION_JSON_TYPE).
header(HEADER_AUTH_TOKEN, getToken()).get(String.class);
log.debug("networks response:" + response);
ObjectMapper mapper = new ObjectMapper();
......@@ -190,8 +200,12 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
* @return List of OpenstackPort
*/
public Collection<OpenstackPort> getPorts() {
Invocation.Builder builder = getClientBuilder(neutronUrl, URI_PORTS);
if (builder == null) {
log.warn("Failed to get ports");
return Collections.EMPTY_LIST;
}
Invocation.Builder builder = getClientBuilder(neutronUrl + URI_PORTS);
String response = builder.accept(MediaType.APPLICATION_JSON_TYPE).
header(HEADER_AUTH_TOKEN, getToken()).get(String.class);
......@@ -213,7 +227,12 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
}
public Collection<OpenstackRouter> getRouters() {
Invocation.Builder builder = getClientBuilder(neutronUrl + PATH_ROUTERS);
Invocation.Builder builder = getClientBuilder(neutronUrl, PATH_ROUTERS);
if (builder == null) {
log.warn("Failed to get routers");
return Collections.EMPTY_LIST;
}
String response = builder.accept(MediaType.APPLICATION_JSON_TYPE).
header(HEADER_AUTH_TOKEN, getToken()).get(String.class);
......@@ -242,7 +261,12 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
* @return List of OpenstackSubnet
*/
public Collection<OpenstackSubnet> getSubnets() {
Invocation.Builder builder = getClientBuilder(neutronUrl + URI_SUBNETS);
Invocation.Builder builder = getClientBuilder(neutronUrl, URI_SUBNETS);
if (builder == null) {
log.warn("Failed to get subnets");
return Collections.EMPTY_LIST;
}
String response = builder.accept(MediaType.APPLICATION_JSON_TYPE).
header(HEADER_AUTH_TOKEN, getToken()).get(String.class);
......@@ -270,7 +294,12 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
* @return OpenstackSecurityGroup object or null if fails
*/
public OpenstackSecurityGroup securityGroup(String id) {
Invocation.Builder builder = getClientBuilder(neutronUrl + URI_SECURITY_GROUPS + "/" + id);
Invocation.Builder builder = getClientBuilder(neutronUrl, URI_SECURITY_GROUPS + "/" + id);
if (builder == null) {
log.warn("Failed to get security group {}", id);
return null;
}
String response = builder.accept(MediaType.APPLICATION_JSON_TYPE).
header(HEADER_AUTH_TOKEN, getToken()).get(String.class);
......@@ -287,9 +316,13 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
return securityGroup;
}
private Invocation.Builder getClientBuilder(String uri) {
Client client = ClientBuilder.newClient();
WebTarget wt = client.target(uri);
private Invocation.Builder getClientBuilder(String baseUrl, String path) {
if (Strings.isNullOrEmpty(baseUrl)) {
log.warn("Keystone or Neutron URL is not set");
return null;
}
WebTarget wt = client.target(baseUrl + path);
return wt.request(JSON_UTF_8.toString());
}
......@@ -298,9 +331,13 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
String request = "{\"auth\": {\"tenantName\": \"admin\", " +
"\"passwordCredentials\": {\"username\": \"" +
userName + "\",\"password\": \"" + pass + "\"}}}";
Invocation.Builder builder = getClientBuilder(keystoneUrl + URI_TOKENS);
String response = builder.accept(MediaType.APPLICATION_JSON).post(Entity.json(request), String.class);
Invocation.Builder builder = getClientBuilder(keystoneUrl, URI_TOKENS);
if (builder == null) {
log.warn("Failed to get token");
return null;
}
String response = builder.accept(MediaType.APPLICATION_JSON).post(Entity.json(request), String.class);
ObjectMapper mapper = new ObjectMapper();
try {
ObjectNode node = (ObjectNode) mapper.readTree(response);
......@@ -420,7 +457,12 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
@Override
public Collection<OpenstackFloatingIP> floatingIps() {
Invocation.Builder builder = getClientBuilder(neutronUrl + URI_FLOATINGIPS);
Invocation.Builder builder = getClientBuilder(neutronUrl, URI_FLOATINGIPS);
if (builder == null) {
log.warn("Failed to get floating IPs");
return Collections.EMPTY_LIST;
}
String response = builder.accept(MediaType.APPLICATION_JSON_TYPE).
header(HEADER_AUTH_TOKEN, getToken()).get(String.class);
......@@ -442,21 +484,21 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
return openstackFloatingIPs;
}
private class InternalConfigListener implements NetworkConfigListener {
private void configureNetwork() {
OpenstackInterfaceConfig cfg =
cfgService.getConfig(appId, OpenstackInterfaceConfig.class);
if (cfg == null) {
log.error("There is no openstack server information in config.");
return;
}
public void configureNetwork() {
OpenstackInterfaceConfig cfg =
cfgService.getConfig(appId, OpenstackInterfaceConfig.class);
if (cfg == null) {
log.error("There is no openstack server information in config.");
return;
}
neutronUrl = checkNotNull(cfg.neutronServer());
keystoneUrl = checkNotNull(cfg.keystoneServer());
userName = checkNotNull(cfg.userName());
pass = checkNotNull(cfg.password());
}
neutronUrl = checkNotNull(cfg.neutronServer());
keystoneUrl = checkNotNull(cfg.keystoneServer());
userName = checkNotNull(cfg.userName());
pass = checkNotNull(cfg.password());
}
private class InternalConfigListener implements NetworkConfigListener {
@Override
public void event(NetworkConfigEvent event) {
......@@ -465,7 +507,7 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
event.configClass().equals(OpenstackInterfaceConfig.class)) {
log.info("Network configuration changed");
networkEventExcutorService.execute(this::configureNetwork);
networkEventExcutorService.execute(() -> configureNetwork());
}
}
}
......
......@@ -10,4 +10,5 @@ COMPILE_DEPS = [
osgi_jar_with_tests (
deps = COMPILE_DEPS,
web_context = '/onos/openstackswitching'
)
......
......@@ -184,6 +184,7 @@ public final class OpenstackNodeManager extends ListenerRegistry<OpenstackNodeEv
configRegistry.addListener(configListener);
componentConfigService.registerProperties(getClass());
readConfiguration();
log.info("Started");
}
......