69c0b6a3a659b69acae18088fc7983106ca89422
[onosfw.git] /
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.rest.resources;
17
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.util.Set;
21
22 import javax.ws.rs.Consumes;
23 import javax.ws.rs.DELETE;
24 import javax.ws.rs.GET;
25 import javax.ws.rs.POST;
26 import javax.ws.rs.Path;
27 import javax.ws.rs.PathParam;
28 import javax.ws.rs.Produces;
29 import javax.ws.rs.core.MediaType;
30 import javax.ws.rs.core.Response;
31
32 import org.onosproject.net.config.Config;
33 import org.onosproject.net.config.NetworkConfigService;
34 import org.onosproject.net.config.SubjectFactory;
35 import org.onosproject.rest.AbstractWebResource;
36
37 import com.fasterxml.jackson.databind.node.ObjectNode;
38
39 import static org.onlab.util.Tools.emptyIsNotFound;
40 import static org.onlab.util.Tools.nullIsNotFound;
41
42 /**
43  * Manage network configurations.
44  */
45 @Path("network/configuration")
46 public class NetworkConfigWebResource extends AbstractWebResource {
47
48
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
68     /**
69      * Get entire network configuration base.
70      *
71      * @rsModel NetCfgGet
72      * @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();
80         service.getSubjectClasses().forEach(sc -> {
81             SubjectFactory subjectFactory = service.getSubjectFactory(sc);
82             produceJson(service, newObject(root, subjectFactory.subjectClassKey()),
83                         subjectFactory, sc);
84         });
85         return ok(root).build();
86     }
87
88     /**
89      * Get all network configuration for a subject class.
90      *
91      * @param subjectClassKey subject class key
92      * @return network configuration JSON
93      */
94     @GET
95     @Path("{subjectClassKey}")
96     @Produces(MediaType.APPLICATION_JSON)
97     @SuppressWarnings("unchecked")
98     public Response download(@PathParam("subjectClassKey") String subjectClassKey) {
99         NetworkConfigService service = get(NetworkConfigService.class);
100         ObjectNode root = mapper().createObjectNode();
101         SubjectFactory subjectFactory =
102                 nullIsNotFound(service.getSubjectFactory(subjectClassKey),
103                                subjectClassNotFoundErrorString(subjectClassKey));
104         produceJson(service, root, subjectFactory, subjectFactory.subjectClass());
105         return ok(root).build();
106     }
107
108     /**
109      * Get all network configuration for a subjectKey.
110      *
111      * @param subjectClassKey subjectKey class key
112      * @param subjectKey      subjectKey key
113      * @return network configuration JSON
114      */
115     @GET
116     @Path("{subjectClassKey}/{subjectKey}")
117     @Produces(MediaType.APPLICATION_JSON)
118     @SuppressWarnings("unchecked")
119     public Response download(@PathParam("subjectClassKey") String subjectClassKey,
120                              @PathParam("subjectKey") String subjectKey) {
121         NetworkConfigService service = get(NetworkConfigService.class);
122         ObjectNode root = mapper().createObjectNode();
123         SubjectFactory subjectFactory =
124                 nullIsNotFound(service.getSubjectFactory(subjectClassKey),
125                                subjectClassNotFoundErrorString(subjectClassKey));
126         produceSubjectJson(service, root, subjectFactory.createSubject(subjectKey),
127                            true,
128                            subjectNotFoundErrorString(subjectClassKey, subjectKey));
129         return ok(root).build();
130     }
131
132     /**
133      * Get specific network configuration for a subjectKey.
134      *
135      * @param subjectClassKey subjectKey class key
136      * @param subjectKey      subjectKey key
137      * @param configKey       configuration class key
138      * @return network configuration JSON
139      */
140     @GET
141     @Path("{subjectClassKey}/{subjectKey}/{configKey}")
142     @Produces(MediaType.APPLICATION_JSON)
143     @SuppressWarnings("unchecked")
144     public Response download(@PathParam("subjectClassKey") String subjectClassKey,
145                              @PathParam("subjectKey") String subjectKey,
146                              @PathParam("configKey") String configKey) {
147         NetworkConfigService service = get(NetworkConfigService.class);
148
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();
163     }
164
165     @SuppressWarnings("unchecked")
166     private void produceJson(NetworkConfigService service, ObjectNode node,
167                              SubjectFactory subjectFactory, Class subjectClass) {
168         service.getSubjects(subjectClass).forEach(s ->
169             produceSubjectJson(service, newObject(node, subjectFactory.subjectKey(s)), s, false, ""));
170     }
171
172     private void produceSubjectJson(NetworkConfigService service, ObjectNode node,
173                                     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()));
182     }
183
184
185     /**
186      * Upload bulk network configuration.
187      *
188      * @rsModel NetCfgGet
189      * @param request network configuration JSON rooted at the top node
190      * @return empty response
191      * @throws IOException if unable to parse the request
192      */
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),
201                                                     service.getSubjectFactory(sk)));
202         return Response.ok().build();
203     }
204
205     /**
206      * Upload multiple network configurations for a subject class.
207      *
208      * @param subjectClassKey subject class key
209      * @param request         network configuration JSON rooted at the top node
210      * @return empty response
211      * @throws IOException if unable to parse the request
212      */
213     @POST
214     @Path("{subjectClassKey}")
215     @Consumes(MediaType.APPLICATION_JSON)
216     @SuppressWarnings("unchecked")
217     public Response upload(@PathParam("subjectClassKey") String subjectClassKey,
218                            InputStream request) throws IOException {
219         NetworkConfigService service = get(NetworkConfigService.class);
220         ObjectNode root = (ObjectNode) mapper().readTree(request);
221         consumeJson(service, root, service.getSubjectFactory(subjectClassKey));
222         return Response.ok().build();
223     }
224
225     /**
226      * Upload mutliple network configurations for a subjectKey.
227      *
228      * @param subjectClassKey subjectKey class key
229      * @param subjectKey      subjectKey key
230      * @param request         network configuration JSON rooted at the top node
231      * @return empty response
232      * @throws IOException if unable to parse the request
233      */
234     @POST
235     @Path("{subjectClassKey}/{subjectKey}")
236     @Consumes(MediaType.APPLICATION_JSON)
237     @SuppressWarnings("unchecked")
238     public Response upload(@PathParam("subjectClassKey") String subjectClassKey,
239                            @PathParam("subjectKey") String subjectKey,
240                            InputStream request) throws IOException {
241         NetworkConfigService service = get(NetworkConfigService.class);
242         ObjectNode root = (ObjectNode) mapper().readTree(request);
243         consumeSubjectJson(service, root,
244                            service.getSubjectFactory(subjectClassKey).createSubject(subjectKey),
245                            subjectClassKey);
246         return Response.ok().build();
247     }
248
249     /**
250      * Upload specific network configuration for a subjectKey.
251      *
252      * @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
256      * @return empty response
257      * @throws IOException if unable to parse the request
258      */
259     @POST
260     @Path("{subjectClassKey}/{subjectKey}/{configKey}")
261     @Consumes(MediaType.APPLICATION_JSON)
262     @SuppressWarnings("unchecked")
263     public Response upload(@PathParam("subjectClassKey") String subjectClassKey,
264                            @PathParam("subjectKey") String subjectKey,
265                            @PathParam("configKey") String configKey,
266                            InputStream request) throws IOException {
267         NetworkConfigService service = get(NetworkConfigService.class);
268         ObjectNode root = (ObjectNode) mapper().readTree(request);
269         service.applyConfig(service.getSubjectFactory(subjectClassKey).createSubject(subjectKey),
270                             service.getConfigClass(subjectClassKey, configKey), root);
271         return Response.ok().build();
272     }
273
274     private void consumeJson(NetworkConfigService service, ObjectNode classNode,
275                              SubjectFactory subjectFactory) {
276         classNode.fieldNames().forEachRemaining(s ->
277             consumeSubjectJson(service, (ObjectNode) classNode.path(s),
278                                subjectFactory.createSubject(s),
279                                subjectFactory.subjectClassKey()));
280     }
281
282     private void consumeSubjectJson(NetworkConfigService service,
283                                     ObjectNode subjectNode, Object subject,
284                                     String subjectKey) {
285         subjectNode.fieldNames().forEachRemaining(c ->
286             service.applyConfig(subject, service.getConfigClass(subjectKey, c),
287                                 subjectNode.path(c)));
288     }
289
290
291     /**
292      * 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)
303                                 .forEach(config -> service.removeConfig(subject, config.getClass()))));
304         return Response.ok().build();
305     }
306
307     /**
308      * Clear all network configurations for a subject class.
309      *
310      * @param subjectClassKey subject class key
311      */
312     @DELETE
313     @Path("{subjectClassKey}")
314     @SuppressWarnings("unchecked")
315     public void delete(@PathParam("subjectClassKey") String subjectClassKey) {
316         NetworkConfigService service = get(NetworkConfigService.class);
317         service.getSubjects(service.getSubjectFactory(subjectClassKey).subjectClass())
318                 .forEach(subject -> service.getConfigs(subject)
319                         .forEach(config -> service.removeConfig(subject, config.getClass())));
320     }
321
322     /**
323      * Clear all network configurations for a subjectKey.
324      *
325      * @param subjectClassKey subjectKey class key
326      * @param subjectKey      subjectKey key
327      */
328     @DELETE
329     @Path("{subjectClassKey}/{subjectKey}")
330     @SuppressWarnings("unchecked")
331     public void delete(@PathParam("subjectClassKey") String subjectClassKey,
332                            @PathParam("subjectKey") String subjectKey) {
333         NetworkConfigService service = get(NetworkConfigService.class);
334         Object s = service.getSubjectFactory(subjectClassKey).createSubject(subjectKey);
335         service.getConfigs(s).forEach(c -> service.removeConfig(s, c.getClass()));
336     }
337
338     /**
339      * Clear specific network configuration for a subjectKey.
340      *
341      * @param subjectClassKey subjectKey class key
342      * @param subjectKey      subjectKey key
343      * @param configKey       configuration class key
344      */
345     @DELETE
346     @Path("{subjectClassKey}/{subjectKey}/{configKey}")
347     @SuppressWarnings("unchecked")
348     public void delete(@PathParam("subjectClassKey") String subjectClassKey,
349                            @PathParam("subjectKey") String subjectKey,
350                            @PathParam("configKey") String configKey) {
351         NetworkConfigService service = get(NetworkConfigService.class);
352         service.removeConfig(service.getSubjectFactory(subjectClassKey).createSubject(subjectKey),
353                              service.getConfigClass(subjectClassKey, configKey));
354     }
355
356 }