blob: cce51348296005147bacd59e78ead6e9d4217075 [file] [log] [blame]
sanghof8164112017-07-14 14:33:16 +09001/*
2 * Copyright 2017-present 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 */
16package org.onosproject.openstacknode.web;
17
18import com.fasterxml.jackson.databind.JsonNode;
19import com.fasterxml.jackson.databind.node.ArrayNode;
20import com.google.common.collect.Sets;
21import org.onlab.osgi.DefaultServiceDirectory;
22import org.onlab.packet.IpAddress;
23import org.onosproject.net.DeviceId;
24import org.onosproject.openstacknode.api.NodeState;
25import org.onosproject.openstacknode.api.OpenstackNode;
26import org.onosproject.openstacknode.api.OpenstackNodeAdminService;
27import org.onosproject.openstacknode.api.OpenstackNodeService;
28import org.onosproject.openstacknode.impl.DefaultOpenstackNode;
29import org.onosproject.rest.AbstractWebResource;
30import org.slf4j.Logger;
31import org.slf4j.LoggerFactory;
32
33import javax.ws.rs.Consumes;
34import javax.ws.rs.DELETE;
35import javax.ws.rs.POST;
36import javax.ws.rs.PUT;
37import javax.ws.rs.Path;
38import javax.ws.rs.Produces;
39import javax.ws.rs.core.Context;
40import javax.ws.rs.core.MediaType;
41import javax.ws.rs.core.Response;
42import javax.ws.rs.core.UriBuilder;
43import javax.ws.rs.core.UriInfo;
44import java.io.InputStream;
45import java.util.Set;
46
47import static com.fasterxml.jackson.databind.SerializationFeature.INDENT_OUTPUT;
48import static javax.ws.rs.core.Response.created;
49
50@Path("configure")
51public class OpenstackNodeWebResource extends AbstractWebResource {
52 private final Logger log = LoggerFactory.getLogger(getClass());
53
54 private static final String MESSAGE_NODE = "Received node %s request";
55 private static final String NODES = "nodes";
56
57 private final OpenstackNodeAdminService osNodeAdminService =
58 DefaultServiceDirectory.getService(OpenstackNodeAdminService.class);
59 private final OpenstackNodeService osNodeService =
60 DefaultServiceDirectory.getService(OpenstackNodeService.class);
61
62 @Context
63 private UriInfo uriInfo;
64
65 @POST
66 @Consumes(MediaType.APPLICATION_JSON)
67 @Produces(MediaType.APPLICATION_JSON)
68 public Response createNodes(InputStream input) {
69 log.trace(String.format(MESSAGE_NODE, "CREATE"));
70
71 readNodeConfiguration(input).forEach(osNode -> {
72 OpenstackNode existing = osNodeService.node(osNode.hostname());
73 if (existing == null) {
74 osNodeAdminService.createNode(osNode);
75 }
76 });
77
78 UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
79 .path(NODES)
80 .path("NODE_ID");
81
82 return created(locationBuilder.build()).build();
83 }
84
85 @PUT
86 @Consumes(MediaType.APPLICATION_JSON)
87 @Produces(MediaType.APPLICATION_JSON)
88 public Response updateNodes(InputStream input) {
89 log.trace(String.format(MESSAGE_NODE, "UPDATE"));
90
91 Set<OpenstackNode> nodes = readNodeConfiguration(input);
92 for (OpenstackNode osNode: nodes) {
93 OpenstackNode existing = osNodeService.node(osNode.hostname());
94 if (existing == null) {
95 log.warn("There is no node configuration to update : {}", osNode.hostname());
96 return Response.notModified().build();
97 } else if (!existing.equals(osNode)) {
98 osNodeAdminService.updateNode(osNode);
99 }
100 }
101
102 return Response.ok().build();
103 }
104
105 @DELETE
106 @Consumes(MediaType.APPLICATION_JSON)
107 @Produces(MediaType.APPLICATION_JSON)
108 public Response deleteNodes(InputStream input) {
109 log.trace(String.format(MESSAGE_NODE, "DELETE"));
110
111 Set<OpenstackNode> nodes = readNodeConfiguration(input);
112 for (OpenstackNode osNode: nodes) {
113 OpenstackNode existing = osNodeService.node(osNode.hostname());
114 if (existing == null) {
115 log.warn("There is no node configuration to delete : {}", osNode.hostname());
116 return Response.notModified().build();
117 } else {
118 osNodeAdminService.removeNode(osNode.hostname());
119 }
120 }
121
122 return Response.ok().build();
123 }
124
125 private Set<OpenstackNode> readNodeConfiguration(InputStream input) {
126 Set<OpenstackNode> nodeSet = Sets.newHashSet();
127 try {
128 JsonNode jsonTree = mapper().enable(INDENT_OUTPUT).readTree(input);
129 ArrayNode nodes = (ArrayNode) jsonTree.path("nodes");
130 nodes.forEach(node -> {
131 try {
132 String hostname = node.get("hostname").asText();
133 String type = node.get("type").asText();
134 String mIp = node.get("managementIp").asText();
135 String dIp = node.get("dataIp").asText();
136 String iBridge = node.get("integrationBridge").asText();
137 String rBridge = null;
138 if (node.get("routerBridge") != null) {
139 rBridge = node.get("routerBridge").asText();
140 }
141 DefaultOpenstackNode.Builder nodeBuilder = DefaultOpenstackNode.builder()
142 .hostname(hostname)
143 .type(OpenstackNode.NodeType.valueOf(type))
144 .managementIp(IpAddress.valueOf(mIp))
145 .dataIp(IpAddress.valueOf(dIp))
146 .intgBridge(DeviceId.deviceId(iBridge))
147 .state(NodeState.INIT);
148 if (rBridge != null) {
149 nodeBuilder.routerBridge(DeviceId.deviceId(rBridge));
150 }
151 log.trace("node is {}", nodeBuilder.build().toString());
152 nodeSet.add(nodeBuilder.build());
153 } catch (Exception e) {
154 log.error(e.toString());
155 throw new IllegalArgumentException();
156 }
157 });
158 } catch (Exception e) {
159 throw new IllegalArgumentException(e);
160 }
161
162 return nodeSet;
163 }
164}