blob: 65014d1f959ee1e28eb2d5f97b4db62bad0aeac4 [file] [log] [blame]
sanghoshinf25d2e02015-11-11 23:07:17 +09001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Jian Li7f256f52016-01-24 15:08:05 -080016package org.onosproject.openstackswitching.impl;
sanghoshinf25d2e02015-11-11 23:07:17 +090017
18import com.fasterxml.jackson.databind.ObjectMapper;
19import com.fasterxml.jackson.databind.node.ArrayNode;
20import com.fasterxml.jackson.databind.node.ObjectNode;
21import com.google.common.collect.Lists;
22import com.sun.jersey.api.client.Client;
23import com.sun.jersey.api.client.WebResource;
Jian Li7f256f52016-01-24 15:08:05 -080024import org.onosproject.openstackswitching.OpenstackNetwork;
25import org.onosproject.openstackswitching.OpenstackPort;
26import org.onosproject.openstackswitching.OpenstackSubnet;
sanghoshinf25d2e02015-11-11 23:07:17 +090027import org.onosproject.openstackswitching.web.OpenstackNetworkCodec;
28import org.onosproject.openstackswitching.web.OpenstackPortCodec;
29import org.onosproject.openstackswitching.web.OpenstackSubnetCodec;
30import org.slf4j.Logger;
31import javax.ws.rs.core.MediaType;
32import java.io.IOException;
33import java.util.Collection;
Hyunsun Moonf7895202016-01-12 12:21:48 -080034import java.util.Collections;
sanghoshinf25d2e02015-11-11 23:07:17 +090035import java.util.List;
36
37import static com.google.common.base.Preconditions.checkNotNull;
38import static com.google.common.net.MediaType.JSON_UTF_8;
39import static org.slf4j.LoggerFactory.getLogger;
40
41/**
42 * Handles REST Calls to Openstack Neutron.
43 *
44 */
45public class OpenstackRestHandler {
46
47 private final Logger log = getLogger(getClass());
48 private String neutronUrl;
49 private String keystoneUrl;
50 private String tokenId;
51 private String userName;
52 private String pass;
53
54 /**
55 * Creates OpenstackRestHandler instance.
56 *
57 * @param cfg OpenstackSwitchingConfig reference
58 */
59 public OpenstackRestHandler(OpenstackSwitchingConfig cfg) {
60 this.neutronUrl = checkNotNull(cfg.neutronServer());
61 this.keystoneUrl = checkNotNull(cfg.keystoneServer());
62 this.userName = checkNotNull(cfg.userName());
63 this.pass = checkNotNull(cfg.password());
64 }
65
66 /**
67 * Returns network information stored in Neutron.
68 *
69 * @return List of OpenstackNetwork
70 */
71 public Collection<OpenstackNetwork> getNetworks() {
72
73 WebResource.Builder builder = getClientBuilder(neutronUrl + "networks");
74 String response = builder.accept(MediaType.APPLICATION_JSON_TYPE).
75 header("X-Auth-Token", getToken()).get(String.class);
76
Hyunsun Moonf7895202016-01-12 12:21:48 -080077 log.debug("networks response:" + response);
78
sanghoshinf25d2e02015-11-11 23:07:17 +090079 ObjectMapper mapper = new ObjectMapper();
80 List<OpenstackNetwork> openstackNetworks = Lists.newArrayList();
81 try {
82 ObjectNode node = (ObjectNode) mapper.readTree(response);
83 ArrayNode networkList = (ArrayNode) node.path("networks");
84 OpenstackNetworkCodec networkCodec = new OpenstackNetworkCodec();
85 networkList.forEach(n -> openstackNetworks.add(networkCodec.decode((ObjectNode) n, null)));
86 } catch (IOException e) {
Ray Milkey4fd3ceb2015-12-10 14:43:08 -080087 log.warn("getNetworks()", e);
sanghoshinf25d2e02015-11-11 23:07:17 +090088 }
89
Hyunsun Moonf7895202016-01-12 12:21:48 -080090 openstackNetworks.removeAll(Collections.singleton(null));
sanghoshinf25d2e02015-11-11 23:07:17 +090091 openstackNetworks.forEach(n -> log.debug("network ID: {}", n.id()));
92
93 return openstackNetworks;
94 }
95
96 /**
97 * Returns port information stored in Neutron.
98 *
99 * @return List of OpenstackPort
100 */
101 public Collection<OpenstackPort> getPorts() {
102
103 WebResource.Builder builder = getClientBuilder(neutronUrl + "ports");
104 String response = builder.accept(MediaType.APPLICATION_JSON_TYPE).
105 header("X-Auth-Token", getToken()).get(String.class);
106
107 ObjectMapper mapper = new ObjectMapper();
108 List<OpenstackPort> openstackPorts = Lists.newArrayList();
109 try {
110 ObjectNode node = (ObjectNode) mapper.readTree(response);
111 ArrayNode portList = (ArrayNode) node.path("ports");
112 OpenstackPortCodec portCodec = new OpenstackPortCodec();
113 portList.forEach(p -> openstackPorts.add(portCodec.decode((ObjectNode) p, null)));
114 } catch (IOException e) {
Ray Milkey4fd3ceb2015-12-10 14:43:08 -0800115 log.warn("getPorts()", e);
sanghoshinf25d2e02015-11-11 23:07:17 +0900116 }
117
118 log.debug("port response:" + response);
119 openstackPorts.forEach(n -> log.debug("port ID: {}", n.id()));
120
121 return openstackPorts;
122 }
123
124 /**
125 * Returns Subnet information in Neutron.
126 *
127 * @return List of OpenstackSubnet
128 */
129 public Collection<OpenstackSubnet> getSubnets() {
130
131 WebResource.Builder builder = getClientBuilder(neutronUrl + "subnets");
132 String response = builder.accept(MediaType.APPLICATION_JSON_TYPE).
133 header("X-Auth-Token", getToken()).get(String.class);
134
135 ObjectMapper mapper = new ObjectMapper();
136 List<OpenstackSubnet> subnets = Lists.newArrayList();
137 try {
138 ObjectNode node = (ObjectNode) mapper.readTree(response);
139 ArrayNode subnetList = (ArrayNode) node.path("subnets");
140 OpenstackSubnetCodec subnetCodec = new OpenstackSubnetCodec();
141 subnetList.forEach(s -> subnets.add(subnetCodec.decode((ObjectNode) s, null)));
142 } catch (IOException e) {
Ray Milkey4fd3ceb2015-12-10 14:43:08 -0800143 log.warn("getSubnets()", e);
sanghoshinf25d2e02015-11-11 23:07:17 +0900144 }
145
146 log.debug("subnets response:" + response);
147 subnets.forEach(s -> log.debug("subnet ID: {}", s.id()));
148
149 return subnets;
150 }
151
152 private WebResource.Builder getClientBuilder(String uri) {
153 Client client = Client.create();
154 WebResource resource = client.resource(uri);
155 return resource.accept(JSON_UTF_8.toString())
156 .type(JSON_UTF_8.toString());
157 }
158
159 private String getToken() {
160 if (isTokenInvalid()) {
161 String request = "{\"auth\": {\"tenantName\": \"admin\", " +
162 "\"passwordCredentials\": {\"username\": \"" +
163 userName + "\",\"password\": \"" + pass + "\"}}}";
164 WebResource.Builder builder = getClientBuilder(keystoneUrl + "tokens");
165 String response = builder.accept(MediaType.APPLICATION_JSON).post(String.class, request);
166
167 ObjectMapper mapper = new ObjectMapper();
168 try {
169 ObjectNode node = (ObjectNode) mapper.readTree(response);
170 tokenId = node.path("access").path("token").path("id").asText();
171 } catch (IOException e) {
Ray Milkey4fd3ceb2015-12-10 14:43:08 -0800172 log.warn("getToken()", e);
sanghoshinf25d2e02015-11-11 23:07:17 +0900173 }
174 log.debug("token response:" + response);
175 }
176
177 return tokenId;
178 }
179
180 private boolean isTokenInvalid() {
181 //TODO: validation check for the existing token
182 return true;
183 }
184
185}