blob: 9e474fd36bfe396f540dab72a5fe48365e53cdb8 [file] [log] [blame]
Thomas Vachuska96d55b12015-05-11 08:52:03 -07001/*
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 */
16package org.onosproject.rest.resources;
17
Ray Milkey36992c82015-11-17 13:31:15 -080018import java.io.IOException;
19import java.io.InputStream;
20import java.util.Set;
Thomas Vachuska96d55b12015-05-11 08:52:03 -070021
22import javax.ws.rs.Consumes;
23import javax.ws.rs.DELETE;
24import javax.ws.rs.GET;
25import javax.ws.rs.POST;
26import javax.ws.rs.Path;
27import javax.ws.rs.PathParam;
28import javax.ws.rs.Produces;
29import javax.ws.rs.core.MediaType;
30import javax.ws.rs.core.Response;
Ray Milkey36992c82015-11-17 13:31:15 -080031
32import org.onosproject.net.config.Config;
33import org.onosproject.net.config.NetworkConfigService;
34import org.onosproject.net.config.SubjectFactory;
35import org.onosproject.rest.AbstractWebResource;
36
37import com.fasterxml.jackson.databind.node.ObjectNode;
38
39import static org.onlab.util.Tools.emptyIsNotFound;
40import static org.onlab.util.Tools.nullIsNotFound;
Thomas Vachuska96d55b12015-05-11 08:52:03 -070041
42/**
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -070043 * Manage network configurations.
Thomas Vachuska96d55b12015-05-11 08:52:03 -070044 */
45@Path("network/configuration")
46public class NetworkConfigWebResource extends AbstractWebResource {
47
Ray Milkey36992c82015-11-17 13:31:15 -080048
49 private String subjectClassNotFoundErrorString(String subjectClassKey) {
50 return "Config for '" + subjectClassKey + "' not found";
51 }
52
53 private String subjectNotFoundErrorString(String subjectClassKey,
54 String subjectKey) {
55 return "Config for '"
56 + subjectClassKey + "/" + subjectKey
57 + "' not found";
58 }
59
60 private String configKeyNotFoundErrorString(String subjectClassKey,
61 String subjectKey,
62 String configKey) {
63 return "Config for '"
64 + subjectClassKey + "/" + subjectKey + "/" + configKey
65 + "' not found";
66 }
67
Thomas Vachuska96d55b12015-05-11 08:52:03 -070068 /**
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -070069 * Get entire network configuration base.
Ray Milkey36992c82015-11-17 13:31:15 -080070 *
Thomas Vachuska96d55b12015-05-11 08:52:03 -070071 * @return network configuration JSON
72 */
73 @GET
74 @Produces(MediaType.APPLICATION_JSON)
75 @SuppressWarnings("unchecked")
76 public Response download() {
77 NetworkConfigService service = get(NetworkConfigService.class);
78 ObjectNode root = mapper().createObjectNode();
Thomas Vachuskaea5adc62015-10-07 11:52:30 -070079 service.getSubjectClasses().forEach(sc -> {
80 SubjectFactory subjectFactory = service.getSubjectFactory(sc);
81 produceJson(service, newObject(root, subjectFactory.subjectClassKey()),
82 subjectFactory, sc);
83 });
Thomas Vachuska96d55b12015-05-11 08:52:03 -070084 return ok(root).build();
85 }
86
87 /**
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -070088 * Get all network configuration for a subject class.
Thomas Vachuska96d55b12015-05-11 08:52:03 -070089 *
Thomas Vachuskaea5adc62015-10-07 11:52:30 -070090 * @param subjectClassKey subject class key
Thomas Vachuska96d55b12015-05-11 08:52:03 -070091 * @return network configuration JSON
92 */
93 @GET
Thomas Vachuskaea5adc62015-10-07 11:52:30 -070094 @Path("{subjectClassKey}")
Thomas Vachuska96d55b12015-05-11 08:52:03 -070095 @Produces(MediaType.APPLICATION_JSON)
96 @SuppressWarnings("unchecked")
Thomas Vachuskaea5adc62015-10-07 11:52:30 -070097 public Response download(@PathParam("subjectClassKey") String subjectClassKey) {
Thomas Vachuska96d55b12015-05-11 08:52:03 -070098 NetworkConfigService service = get(NetworkConfigService.class);
99 ObjectNode root = mapper().createObjectNode();
Ray Milkey36992c82015-11-17 13:31:15 -0800100 SubjectFactory subjectFactory =
101 nullIsNotFound(service.getSubjectFactory(subjectClassKey),
102 subjectClassNotFoundErrorString(subjectClassKey));
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700103 produceJson(service, root, subjectFactory, subjectFactory.subjectClass());
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700104 return ok(root).build();
105 }
106
107 /**
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700108 * Get all network configuration for a subjectKey.
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700109 *
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700110 * @param subjectClassKey subjectKey class key
111 * @param subjectKey subjectKey key
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700112 * @return network configuration JSON
113 */
114 @GET
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700115 @Path("{subjectClassKey}/{subjectKey}")
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700116 @Produces(MediaType.APPLICATION_JSON)
117 @SuppressWarnings("unchecked")
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700118 public Response download(@PathParam("subjectClassKey") String subjectClassKey,
119 @PathParam("subjectKey") String subjectKey) {
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700120 NetworkConfigService service = get(NetworkConfigService.class);
121 ObjectNode root = mapper().createObjectNode();
Ray Milkey36992c82015-11-17 13:31:15 -0800122 SubjectFactory subjectFactory =
123 nullIsNotFound(service.getSubjectFactory(subjectClassKey),
124 subjectClassNotFoundErrorString(subjectClassKey));
125 produceSubjectJson(service, root, subjectFactory.createSubject(subjectKey),
126 true,
127 subjectNotFoundErrorString(subjectClassKey, subjectKey));
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700128 return ok(root).build();
129 }
130
131 /**
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700132 * Get specific network configuration for a subjectKey.
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700133 *
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700134 * @param subjectClassKey subjectKey class key
135 * @param subjectKey subjectKey key
136 * @param configKey configuration class key
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700137 * @return network configuration JSON
138 */
139 @GET
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700140 @Path("{subjectClassKey}/{subjectKey}/{configKey}")
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700141 @Produces(MediaType.APPLICATION_JSON)
142 @SuppressWarnings("unchecked")
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700143 public Response download(@PathParam("subjectClassKey") String subjectClassKey,
144 @PathParam("subjectKey") String subjectKey,
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700145 @PathParam("configKey") String configKey) {
146 NetworkConfigService service = get(NetworkConfigService.class);
Ray Milkey36992c82015-11-17 13:31:15 -0800147
148 Object subject =
149 nullIsNotFound(service.getSubjectFactory(subjectClassKey)
150 .createSubject(subjectKey),
151 subjectNotFoundErrorString(subjectClassKey, subjectKey));
152
153 Class configClass =
154 nullIsNotFound(service.getConfigClass(subjectClassKey, configKey),
155 configKeyNotFoundErrorString(subjectClassKey, subjectKey, configKey));
156 Config config =
157 nullIsNotFound(service.getConfig(subject, configClass),
158 configKeyNotFoundErrorString(subjectClassKey,
159 subjectKey,
160 configKey));
161 return ok(config.node()).build();
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700162 }
163
164 @SuppressWarnings("unchecked")
165 private void produceJson(NetworkConfigService service, ObjectNode node,
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700166 SubjectFactory subjectFactory, Class subjectClass) {
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700167 service.getSubjects(subjectClass).forEach(s ->
Ray Milkey36992c82015-11-17 13:31:15 -0800168 produceSubjectJson(service, newObject(node, subjectFactory.subjectKey(s)), s, false, ""));
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700169 }
170
171 private void produceSubjectJson(NetworkConfigService service, ObjectNode node,
Ray Milkey36992c82015-11-17 13:31:15 -0800172 Object subject,
173 boolean emptyIsError,
174 String emptyErrorMessage) {
175 Set<? extends Config<Object>> configs = service.getConfigs(subject);
176 if (emptyIsError) {
177 // caller wants an empty set to be a 404
178 configs = emptyIsNotFound(configs, emptyErrorMessage);
179 }
180 configs.forEach(c -> node.set(c.key(), c.node()));
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700181 }
182
183
184 /**
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700185 * Upload bulk network configuration.
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700186 *
187 * @param request network configuration JSON rooted at the top node
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700188 * @return empty response
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700189 * @throws IOException if unable to parse the request
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700190 */
191 @POST
192 @Consumes(MediaType.APPLICATION_JSON)
193 @SuppressWarnings("unchecked")
194 public Response upload(InputStream request) throws IOException {
195 NetworkConfigService service = get(NetworkConfigService.class);
196 ObjectNode root = (ObjectNode) mapper().readTree(request);
197 root.fieldNames()
198 .forEachRemaining(sk -> consumeJson(service, (ObjectNode) root.path(sk),
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700199 service.getSubjectFactory(sk)));
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700200 return Response.ok().build();
201 }
202
203 /**
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700204 * Upload multiple network configurations for a subject class.
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700205 *
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700206 * @param subjectClassKey subject class key
207 * @param request network configuration JSON rooted at the top node
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700208 * @return empty response
Thomas Vachuskad894b5d2015-07-30 11:59:07 -0700209 * @throws IOException if unable to parse the request
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700210 */
211 @POST
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700212 @Path("{subjectClassKey}")
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700213 @Consumes(MediaType.APPLICATION_JSON)
214 @SuppressWarnings("unchecked")
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700215 public Response upload(@PathParam("subjectClassKey") String subjectClassKey,
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700216 InputStream request) throws IOException {
217 NetworkConfigService service = get(NetworkConfigService.class);
218 ObjectNode root = (ObjectNode) mapper().readTree(request);
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700219 consumeJson(service, root, service.getSubjectFactory(subjectClassKey));
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700220 return Response.ok().build();
221 }
222
223 /**
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700224 * Upload mutliple network configurations for a subjectKey.
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700225 *
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700226 * @param subjectClassKey subjectKey class key
227 * @param subjectKey subjectKey key
228 * @param request network configuration JSON rooted at the top node
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700229 * @return empty response
Thomas Vachuskad894b5d2015-07-30 11:59:07 -0700230 * @throws IOException if unable to parse the request
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700231 */
232 @POST
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700233 @Path("{subjectClassKey}/{subjectKey}")
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700234 @Consumes(MediaType.APPLICATION_JSON)
235 @SuppressWarnings("unchecked")
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700236 public Response upload(@PathParam("subjectClassKey") String subjectClassKey,
237 @PathParam("subjectKey") String subjectKey,
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700238 InputStream request) throws IOException {
239 NetworkConfigService service = get(NetworkConfigService.class);
240 ObjectNode root = (ObjectNode) mapper().readTree(request);
241 consumeSubjectJson(service, root,
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700242 service.getSubjectFactory(subjectClassKey).createSubject(subjectKey),
243 subjectClassKey);
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700244 return Response.ok().build();
245 }
246
247 /**
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700248 * Upload specific network configuration for a subjectKey.
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700249 *
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700250 * @param subjectClassKey subjectKey class key
251 * @param subjectKey subjectKey key
252 * @param configKey configuration class key
253 * @param request network configuration JSON rooted at the top node
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700254 * @return empty response
Thomas Vachuskad894b5d2015-07-30 11:59:07 -0700255 * @throws IOException if unable to parse the request
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700256 */
257 @POST
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700258 @Path("{subjectClassKey}/{subjectKey}/{configKey}")
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700259 @Consumes(MediaType.APPLICATION_JSON)
260 @SuppressWarnings("unchecked")
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700261 public Response upload(@PathParam("subjectClassKey") String subjectClassKey,
262 @PathParam("subjectKey") String subjectKey,
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700263 @PathParam("configKey") String configKey,
264 InputStream request) throws IOException {
265 NetworkConfigService service = get(NetworkConfigService.class);
266 ObjectNode root = (ObjectNode) mapper().readTree(request);
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700267 service.applyConfig(service.getSubjectFactory(subjectClassKey).createSubject(subjectKey),
268 service.getConfigClass(subjectClassKey, configKey), root);
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700269 return Response.ok().build();
270 }
271
272 private void consumeJson(NetworkConfigService service, ObjectNode classNode,
273 SubjectFactory subjectFactory) {
274 classNode.fieldNames().forEachRemaining(s ->
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700275 consumeSubjectJson(service, (ObjectNode) classNode.path(s),
276 subjectFactory.createSubject(s),
277 subjectFactory.subjectClassKey()));
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700278 }
279
280 private void consumeSubjectJson(NetworkConfigService service,
Jonathan Hart111b42b2015-07-14 13:28:05 -0700281 ObjectNode subjectNode, Object subject,
282 String subjectKey) {
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700283 subjectNode.fieldNames().forEachRemaining(c ->
Jonathan Hart111b42b2015-07-14 13:28:05 -0700284 service.applyConfig(subject, service.getConfigClass(subjectKey, c),
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700285 subjectNode.path(c)));
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700286 }
287
288
289 /**
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700290 * Clear entire network configuration base.
291 *
292 * @return empty response
293 */
294 @DELETE
295 @SuppressWarnings("unchecked")
296 public Response delete() {
297 NetworkConfigService service = get(NetworkConfigService.class);
298 service.getSubjectClasses()
299 .forEach(subjectClass -> service.getSubjects(subjectClass)
300 .forEach(subject -> service.getConfigs(subject)
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700301 .forEach(config -> service.removeConfig(subject, config.getClass()))));
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700302 return Response.ok().build();
303 }
304
305 /**
306 * Clear all network configurations for a subject class.
307 *
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700308 * @param subjectClassKey subject class key
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700309 */
310 @DELETE
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700311 @Path("{subjectClassKey}")
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700312 @SuppressWarnings("unchecked")
Ray Milkeyb9fe25d2015-11-18 15:54:44 -0800313 public void delete(@PathParam("subjectClassKey") String subjectClassKey) {
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700314 NetworkConfigService service = get(NetworkConfigService.class);
Ray Milkeyb9fe25d2015-11-18 15:54:44 -0800315 service.getSubjects(service.getSubjectFactory(subjectClassKey).subjectClass())
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700316 .forEach(subject -> service.getConfigs(subject)
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700317 .forEach(config -> service.removeConfig(subject, config.getClass())));
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700318 }
319
320 /**
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700321 * Clear all network configurations for a subjectKey.
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700322 *
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700323 * @param subjectClassKey subjectKey class key
324 * @param subjectKey subjectKey key
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700325 */
326 @DELETE
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700327 @Path("{subjectClassKey}/{subjectKey}")
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700328 @SuppressWarnings("unchecked")
Ray Milkeyb9fe25d2015-11-18 15:54:44 -0800329 public void delete(@PathParam("subjectClassKey") String subjectClassKey,
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700330 @PathParam("subjectKey") String subjectKey) {
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700331 NetworkConfigService service = get(NetworkConfigService.class);
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700332 Object s = service.getSubjectFactory(subjectClassKey).createSubject(subjectKey);
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700333 service.getConfigs(s).forEach(c -> service.removeConfig(s, c.getClass()));
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700334 }
335
336 /**
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700337 * Clear specific network configuration for a subjectKey.
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700338 *
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700339 * @param subjectClassKey subjectKey class key
340 * @param subjectKey subjectKey key
341 * @param configKey configuration class key
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700342 */
343 @DELETE
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700344 @Path("{subjectClassKey}/{subjectKey}/{configKey}")
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700345 @SuppressWarnings("unchecked")
Ray Milkeyb9fe25d2015-11-18 15:54:44 -0800346 public void delete(@PathParam("subjectClassKey") String subjectClassKey,
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700347 @PathParam("subjectKey") String subjectKey,
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700348 @PathParam("configKey") String configKey) {
349 NetworkConfigService service = get(NetworkConfigService.class);
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700350 service.removeConfig(service.getSubjectFactory(subjectClassKey).createSubject(subjectKey),
351 service.getConfigClass(subjectClassKey, configKey));
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700352 }
353
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700354}