blob: 69c0b6a3a659b69acae18088fc7983106ca89422 [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 *
andrea5056b512015-11-18 10:25:28 -080071 * @rsModel NetCfgGet
Thomas Vachuska96d55b12015-05-11 08:52:03 -070072 * @return network configuration JSON
73 */
74 @GET
75 @Produces(MediaType.APPLICATION_JSON)
76 @SuppressWarnings("unchecked")
77 public Response download() {
78 NetworkConfigService service = get(NetworkConfigService.class);
79 ObjectNode root = mapper().createObjectNode();
Thomas Vachuskaea5adc62015-10-07 11:52:30 -070080 service.getSubjectClasses().forEach(sc -> {
81 SubjectFactory subjectFactory = service.getSubjectFactory(sc);
82 produceJson(service, newObject(root, subjectFactory.subjectClassKey()),
83 subjectFactory, sc);
84 });
Thomas Vachuska96d55b12015-05-11 08:52:03 -070085 return ok(root).build();
86 }
87
88 /**
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -070089 * Get all network configuration for a subject class.
Thomas Vachuska96d55b12015-05-11 08:52:03 -070090 *
Thomas Vachuskaea5adc62015-10-07 11:52:30 -070091 * @param subjectClassKey subject class key
Thomas Vachuska96d55b12015-05-11 08:52:03 -070092 * @return network configuration JSON
93 */
94 @GET
Thomas Vachuskaea5adc62015-10-07 11:52:30 -070095 @Path("{subjectClassKey}")
Thomas Vachuska96d55b12015-05-11 08:52:03 -070096 @Produces(MediaType.APPLICATION_JSON)
97 @SuppressWarnings("unchecked")
Thomas Vachuskaea5adc62015-10-07 11:52:30 -070098 public Response download(@PathParam("subjectClassKey") String subjectClassKey) {
Thomas Vachuska96d55b12015-05-11 08:52:03 -070099 NetworkConfigService service = get(NetworkConfigService.class);
100 ObjectNode root = mapper().createObjectNode();
Ray Milkey36992c82015-11-17 13:31:15 -0800101 SubjectFactory subjectFactory =
102 nullIsNotFound(service.getSubjectFactory(subjectClassKey),
103 subjectClassNotFoundErrorString(subjectClassKey));
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700104 produceJson(service, root, subjectFactory, subjectFactory.subjectClass());
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700105 return ok(root).build();
106 }
107
108 /**
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700109 * Get all network configuration for a subjectKey.
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700110 *
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700111 * @param subjectClassKey subjectKey class key
112 * @param subjectKey subjectKey key
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700113 * @return network configuration JSON
114 */
115 @GET
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700116 @Path("{subjectClassKey}/{subjectKey}")
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700117 @Produces(MediaType.APPLICATION_JSON)
118 @SuppressWarnings("unchecked")
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700119 public Response download(@PathParam("subjectClassKey") String subjectClassKey,
120 @PathParam("subjectKey") String subjectKey) {
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700121 NetworkConfigService service = get(NetworkConfigService.class);
122 ObjectNode root = mapper().createObjectNode();
Ray Milkey36992c82015-11-17 13:31:15 -0800123 SubjectFactory subjectFactory =
124 nullIsNotFound(service.getSubjectFactory(subjectClassKey),
125 subjectClassNotFoundErrorString(subjectClassKey));
126 produceSubjectJson(service, root, subjectFactory.createSubject(subjectKey),
127 true,
128 subjectNotFoundErrorString(subjectClassKey, subjectKey));
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700129 return ok(root).build();
130 }
131
132 /**
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700133 * Get specific network configuration for a subjectKey.
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700134 *
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700135 * @param subjectClassKey subjectKey class key
136 * @param subjectKey subjectKey key
137 * @param configKey configuration class key
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700138 * @return network configuration JSON
139 */
140 @GET
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700141 @Path("{subjectClassKey}/{subjectKey}/{configKey}")
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700142 @Produces(MediaType.APPLICATION_JSON)
143 @SuppressWarnings("unchecked")
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700144 public Response download(@PathParam("subjectClassKey") String subjectClassKey,
145 @PathParam("subjectKey") String subjectKey,
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700146 @PathParam("configKey") String configKey) {
147 NetworkConfigService service = get(NetworkConfigService.class);
Ray Milkey36992c82015-11-17 13:31:15 -0800148
149 Object subject =
150 nullIsNotFound(service.getSubjectFactory(subjectClassKey)
151 .createSubject(subjectKey),
152 subjectNotFoundErrorString(subjectClassKey, subjectKey));
153
154 Class configClass =
155 nullIsNotFound(service.getConfigClass(subjectClassKey, configKey),
156 configKeyNotFoundErrorString(subjectClassKey, subjectKey, configKey));
157 Config config =
158 nullIsNotFound(service.getConfig(subject, configClass),
159 configKeyNotFoundErrorString(subjectClassKey,
160 subjectKey,
161 configKey));
162 return ok(config.node()).build();
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700163 }
164
165 @SuppressWarnings("unchecked")
166 private void produceJson(NetworkConfigService service, ObjectNode node,
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700167 SubjectFactory subjectFactory, Class subjectClass) {
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700168 service.getSubjects(subjectClass).forEach(s ->
Ray Milkey36992c82015-11-17 13:31:15 -0800169 produceSubjectJson(service, newObject(node, subjectFactory.subjectKey(s)), s, false, ""));
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700170 }
171
172 private void produceSubjectJson(NetworkConfigService service, ObjectNode node,
Ray Milkey36992c82015-11-17 13:31:15 -0800173 Object subject,
174 boolean emptyIsError,
175 String emptyErrorMessage) {
176 Set<? extends Config<Object>> configs = service.getConfigs(subject);
177 if (emptyIsError) {
178 // caller wants an empty set to be a 404
179 configs = emptyIsNotFound(configs, emptyErrorMessage);
180 }
181 configs.forEach(c -> node.set(c.key(), c.node()));
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700182 }
183
184
185 /**
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700186 * Upload bulk network configuration.
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700187 *
andrea5056b512015-11-18 10:25:28 -0800188 * @rsModel NetCfgGet
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700189 * @param request network configuration JSON rooted at the top node
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700190 * @return empty response
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700191 * @throws IOException if unable to parse the request
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700192 */
193 @POST
194 @Consumes(MediaType.APPLICATION_JSON)
195 @SuppressWarnings("unchecked")
196 public Response upload(InputStream request) throws IOException {
197 NetworkConfigService service = get(NetworkConfigService.class);
198 ObjectNode root = (ObjectNode) mapper().readTree(request);
199 root.fieldNames()
200 .forEachRemaining(sk -> consumeJson(service, (ObjectNode) root.path(sk),
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700201 service.getSubjectFactory(sk)));
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700202 return Response.ok().build();
203 }
204
205 /**
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700206 * Upload multiple network configurations for a subject class.
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700207 *
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700208 * @param subjectClassKey subject class key
209 * @param request network configuration JSON rooted at the top node
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700210 * @return empty response
Thomas Vachuskad894b5d2015-07-30 11:59:07 -0700211 * @throws IOException if unable to parse the request
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700212 */
213 @POST
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700214 @Path("{subjectClassKey}")
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700215 @Consumes(MediaType.APPLICATION_JSON)
216 @SuppressWarnings("unchecked")
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700217 public Response upload(@PathParam("subjectClassKey") String subjectClassKey,
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700218 InputStream request) throws IOException {
219 NetworkConfigService service = get(NetworkConfigService.class);
220 ObjectNode root = (ObjectNode) mapper().readTree(request);
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700221 consumeJson(service, root, service.getSubjectFactory(subjectClassKey));
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700222 return Response.ok().build();
223 }
224
225 /**
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700226 * Upload mutliple network configurations for a subjectKey.
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700227 *
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700228 * @param subjectClassKey subjectKey class key
229 * @param subjectKey subjectKey key
230 * @param request network configuration JSON rooted at the top node
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700231 * @return empty response
Thomas Vachuskad894b5d2015-07-30 11:59:07 -0700232 * @throws IOException if unable to parse the request
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700233 */
234 @POST
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700235 @Path("{subjectClassKey}/{subjectKey}")
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700236 @Consumes(MediaType.APPLICATION_JSON)
237 @SuppressWarnings("unchecked")
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700238 public Response upload(@PathParam("subjectClassKey") String subjectClassKey,
239 @PathParam("subjectKey") String subjectKey,
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700240 InputStream request) throws IOException {
241 NetworkConfigService service = get(NetworkConfigService.class);
242 ObjectNode root = (ObjectNode) mapper().readTree(request);
243 consumeSubjectJson(service, root,
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700244 service.getSubjectFactory(subjectClassKey).createSubject(subjectKey),
245 subjectClassKey);
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700246 return Response.ok().build();
247 }
248
249 /**
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700250 * Upload specific network configuration for a subjectKey.
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700251 *
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700252 * @param subjectClassKey subjectKey class key
253 * @param subjectKey subjectKey key
254 * @param configKey configuration class key
255 * @param request network configuration JSON rooted at the top node
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700256 * @return empty response
Thomas Vachuskad894b5d2015-07-30 11:59:07 -0700257 * @throws IOException if unable to parse the request
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700258 */
259 @POST
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700260 @Path("{subjectClassKey}/{subjectKey}/{configKey}")
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700261 @Consumes(MediaType.APPLICATION_JSON)
262 @SuppressWarnings("unchecked")
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700263 public Response upload(@PathParam("subjectClassKey") String subjectClassKey,
264 @PathParam("subjectKey") String subjectKey,
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700265 @PathParam("configKey") String configKey,
266 InputStream request) throws IOException {
267 NetworkConfigService service = get(NetworkConfigService.class);
268 ObjectNode root = (ObjectNode) mapper().readTree(request);
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700269 service.applyConfig(service.getSubjectFactory(subjectClassKey).createSubject(subjectKey),
270 service.getConfigClass(subjectClassKey, configKey), root);
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700271 return Response.ok().build();
272 }
273
274 private void consumeJson(NetworkConfigService service, ObjectNode classNode,
275 SubjectFactory subjectFactory) {
276 classNode.fieldNames().forEachRemaining(s ->
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700277 consumeSubjectJson(service, (ObjectNode) classNode.path(s),
278 subjectFactory.createSubject(s),
279 subjectFactory.subjectClassKey()));
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700280 }
281
282 private void consumeSubjectJson(NetworkConfigService service,
Jonathan Hart111b42b2015-07-14 13:28:05 -0700283 ObjectNode subjectNode, Object subject,
284 String subjectKey) {
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700285 subjectNode.fieldNames().forEachRemaining(c ->
Jonathan Hart111b42b2015-07-14 13:28:05 -0700286 service.applyConfig(subject, service.getConfigClass(subjectKey, c),
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700287 subjectNode.path(c)));
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700288 }
289
290
291 /**
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700292 * Clear entire network configuration base.
293 *
294 * @return empty response
295 */
296 @DELETE
297 @SuppressWarnings("unchecked")
298 public Response delete() {
299 NetworkConfigService service = get(NetworkConfigService.class);
300 service.getSubjectClasses()
301 .forEach(subjectClass -> service.getSubjects(subjectClass)
302 .forEach(subject -> service.getConfigs(subject)
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700303 .forEach(config -> service.removeConfig(subject, config.getClass()))));
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700304 return Response.ok().build();
305 }
306
307 /**
308 * Clear all network configurations for a subject class.
309 *
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700310 * @param subjectClassKey subject class key
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700311 */
312 @DELETE
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700313 @Path("{subjectClassKey}")
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700314 @SuppressWarnings("unchecked")
Ray Milkeyb9fe25d2015-11-18 15:54:44 -0800315 public void delete(@PathParam("subjectClassKey") String subjectClassKey) {
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700316 NetworkConfigService service = get(NetworkConfigService.class);
Ray Milkeyb9fe25d2015-11-18 15:54:44 -0800317 service.getSubjects(service.getSubjectFactory(subjectClassKey).subjectClass())
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700318 .forEach(subject -> service.getConfigs(subject)
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700319 .forEach(config -> service.removeConfig(subject, config.getClass())));
Thomas Vachuska0fa2aa12015-08-18 12:53:04 -0700320 }
321
322 /**
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700323 * Clear all network configurations for a subjectKey.
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700324 *
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700325 * @param subjectClassKey subjectKey class key
326 * @param subjectKey subjectKey key
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700327 */
328 @DELETE
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700329 @Path("{subjectClassKey}/{subjectKey}")
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700330 @SuppressWarnings("unchecked")
Ray Milkeyb9fe25d2015-11-18 15:54:44 -0800331 public void delete(@PathParam("subjectClassKey") String subjectClassKey,
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700332 @PathParam("subjectKey") String subjectKey) {
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700333 NetworkConfigService service = get(NetworkConfigService.class);
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700334 Object s = service.getSubjectFactory(subjectClassKey).createSubject(subjectKey);
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700335 service.getConfigs(s).forEach(c -> service.removeConfig(s, c.getClass()));
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700336 }
337
338 /**
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700339 * Clear specific network configuration for a subjectKey.
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700340 *
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700341 * @param subjectClassKey subjectKey class key
342 * @param subjectKey subjectKey key
343 * @param configKey configuration class key
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700344 */
345 @DELETE
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700346 @Path("{subjectClassKey}/{subjectKey}/{configKey}")
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700347 @SuppressWarnings("unchecked")
Ray Milkeyb9fe25d2015-11-18 15:54:44 -0800348 public void delete(@PathParam("subjectClassKey") String subjectClassKey,
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700349 @PathParam("subjectKey") String subjectKey,
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700350 @PathParam("configKey") String configKey) {
351 NetworkConfigService service = get(NetworkConfigService.class);
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700352 service.removeConfig(service.getSubjectFactory(subjectClassKey).createSubject(subjectKey),
353 service.getConfigClass(subjectClassKey, configKey));
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700354 }
355
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700356}