jiangrui
Committed by Gerrit Code Review

[ONOS-2755] add restfull service of floatingIp

Change-Id: Ife1ee53639f64136d72267d205c71d2766d7d97b
1 +/*
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 + */
16 +package org.onosproject.vtnweb.resources;
17 +
18 +import static com.google.common.base.Preconditions.checkNotNull;
19 +import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
20 +import static javax.ws.rs.core.Response.Status.NOT_FOUND;
21 +import static javax.ws.rs.core.Response.Status.CREATED;
22 +import static javax.ws.rs.core.Response.Status.CONFLICT;
23 +import static javax.ws.rs.core.Response.Status.NO_CONTENT;
24 +
25 +import java.io.IOException;
26 +import java.io.InputStream;
27 +import java.util.Collection;
28 +import java.util.Collections;
29 +import java.util.HashMap;
30 +import java.util.List;
31 +import java.util.Map;
32 +import java.util.Set;
33 +
34 +import javax.ws.rs.Consumes;
35 +import javax.ws.rs.DELETE;
36 +import javax.ws.rs.GET;
37 +import javax.ws.rs.POST;
38 +import javax.ws.rs.PUT;
39 +import javax.ws.rs.Path;
40 +import javax.ws.rs.PathParam;
41 +import javax.ws.rs.Produces;
42 +import javax.ws.rs.QueryParam;
43 +import javax.ws.rs.core.MediaType;
44 +import javax.ws.rs.core.Response;
45 +
46 +import org.onlab.packet.IpAddress;
47 +import org.onlab.util.ItemNotFoundException;
48 +import org.onosproject.rest.AbstractWebResource;
49 +import org.onosproject.vtnrsc.DefaultFloatingIp;
50 +import org.onosproject.vtnrsc.FloatingIp;
51 +import org.onosproject.vtnrsc.FloatingIpId;
52 +import org.onosproject.vtnrsc.TenantId;
53 +import org.onosproject.vtnrsc.TenantNetworkId;
54 +import org.onosproject.vtnrsc.VirtualPortId;
55 +import org.onosproject.vtnrsc.RouterId;
56 +import org.onosproject.vtnrsc.FloatingIp.Status;
57 +import org.onosproject.vtnrsc.floatingip.FloatingIpService;
58 +import org.onosproject.vtnweb.web.FloatingIpCodec;
59 +import org.slf4j.Logger;
60 +import org.slf4j.LoggerFactory;
61 +
62 +import com.fasterxml.jackson.databind.JsonNode;
63 +import com.fasterxml.jackson.databind.ObjectMapper;
64 +import com.fasterxml.jackson.databind.node.ObjectNode;
65 +import com.google.common.collect.Sets;
66 +
67 +@Path("floatingips")
68 +public class FloatingIpWebResource extends AbstractWebResource {
69 + private final Logger log = LoggerFactory
70 + .getLogger(FloatingIpWebResource.class);
71 + public static final String CREATE_FAIL = "Floating IP is failed to create!";
72 + public static final String UPDATE_FAIL = "Floating IP is failed to update!";
73 + public static final String GET_FAIL = "Floating IP is failed to get!";
74 + public static final String NOT_EXIST = "Floating IP does not exist!";
75 + public static final String DELETE_SUCCESS = "Floating IP delete success!";
76 + public static final String JSON_NOT_NULL = "JsonNode can not be null";
77 +
78 + @GET
79 + @Produces(MediaType.APPLICATION_JSON)
80 + public Response listFloatingIps() {
81 + Collection<FloatingIp> floatingIps = get(FloatingIpService.class)
82 + .getFloatingIps();
83 + ObjectNode result = new ObjectMapper().createObjectNode();
84 + result.set("floatingips",
85 + new FloatingIpCodec().encode(floatingIps, this));
86 + return ok(result.toString()).build();
87 + }
88 +
89 + @GET
90 + @Path("{floatingIpUUID}")
91 + @Produces(MediaType.APPLICATION_JSON)
92 + public Response getFloatingIp(@PathParam("floatingIpUUID") String id,
93 + @QueryParam("fields") List<String> fields) {
94 +
95 + if (!get(FloatingIpService.class).exists(FloatingIpId.of(id))) {
96 + return Response.status(NOT_FOUND).entity(NOT_EXIST).build();
97 + }
98 + FloatingIp sub = nullIsNotFound(get(FloatingIpService.class)
99 + .getFloatingIp(FloatingIpId.of(id)), GET_FAIL);
100 +
101 + ObjectNode result = new ObjectMapper().createObjectNode();
102 + if (fields.size() > 0) {
103 + result.set("floatingip",
104 + new FloatingIpCodec().extracFields(sub, this, fields));
105 + } else {
106 + result.set("floatingip", new FloatingIpCodec().encode(sub, this));
107 + }
108 + return ok(result.toString()).build();
109 + }
110 +
111 + @POST
112 + @Produces(MediaType.APPLICATION_JSON)
113 + @Consumes(MediaType.APPLICATION_JSON)
114 + public Response createFloatingIp(final InputStream input) {
115 + try {
116 + ObjectMapper mapper = new ObjectMapper();
117 + JsonNode subnode = mapper.readTree(input);
118 + Collection<FloatingIp> floatingIps = createOrUpdateByInputStream(subnode);
119 + Boolean result = nullIsNotFound((get(FloatingIpService.class)
120 + .createFloatingIps(floatingIps)),
121 + CREATE_FAIL);
122 + if (!result) {
123 + return Response.status(CONFLICT).entity(CREATE_FAIL).build();
124 + }
125 + return Response.status(CREATED).entity(result.toString()).build();
126 +
127 + } catch (Exception e) {
128 + return Response.status(BAD_REQUEST).entity(e.getMessage()).build();
129 + }
130 + }
131 +
132 + @PUT
133 + @Path("{floatingIpUUID}")
134 + @Produces(MediaType.APPLICATION_JSON)
135 + @Consumes(MediaType.APPLICATION_JSON)
136 + public Response updateFloatingIp(@PathParam("floatingIpUUID") String id,
137 + final InputStream input) {
138 + try {
139 + ObjectMapper mapper = new ObjectMapper();
140 + JsonNode subnode = mapper.readTree(input);
141 + Collection<FloatingIp> floatingIps = createOrUpdateByInputStream(subnode);
142 + Boolean result = nullIsNotFound(get(FloatingIpService.class)
143 + .updateFloatingIps(floatingIps), UPDATE_FAIL);
144 + if (!result) {
145 + return Response.status(CONFLICT).entity(UPDATE_FAIL).build();
146 + }
147 + return ok(result.toString()).build();
148 + } catch (Exception e) {
149 + return Response.status(BAD_REQUEST).entity(e.getMessage()).build();
150 + }
151 + }
152 +
153 + @Path("{floatingIpUUID}")
154 + @DELETE
155 + public Response deleteSingleFloatingIp(@PathParam("floatingIpUUID") String id)
156 + throws IOException {
157 + try {
158 + FloatingIpId floatingIpId = FloatingIpId.of(id);
159 + Set<FloatingIpId> floatingIpIds = Sets.newHashSet(floatingIpId);
160 + get(FloatingIpService.class).removeFloatingIps(floatingIpIds);
161 + return Response.status(NO_CONTENT).entity(DELETE_SUCCESS).build();
162 + } catch (Exception e) {
163 + return Response.status(NOT_FOUND).entity(e.getMessage()).build();
164 + }
165 + }
166 +
167 + private Collection<FloatingIp> createOrUpdateByInputStream(JsonNode subnode)
168 + throws Exception {
169 + checkNotNull(subnode, JSON_NOT_NULL);
170 + Collection<FloatingIp> floatingIps = null;
171 + JsonNode floatingIpNodes = subnode.get("floatingips");
172 + if (floatingIpNodes == null) {
173 + floatingIpNodes = subnode.get("floatingip");
174 + }
175 + log.debug("floatingNodes is {}", floatingIpNodes.toString());
176 +
177 + if (floatingIpNodes.isArray()) {
178 + throw new IllegalArgumentException("only singleton requests allowed");
179 + } else {
180 + floatingIps = changeJsonToSub(floatingIpNodes);
181 + }
182 + return floatingIps;
183 + }
184 +
185 + /**
186 + * Returns a collection of floatingIps from floatingIpNodes.
187 + *
188 + * @param floatingIpNodes the floatingIp json node
189 + * @return floatingIps a collection of floatingIp
190 + * @throws Exception
191 + */
192 + public Collection<FloatingIp> changeJsonToSub(JsonNode floatingIpNodes)
193 + throws Exception {
194 + checkNotNull(floatingIpNodes, JSON_NOT_NULL);
195 + Map<FloatingIpId, FloatingIp> subMap = new HashMap<FloatingIpId, FloatingIp>();
196 + if (!floatingIpNodes.hasNonNull("id")) {
197 + throw new IllegalArgumentException("id should not be null");
198 + } else if (floatingIpNodes.get("id").asText().isEmpty()) {
199 + throw new IllegalArgumentException("id should not be empty");
200 + }
201 + FloatingIpId id = FloatingIpId.of(floatingIpNodes.get("id")
202 + .asText());
203 +
204 + if (!floatingIpNodes.hasNonNull("tenant_id")) {
205 + throw new IllegalArgumentException("tenant_id should not be null");
206 + } else if (floatingIpNodes.get("tenant_id").asText().isEmpty()) {
207 + throw new IllegalArgumentException("tenant_id should not be empty");
208 + }
209 + TenantId tenantId = TenantId.tenantId(floatingIpNodes.get("tenant_id")
210 + .asText());
211 +
212 + if (!floatingIpNodes.hasNonNull("floating_network_id")) {
213 + throw new IllegalArgumentException(
214 + "floating_network_id should not be null");
215 + } else if (floatingIpNodes.get("floating_network_id").asText()
216 + .isEmpty()) {
217 + throw new IllegalArgumentException(
218 + "floating_network_id should not be empty");
219 + }
220 + TenantNetworkId networkId = TenantNetworkId.networkId(floatingIpNodes
221 + .get("floating_network_id").asText());
222 +
223 + VirtualPortId portId = null;
224 + if (floatingIpNodes.hasNonNull("port_id")) {
225 + portId = VirtualPortId.portId(floatingIpNodes.get("port_id")
226 + .asText());
227 + }
228 +
229 + RouterId routerId = null;
230 + if (floatingIpNodes.hasNonNull("router_id")) {
231 + routerId = RouterId.valueOf(floatingIpNodes.get("router_id")
232 + .asText());
233 + }
234 +
235 + IpAddress fixedIp = null;
236 + if (floatingIpNodes.hasNonNull("fixed_ip_address")) {
237 + fixedIp = IpAddress.valueOf(floatingIpNodes.get("fixed_ip_address")
238 + .asText());
239 + }
240 +
241 + if (!floatingIpNodes.hasNonNull("floating_ip_address")) {
242 + throw new IllegalArgumentException(
243 + "floating_ip_address should not be null");
244 + } else if (floatingIpNodes.get("floating_ip_address").asText()
245 + .isEmpty()) {
246 + throw new IllegalArgumentException(
247 + "floating_ip_address should not be empty");
248 + }
249 + IpAddress floatingIp = IpAddress.valueOf(floatingIpNodes
250 + .get("floating_ip_address").asText());
251 +
252 + if (!floatingIpNodes.hasNonNull("status")) {
253 + throw new IllegalArgumentException("status should not be null");
254 + } else if (floatingIpNodes.get("status").asText().isEmpty()) {
255 + throw new IllegalArgumentException("status should not be empty");
256 + }
257 + Status status = Status.valueOf(floatingIpNodes.get("status").asText());
258 +
259 + DefaultFloatingIp floatingIpObj = new DefaultFloatingIp(id, tenantId,
260 + networkId,
261 + portId,
262 + routerId,
263 + floatingIp,
264 + fixedIp, status);
265 + subMap.put(id, floatingIpObj);
266 + return Collections.unmodifiableCollection(subMap.values());
267 + }
268 +
269 + /**
270 + * Returns the specified item if that items is null; otherwise throws not
271 + * found exception.
272 + *
273 + * @param item item to check
274 + * @param <T> item type
275 + * @param message not found message
276 + * @return item if not null
277 + * @throws org.onlab.util.ItemNotFoundException if item is null
278 + */
279 + protected <T> T nullIsNotFound(T item, String message) {
280 + if (item == null) {
281 + throw new ItemNotFoundException(message);
282 + }
283 + return item;
284 + }
285 +}
1 +/*
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 + */
16 +package org.onosproject.vtnweb.web;
17 +
18 +import static com.google.common.base.Preconditions.checkNotNull;
19 +
20 +import java.util.Iterator;
21 +import java.util.List;
22 +
23 +import org.onosproject.codec.CodecContext;
24 +import org.onosproject.codec.JsonCodec;
25 +import org.onosproject.vtnrsc.FloatingIp;
26 +
27 +import com.fasterxml.jackson.databind.node.ObjectNode;
28 +
29 +/**
30 + * FloatingIp JSON codec.
31 + */
32 +public final class FloatingIpCodec extends JsonCodec<FloatingIp> {
33 + @Override
34 + public ObjectNode encode(FloatingIp floatingIp, CodecContext context) {
35 + checkNotNull(floatingIp, "floatingIp cannot be null");
36 + ObjectNode result = context
37 + .mapper()
38 + .createObjectNode()
39 + .put("id", floatingIp.id().floatingIpId().toString())
40 + .put("floating_network_id", floatingIp.networkId().toString())
41 + .put("router_id",
42 + floatingIp.routerId() == null ? null : floatingIp
43 + .routerId().routerId())
44 + .put("tenant_id", floatingIp.tenantId().toString())
45 + .put("port_id",
46 + floatingIp.portId() == null ? null : floatingIp.portId()
47 + .toString())
48 + .put("fixed_ip_address",
49 + floatingIp.fixedIp() == null ? null : floatingIp.fixedIp()
50 + .toString())
51 + .put("floating_ip_address", floatingIp.floatingIp().toString())
52 + .put("status", floatingIp.status().toString());
53 + return result;
54 + }
55 +
56 + public ObjectNode extracFields(FloatingIp floatingIp, CodecContext context,
57 + List<String> fields) {
58 + checkNotNull(floatingIp, "floatingIp cannot be null");
59 + ObjectNode result = context.mapper().createObjectNode();
60 + Iterator<String> i = fields.iterator();
61 + while (i.hasNext()) {
62 + String s = i.next();
63 + if (s.equals("floating_network_id")) {
64 + result.put("floating_network_id", floatingIp.networkId()
65 + .toString());
66 + }
67 + if (s.equals("router_id")) {
68 + result.put("router_id",
69 + floatingIp.routerId() == null ? null : floatingIp
70 + .routerId().routerId());
71 + }
72 + if (s.equals("tenant_id")) {
73 + result.put("tenant_id", floatingIp.tenantId().toString());
74 + }
75 + if (s.equals("port_id")) {
76 + result.put("port_id",
77 + floatingIp.portId() == null ? null : floatingIp
78 + .portId().toString());
79 + }
80 + if (s.equals("id")) {
81 + result.put("id", floatingIp.id().floatingIpId().toString());
82 + }
83 + if (s.equals("fixed_ip_address")) {
84 + result.put("fixed_ip_address",
85 + floatingIp.fixedIp() == null ? null : floatingIp
86 + .fixedIp().toString());
87 + }
88 + if (s.equals("floating_ip_address")) {
89 + result.put("floating_ip_address", floatingIp.floatingIp()
90 + .toString());
91 + }
92 + if (s.equals("status")) {
93 + result.put("status", floatingIp.status().toString());
94 + }
95 + }
96 + return result;
97 + }
98 +}
...@@ -37,6 +37,8 @@ ...@@ -37,6 +37,8 @@
37 org.onosproject.vtnweb.resources.PortChainWebResource 37 org.onosproject.vtnweb.resources.PortChainWebResource
38 org.onosproject.vtnweb.resources.PortPairGroupWebResource 38 org.onosproject.vtnweb.resources.PortPairGroupWebResource
39 org.onosproject.vtnweb.resources.PortPairWebResource 39 org.onosproject.vtnweb.resources.PortPairWebResource
40 + org.onosproject.vtnweb.resources.FloatingIpWebResource
41 + org.onosproject.vtnweb.resources.RouterWebResource
40 </param-value> 42 </param-value>
41 </init-param> 43 </init-param>
42 <load-on-startup>1</load-on-startup> 44 <load-on-startup>1</load-on-startup>
......