| /* |
| * Copyright 2015 Open Networking Laboratory |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.onosproject.openstacknetworking.web; |
| |
| import com.fasterxml.jackson.databind.ObjectMapper; |
| import com.fasterxml.jackson.databind.node.ArrayNode; |
| import com.fasterxml.jackson.databind.node.ObjectNode; |
| import com.google.common.collect.Lists; |
| import com.sun.jersey.api.client.Client; |
| import com.sun.jersey.api.client.WebResource; |
| import org.apache.felix.scr.annotations.Activate; |
| import org.apache.felix.scr.annotations.Component; |
| 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.onosproject.core.ApplicationId; |
| import org.onosproject.core.CoreService; |
| import org.onosproject.net.Port; |
| import org.onosproject.net.driver.DriverService; |
| import org.onosproject.openstacknetworking.OpenstackNetwork; |
| import org.onosproject.openstacknetworking.OpenstackNetworkingService; |
| import org.onosproject.openstacknetworking.OpenstackPort; |
| import org.onosproject.openstacknetworking.OpenstackPortInfo; |
| import org.onosproject.openstacknetworking.OpenstackRouter; |
| import org.onosproject.openstacknetworking.OpenstackSecurityGroup; |
| import org.onosproject.openstacknetworking.OpenstackSubnet; |
| import org.onosproject.openstacknetworking.OpenstackSwitchingService; |
| import org.slf4j.Logger; |
| import javax.ws.rs.core.MediaType; |
| import java.io.IOException; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.List; |
| import java.util.Map; |
| 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.slf4j.LoggerFactory.getLogger; |
| |
| /** |
| * Handles REST Calls to Openstack Neutron. |
| * |
| */ |
| @Service |
| @Component(immediate = true) |
| public class OpenstackNetworkingManager implements OpenstackNetworkingService { |
| |
| private static final String URI_NETWORKS = "networks"; |
| private static final String URI_PORTS = "ports"; |
| private static final String URI_SUBNETS = "subnets"; |
| private static final String URI_SECURITY_GROUPS = "security-groups"; |
| private static final String URI_TOKENS = "tokens"; |
| |
| private static final String PATH_ROUTERS = "routers"; |
| private static final String PATH_NETWORKS = "networks"; |
| private static final String PATH_PORTS = "ports"; |
| private static final String PATH_SUBNETS = "subnets"; |
| private static final String PATH_ACCESS = "access"; |
| private static final String PATH_TOKEN = "token"; |
| private static final String PATH_ID = "id"; |
| |
| private static final String HEADER_AUTH_TOKEN = "X-Auth-Token"; |
| |
| private final Logger log = getLogger(getClass()); |
| private String neutronUrl; |
| private String keystoneUrl; |
| private String tokenId; |
| private String userName; |
| private String pass; |
| |
| private static final String PORT_NAME = "portName"; |
| |
| private ApplicationId appId; |
| |
| @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| protected CoreService coreService; |
| |
| @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| protected DriverService driverService; |
| |
| protected OpenstackSwitchingService openstackSwitchingService; |
| |
| @Activate |
| protected void activate() { |
| appId = coreService |
| .registerApplication("org.onosproject.openstacknetworking"); |
| |
| log.info("started"); |
| } |
| |
| @Deactivate |
| protected void deactivate() { |
| log.info("stopped"); |
| } |
| |
| /** |
| * Returns network information stored in Neutron. |
| * |
| * @return List of OpenstackNetwork |
| */ |
| public Collection<OpenstackNetwork> getNetworks() { |
| |
| WebResource.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(); |
| List<OpenstackNetwork> openstackNetworks = Lists.newArrayList(); |
| try { |
| ObjectNode node = (ObjectNode) mapper.readTree(response); |
| ArrayNode networkList = (ArrayNode) node.path(PATH_NETWORKS); |
| OpenstackNetworkCodec networkCodec = new OpenstackNetworkCodec(); |
| networkList.forEach(n -> openstackNetworks.add(networkCodec.decode((ObjectNode) n, null))); |
| } catch (IOException e) { |
| log.warn("getNetworks()", e); |
| } |
| |
| openstackNetworks.removeAll(Collections.singleton(null)); |
| openstackNetworks.forEach(n -> log.debug("network ID: {}", n.id())); |
| |
| return openstackNetworks; |
| } |
| |
| /** |
| * Returns port information stored in Neutron. |
| * |
| * @return List of OpenstackPort |
| */ |
| public Collection<OpenstackPort> getPorts() { |
| |
| WebResource.Builder builder = getClientBuilder(neutronUrl + URI_PORTS); |
| String response = builder.accept(MediaType.APPLICATION_JSON_TYPE). |
| header(HEADER_AUTH_TOKEN, getToken()).get(String.class); |
| |
| ObjectMapper mapper = new ObjectMapper(); |
| List<OpenstackPort> openstackPorts = Lists.newArrayList(); |
| try { |
| ObjectNode node = (ObjectNode) mapper.readTree(response); |
| ArrayNode portList = (ArrayNode) node.path(PATH_PORTS); |
| OpenstackPortCodec portCodec = new OpenstackPortCodec(); |
| portList.forEach(p -> openstackPorts.add(portCodec.decode((ObjectNode) p, null))); |
| } catch (IOException e) { |
| log.warn("getPorts()", e); |
| } |
| |
| log.debug("port response:" + response); |
| openstackPorts.forEach(n -> log.debug("port ID: {}", n.id())); |
| |
| return openstackPorts; |
| } |
| |
| public Collection<OpenstackRouter> getRouters() { |
| WebResource.Builder builder = getClientBuilder(neutronUrl + PATH_ROUTERS); |
| String response = builder.accept(MediaType.APPLICATION_JSON_TYPE). |
| header(HEADER_AUTH_TOKEN, getToken()).get(String.class); |
| |
| ObjectMapper mapper = new ObjectMapper(); |
| List<OpenstackRouter> openstackRouters = Lists.newArrayList(); |
| |
| try { |
| ObjectNode node = (ObjectNode) mapper.readTree(response); |
| ArrayNode routerList = (ArrayNode) node.path(PATH_ROUTERS); |
| OpenstackRouterCodec openstackRouterCodec = new OpenstackRouterCodec(); |
| routerList.forEach(r -> openstackRouters |
| .add(openstackRouterCodec.decode((ObjectNode) r, null))); |
| } catch (IOException e) { |
| log.warn("getRouters()", e); |
| } |
| |
| log.debug("router response:" + response); |
| openstackRouters.forEach(r -> log.debug("router ID: {}", r.id())); |
| |
| return openstackRouters; |
| } |
| |
| /** |
| * Returns Subnet information in Neutron. |
| * |
| * @return List of OpenstackSubnet |
| */ |
| public Collection<OpenstackSubnet> getSubnets() { |
| |
| WebResource.Builder builder = getClientBuilder(neutronUrl + URI_SUBNETS); |
| String response = builder.accept(MediaType.APPLICATION_JSON_TYPE). |
| header(HEADER_AUTH_TOKEN, getToken()).get(String.class); |
| |
| ObjectMapper mapper = new ObjectMapper(); |
| List<OpenstackSubnet> subnets = Lists.newArrayList(); |
| try { |
| ObjectNode node = (ObjectNode) mapper.readTree(response); |
| ArrayNode subnetList = (ArrayNode) node.path(PATH_SUBNETS); |
| OpenstackSubnetCodec subnetCodec = new OpenstackSubnetCodec(); |
| subnetList.forEach(s -> subnets.add(subnetCodec.decode((ObjectNode) s, null))); |
| } catch (IOException e) { |
| log.warn("getSubnets()", e); |
| } |
| |
| log.debug("subnets response:" + response); |
| subnets.forEach(s -> log.debug("subnet ID: {}", s.id())); |
| |
| return subnets; |
| } |
| |
| /** |
| * Extracts OpenstackSecurityGroup information for the ID. |
| * |
| * @param id Security Group ID |
| * @return OpenstackSecurityGroup object or null if fails |
| */ |
| public OpenstackSecurityGroup getSecurityGroup(String id) { |
| WebResource.Builder builder = getClientBuilder(neutronUrl + URI_SECURITY_GROUPS + "/" + id); |
| String response = builder.accept(MediaType.APPLICATION_JSON_TYPE). |
| header(HEADER_AUTH_TOKEN, getToken()).get(String.class); |
| |
| ObjectMapper mapper = new ObjectMapper(); |
| OpenstackSecurityGroup securityGroup = null; |
| try { |
| ObjectNode node = (ObjectNode) mapper.readTree(response); |
| OpenstackSecurityGroupCodec sgCodec = new OpenstackSecurityGroupCodec(); |
| securityGroup = sgCodec.decode(node, null); |
| } catch (IOException e) { |
| log.warn("getSecurityGroup()", e); |
| } |
| |
| return securityGroup; |
| } |
| |
| private WebResource.Builder getClientBuilder(String uri) { |
| Client client = Client.create(); |
| WebResource resource = client.resource(uri); |
| return resource.accept(JSON_UTF_8.toString()) |
| .type(JSON_UTF_8.toString()); |
| } |
| |
| private String getToken() { |
| if (isTokenInvalid()) { |
| String request = "{\"auth\": {\"tenantName\": \"admin\", " + |
| "\"passwordCredentials\": {\"username\": \"" + |
| userName + "\",\"password\": \"" + pass + "\"}}}"; |
| WebResource.Builder builder = getClientBuilder(keystoneUrl + URI_TOKENS); |
| String response = builder.accept(MediaType.APPLICATION_JSON).post(String.class, request); |
| |
| ObjectMapper mapper = new ObjectMapper(); |
| try { |
| ObjectNode node = (ObjectNode) mapper.readTree(response); |
| tokenId = node.path(PATH_ACCESS).path(PATH_TOKEN).path(PATH_ID).asText(); |
| } catch (IOException e) { |
| log.warn("getToken()", e); |
| } |
| log.debug("token response:" + response); |
| } |
| |
| return tokenId; |
| } |
| |
| private boolean isTokenInvalid() { |
| //TODO: validation check for the existing token |
| return true; |
| } |
| |
| @Override |
| public Collection<OpenstackPort> ports(String networkId) { |
| return getPorts().stream() |
| .filter(port -> port.networkId().equals(networkId)) |
| .collect(Collectors.toList()); |
| } |
| |
| @Override |
| public Collection<OpenstackPort> ports() { |
| return getPorts(); |
| } |
| |
| @Override |
| public OpenstackPort port(Port port) { |
| String uuid = port.annotations().value(PORT_NAME).substring(3); |
| return getPorts().stream() |
| .filter(p -> p.id().startsWith(uuid)) |
| .findAny().orElse(null); |
| } |
| |
| @Override |
| public OpenstackPort port(String portId) { |
| return getPorts().stream() |
| .filter(p -> p.id().equals(portId)) |
| .findAny().orElse(null); |
| } |
| |
| @Override |
| public OpenstackNetwork network(String networkId) { |
| return getNetworks().stream() |
| .filter(n -> n.id().equals(networkId)) |
| .findAny().orElse(null); |
| } |
| |
| @Override |
| public Collection<OpenstackNetwork> networks() { |
| return getNetworks(); |
| } |
| |
| @Override |
| public OpenstackSubnet subnet(String subnetId) { |
| return getSubnets().stream() |
| .filter(subnet -> subnet.id().equals(subnetId)) |
| .findAny().orElse(null); |
| } |
| |
| @Override |
| public Collection<OpenstackSubnet> subnets() { |
| return getSubnets(); |
| } |
| |
| @Override |
| public Collection<OpenstackRouter> routers() { |
| return getRouters(); |
| } |
| |
| @Override |
| public OpenstackRouter router(String routerId) { |
| return getRouters().stream() |
| .filter(router -> router.id().equals(routerId)) |
| .findAny().orElse(null); |
| } |
| |
| @Override |
| public Map<String, OpenstackPortInfo> openstackPortInfo() { |
| return openstackSwitchingService.openstackPortInfo(); |
| } |
| |
| @Override |
| public void setConfigurations(String neutronUrl, String keystoneUrl, String userName, String pass) { |
| this.neutronUrl = checkNotNull(neutronUrl); |
| this.keystoneUrl = checkNotNull(keystoneUrl); |
| this.userName = checkNotNull(userName); |
| this.pass = checkNotNull(pass); |
| } |
| } |