blob: 9d311b276242863097045fb65574d487a601fa5f [file] [log] [blame]
sanghof8164112017-07-14 14:33:16 +09001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
sanghof8164112017-07-14 14:33:16 +09003 *
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";
daniel parkde735852017-08-01 19:13:24 +090056 private static final String CREATE = "CREATE";
57 private static final String UPDATE = "UPDATE";
58 private static final String NODE_ID = "NODE_ID";
59 private static final String DELETE = "DELETE";
60
61 private static final String HOST_NAME = "hostname";
62 private static final String TYPE = "type";
63 private static final String MANAGEMENT_IP = "managementIp";
64 private static final String DATA_IP = "dataIp";
65 private static final String INTEGRATION_BRIDGE = "integrationBridge";
66 private static final String VLAN_INTF_NAME = "vlanPort";
67
68 // GATEWAY node specific fields
69 private static final String ROUTER_BRIDGE = "routerBridge";
70
sanghof8164112017-07-14 14:33:16 +090071
72 private final OpenstackNodeAdminService osNodeAdminService =
73 DefaultServiceDirectory.getService(OpenstackNodeAdminService.class);
74 private final OpenstackNodeService osNodeService =
75 DefaultServiceDirectory.getService(OpenstackNodeService.class);
76
77 @Context
78 private UriInfo uriInfo;
79
80 @POST
81 @Consumes(MediaType.APPLICATION_JSON)
82 @Produces(MediaType.APPLICATION_JSON)
83 public Response createNodes(InputStream input) {
daniel parkde735852017-08-01 19:13:24 +090084 log.trace(String.format(MESSAGE_NODE, CREATE));
sanghof8164112017-07-14 14:33:16 +090085
86 readNodeConfiguration(input).forEach(osNode -> {
87 OpenstackNode existing = osNodeService.node(osNode.hostname());
88 if (existing == null) {
89 osNodeAdminService.createNode(osNode);
90 }
91 });
92
93 UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
94 .path(NODES)
daniel parkde735852017-08-01 19:13:24 +090095 .path(NODE_ID);
sanghof8164112017-07-14 14:33:16 +090096
97 return created(locationBuilder.build()).build();
98 }
99
100 @PUT
101 @Consumes(MediaType.APPLICATION_JSON)
102 @Produces(MediaType.APPLICATION_JSON)
103 public Response updateNodes(InputStream input) {
daniel parkde735852017-08-01 19:13:24 +0900104 log.trace(String.format(MESSAGE_NODE, UPDATE));
sanghof8164112017-07-14 14:33:16 +0900105
106 Set<OpenstackNode> nodes = readNodeConfiguration(input);
107 for (OpenstackNode osNode: nodes) {
108 OpenstackNode existing = osNodeService.node(osNode.hostname());
109 if (existing == null) {
110 log.warn("There is no node configuration to update : {}", osNode.hostname());
111 return Response.notModified().build();
112 } else if (!existing.equals(osNode)) {
113 osNodeAdminService.updateNode(osNode);
114 }
115 }
116
117 return Response.ok().build();
118 }
119
120 @DELETE
121 @Consumes(MediaType.APPLICATION_JSON)
122 @Produces(MediaType.APPLICATION_JSON)
123 public Response deleteNodes(InputStream input) {
daniel parkde735852017-08-01 19:13:24 +0900124 log.trace(String.format(MESSAGE_NODE, DELETE));
sanghof8164112017-07-14 14:33:16 +0900125
126 Set<OpenstackNode> nodes = readNodeConfiguration(input);
127 for (OpenstackNode osNode: nodes) {
128 OpenstackNode existing = osNodeService.node(osNode.hostname());
129 if (existing == null) {
130 log.warn("There is no node configuration to delete : {}", osNode.hostname());
131 return Response.notModified().build();
132 } else {
133 osNodeAdminService.removeNode(osNode.hostname());
134 }
135 }
136
137 return Response.ok().build();
138 }
139
140 private Set<OpenstackNode> readNodeConfiguration(InputStream input) {
141 Set<OpenstackNode> nodeSet = Sets.newHashSet();
142 try {
143 JsonNode jsonTree = mapper().enable(INDENT_OUTPUT).readTree(input);
daniel parkde735852017-08-01 19:13:24 +0900144 ArrayNode nodes = (ArrayNode) jsonTree.path(NODES);
sanghof8164112017-07-14 14:33:16 +0900145 nodes.forEach(node -> {
146 try {
daniel parkde735852017-08-01 19:13:24 +0900147 String hostname = node.get(HOST_NAME).asText();
148 String type = node.get(TYPE).asText();
149 String mIp = node.get(MANAGEMENT_IP).asText();
150 String iBridge = node.get(INTEGRATION_BRIDGE).asText();
sanghof8164112017-07-14 14:33:16 +0900151 String rBridge = null;
daniel parkde735852017-08-01 19:13:24 +0900152 if (node.get(ROUTER_BRIDGE) != null) {
153 rBridge = node.get(ROUTER_BRIDGE).asText();
sanghof8164112017-07-14 14:33:16 +0900154 }
155 DefaultOpenstackNode.Builder nodeBuilder = DefaultOpenstackNode.builder()
156 .hostname(hostname)
157 .type(OpenstackNode.NodeType.valueOf(type))
158 .managementIp(IpAddress.valueOf(mIp))
sanghof8164112017-07-14 14:33:16 +0900159 .intgBridge(DeviceId.deviceId(iBridge))
160 .state(NodeState.INIT);
daniel parkde735852017-08-01 19:13:24 +0900161
162 if (node.get(VLAN_INTF_NAME) != null) {
163 nodeBuilder.vlanIntf(node.get(VLAN_INTF_NAME).asText());
164 }
165 if (node.get(DATA_IP) != null) {
166 nodeBuilder.dataIp(IpAddress.valueOf(node.get(DATA_IP).asText()));
167 }
sanghof8164112017-07-14 14:33:16 +0900168 if (rBridge != null) {
169 nodeBuilder.routerBridge(DeviceId.deviceId(rBridge));
170 }
daniel parkde735852017-08-01 19:13:24 +0900171
sanghof8164112017-07-14 14:33:16 +0900172 log.trace("node is {}", nodeBuilder.build().toString());
173 nodeSet.add(nodeBuilder.build());
174 } catch (Exception e) {
175 log.error(e.toString());
176 throw new IllegalArgumentException();
177 }
178 });
179 } catch (Exception e) {
180 throw new IllegalArgumentException(e);
181 }
182
183 return nodeSet;
184 }
185}