ec7f14d8b05286e039c7d7fa780fe21bb1f1e67f
[policy/clamp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2021 Nordix Foundation.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.clamp.controlloop.runtime.main.rest;
22
23 import io.swagger.annotations.ApiOperation;
24 import io.swagger.annotations.ApiParam;
25 import io.swagger.annotations.ApiResponse;
26 import io.swagger.annotations.ApiResponses;
27 import io.swagger.annotations.Authorization;
28 import io.swagger.annotations.Extension;
29 import io.swagger.annotations.ExtensionProperty;
30 import io.swagger.annotations.ResponseHeader;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.UUID;
34 import javax.ws.rs.core.Response.Status;
35 import lombok.RequiredArgsConstructor;
36 import org.onap.policy.clamp.controlloop.models.messages.rest.commissioning.CommissioningResponse;
37 import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningProvider;
38 import org.onap.policy.clamp.controlloop.runtime.main.web.AbstractRestController;
39 import org.onap.policy.models.base.PfModelException;
40 import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
41 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
42 import org.springframework.http.MediaType;
43 import org.springframework.http.ResponseEntity;
44 import org.springframework.web.bind.annotation.DeleteMapping;
45 import org.springframework.web.bind.annotation.GetMapping;
46 import org.springframework.web.bind.annotation.PostMapping;
47 import org.springframework.web.bind.annotation.RequestBody;
48 import org.springframework.web.bind.annotation.RequestHeader;
49 import org.springframework.web.bind.annotation.RequestParam;
50 import org.springframework.web.bind.annotation.RestController;
51
52 /**
53  * Class to provide REST end points for creating, deleting, querying commissioned control loops.
54  */
55 @RestController
56 @RequiredArgsConstructor
57 public class CommissioningController extends AbstractRestController {
58
59     private static final String TAGS = "Clamp Control Loop Commissioning API";
60
61     private final CommissioningProvider provider;
62
63     /**
64      * Creates a control loop definition.
65      *
66      * @param requestId request ID used in ONAP logging
67      * @param body the body of control loop following TOSCA definition
68      * @return a response
69      * @throws PfModelException on errors creating a control loop definition
70      */
71     // @formatter:off
72     @PostMapping(value = "/commission",
73             consumes = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML},
74             produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML})
75     @ApiOperation(
76         value = "Commissions control loop definitions",
77         notes = "Commissions control loop definitions, returning the commissioned control loop definition IDs",
78         response = CommissioningResponse.class,
79         tags = {TAGS},
80         authorizations = @Authorization(value = AUTHORIZATION_TYPE),
81         responseHeaders = {
82             @ResponseHeader(
83                 name = VERSION_MINOR_NAME,
84                 description = VERSION_MINOR_DESCRIPTION,
85                 response = String.class),
86             @ResponseHeader(
87                 name = VERSION_PATCH_NAME,
88                 description = VERSION_PATCH_DESCRIPTION,
89                 response = String.class),
90             @ResponseHeader(
91                 name = VERSION_LATEST_NAME,
92                 description = VERSION_LATEST_DESCRIPTION,
93                 response = String.class),
94             @ResponseHeader(
95                 name = REQUEST_ID_NAME,
96                 description = REQUEST_ID_HDR_DESCRIPTION,
97                 response = UUID.class)
98         },
99         extensions = {
100             @Extension
101                 (
102                     name = EXTENSION_NAME,
103                     properties = {
104                         @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
105                         @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
106                     }
107                 )
108         }
109     )
110     @ApiResponses(
111             value = {
112                 @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
113                 @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
114                 @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
115             }
116     )
117     // @formatter:on
118     public ResponseEntity<CommissioningResponse> create(
119             @RequestHeader(
120                     name = REQUEST_ID_NAME,
121                     required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
122             @ApiParam(value = "Entity Body of Control Loop", required = true) @RequestBody ToscaServiceTemplate body)
123             throws PfModelException {
124
125         return ResponseEntity.ok().body(provider.createControlLoopDefinitions(body));
126     }
127
128     /**
129      * Deletes a control loop definition.
130      *
131      * @param requestId request ID used in ONAP logging
132      * @param name the name of the control loop definition to delete
133      * @param version the version of the control loop definition to delete
134      * @return a response
135      * @throws PfModelException on errors deleting a control loop definition
136      */
137     // @formatter:off
138     @DeleteMapping(value = "/commission",
139             produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML})
140     @ApiOperation(value = "Delete a commissioned control loop",
141         notes = "Deletes a Commissioned Control Loop, returning optional error details",
142         response = CommissioningResponse.class,
143         tags = {TAGS},
144         authorizations = @Authorization(value = AUTHORIZATION_TYPE),
145         responseHeaders = {
146             @ResponseHeader(
147                 name = VERSION_MINOR_NAME,
148                 description = VERSION_MINOR_DESCRIPTION,
149                 response = String.class),
150             @ResponseHeader(
151                 name = VERSION_PATCH_NAME,
152                 description = VERSION_PATCH_DESCRIPTION,
153                 response = String.class),
154             @ResponseHeader(
155                 name = VERSION_LATEST_NAME,
156                 description = VERSION_LATEST_DESCRIPTION,
157                 response = String.class),
158             @ResponseHeader(
159                 name = REQUEST_ID_NAME,
160                 description = REQUEST_ID_HDR_DESCRIPTION,
161                 response = UUID.class)},
162         extensions = {
163             @Extension
164                 (
165                     name = EXTENSION_NAME,
166                     properties = {
167                         @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
168                         @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
169                     }
170                 )
171         }
172     )
173     @ApiResponses(
174         value = {
175             @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
176             @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
177             @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
178         }
179     )
180     // @formatter:on
181     public ResponseEntity<CommissioningResponse> delete(
182             @RequestHeader(
183                     name = REQUEST_ID_NAME,
184                     required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
185             @ApiParam(value = "Control Loop definition name", required = true) @RequestParam(
186                     value = "name") String name,
187             @ApiParam(
188                     value = "Control Loop definition version",
189                     required = true) @RequestParam("version") String version)
190             throws PfModelException {
191
192         return ResponseEntity.ok().body(provider.deleteControlLoopDefinition(name, version));
193     }
194
195     /**
196      * Queries details of all or specific control loop definitions.
197      *
198      * @param requestId request ID used in ONAP logging
199      * @param name the name of the control loop definition to get, null for all definitions
200      * @param version the version of the control loop definition to get, null for all definitions
201      * @return the control loop definitions
202      * @throws PfModelException on errors getting details of all or specific control loop definitions
203      */
204     // @formatter:off
205     @GetMapping(value = "/commission",
206             produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML})
207     @ApiOperation(value = "Query details of the requested commissioned control loop definitions",
208         notes = "Queries details of the requested commissioned control loop definitions, "
209             + "returning all control loop details",
210         response = ToscaNodeTemplate.class,
211         tags = {TAGS},
212         authorizations = @Authorization(value = AUTHORIZATION_TYPE),
213         responseHeaders = {
214             @ResponseHeader(
215                 name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION,
216                 response = String.class),
217             @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION,
218                 response = String.class),
219             @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION,
220                 response = String.class),
221             @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION,
222                 response = UUID.class)},
223         extensions = {
224             @Extension
225                 (
226                     name = EXTENSION_NAME,
227                     properties = {
228                         @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
229                         @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
230                     }
231                 )
232             }
233     )
234     @ApiResponses(
235         value = {
236             @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
237             @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
238             @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
239         }
240     )
241     // @formatter:on
242     public ResponseEntity<List<ToscaNodeTemplate>> query(
243             @RequestHeader(
244                     name = REQUEST_ID_NAME,
245                     required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
246             @ApiParam(value = "Control Loop definition name", required = false) @RequestParam(
247                     value = "name",
248                     required = false) String name,
249             @ApiParam(value = "Control Loop definition version", required = false) @RequestParam(
250                     value = "version",
251                     required = false) String version)
252             throws PfModelException {
253
254         return ResponseEntity.ok().body(provider.getControlLoopDefinitions(name, version));
255     }
256
257     /**
258      * Retrieves the Tosca Service Template.
259      *
260      * @param requestId request ID used in ONAP logging
261      * @param name the name of the tosca service template to retrieve
262      * @param version the version of the tosca service template to get
263      * @return the specified tosca service template
264      * @throws PfModelException on errors getting the Tosca Service Template
265      */
266     // @formatter:off
267     @GetMapping(value = "/commission/toscaservicetemplate",
268             produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML})
269     @ApiOperation(value = "Query details of the requested tosca service templates",
270         notes = "Queries details of the requested commissioned tosca service template, "
271             + "returning all tosca service template details",
272         response = ToscaServiceTemplate.class,
273         tags = {TAGS},
274         authorizations = @Authorization(value = AUTHORIZATION_TYPE),
275         responseHeaders = {
276             @ResponseHeader(
277                 name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION,
278                 response = String.class),
279             @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION,
280                 response = String.class),
281             @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION,
282                 response = String.class),
283             @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION,
284                 response = UUID.class)},
285         extensions = {
286             @Extension
287                 (
288                     name = EXTENSION_NAME,
289                     properties = {
290                         @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
291                         @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
292                     }
293                 )
294         }
295     )
296     @ApiResponses(
297         value = {
298             @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
299             @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
300             @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
301         }
302     )
303     // @formatter:on
304     public ResponseEntity<String> queryToscaServiceTemplate(
305             @RequestHeader(
306                     name = REQUEST_ID_NAME,
307                     required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
308             @ApiParam(value = "Tosca service template name", required = false) @RequestParam(
309                     value = "name",
310                     required = false) String name,
311             @ApiParam(value = "Tosca service template version", required = false) @RequestParam(
312                     value = "version",
313                     required = false) String version)
314             throws PfModelException {
315
316         return ResponseEntity.ok().body(provider.getToscaServiceTemplateReduced(name, version));
317     }
318
319     /**
320      * Retrieves the Json Schema for the specified Tosca Service Template.
321      *
322      * @param requestId request ID used in ONAP logging
323      * @param section section of the tosca service template to get schema for
324      * @return the specified tosca service template or section Json Schema
325      * @throws PfModelException on errros getting the Json Schema for the specified Tosca Service Template
326      */
327     // @formatter:off
328     @GetMapping(value = "/commission/toscaServiceTemplateSchema",
329         produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML})
330     @ApiOperation(value = "Query details of the requested tosca service template json schema",
331         notes = "Queries details of the requested commissioned tosca service template json schema, "
332             + "returning all tosca service template json schema details",
333         response = ToscaServiceTemplate.class,
334         tags = {TAGS},
335         authorizations = @Authorization(value = AUTHORIZATION_TYPE),
336         responseHeaders = {
337             @ResponseHeader(
338                 name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION,
339                 response = String.class),
340             @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION,
341                 response = String.class),
342             @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION,
343                 response = String.class),
344             @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION,
345                 response = UUID.class)},
346         extensions = {
347             @Extension
348                 (
349                     name = EXTENSION_NAME,
350                     properties = {
351                         @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
352                         @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
353                     }
354                 )
355         }
356     )
357     @ApiResponses(
358         value = {
359             @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
360             @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
361             @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
362         }
363     )
364     // @formatter:on
365     public ResponseEntity<String> queryToscaServiceTemplateJsonSchema(
366             @RequestHeader(
367                     name = REQUEST_ID_NAME,
368                     required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
369             @ApiParam(value = "Section of Template schema is desired for", required = false) @RequestParam(
370                     value = "section",
371                     required = false,
372                     defaultValue = "all") String section)
373             throws PfModelException {
374
375         return ResponseEntity.ok().body(provider.getToscaServiceTemplateSchema(section));
376     }
377
378     /**
379      * Retrieves the Common or Instance Properties for the specified Tosca Service Template.
380      *
381      * @param requestId request ID used in ONAP logging
382      * @param common a flag, true to get common properties, false to get instance properties
383      * @param name the name of the tosca service template to retrieve
384      * @param version the version of the tosca service template to get
385      * @return the specified tosca service template or section Json Schema
386      * @throws PfModelException on errors getting the Common or Instance Properties
387      */
388     // @formatter:off
389     @GetMapping(value = "/commission/getCommonOrInstanceProperties",
390         produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML})
391     @ApiOperation(value = "Query details of the requested tosca service template common or instance properties",
392         notes = "Queries details of the requested commissioned tosca service template json common"
393             + "or instance properties, returning all tosca service template common or instance property details",
394         response = ToscaServiceTemplate.class,
395         tags = {"Clamp Control Loop Commissioning API"},
396         authorizations = @Authorization(value = AUTHORIZATION_TYPE),
397         responseHeaders = {
398             @ResponseHeader(
399                 name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION,
400                 response = String.class),
401             @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION,
402                 response = String.class),
403             @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION,
404                 response = String.class),
405             @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION,
406                 response = UUID.class)},
407         extensions = {
408             @Extension
409                 (
410                     name = EXTENSION_NAME,
411                     properties = {
412                         @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
413                         @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
414                     }
415                 )
416         }
417     )
418     @ApiResponses(
419         value = {
420             @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
421             @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
422             @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
423         }
424     )
425     // @formatter:on
426     public ResponseEntity<Map<String, ToscaNodeTemplate>> queryToscaServiceCommonOrInstanceProperties(
427             @RequestHeader(
428                     name = REQUEST_ID_NAME,
429                     required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
430             @ApiParam(value = "Flag, true for common properties, false for instance", required = false) @RequestParam(
431                     value = "common",
432                     defaultValue = "false",
433                     required = false) boolean common,
434             @ApiParam(value = "Tosca service template name", required = false) @RequestParam(
435                     value = "name",
436                     required = false) String name,
437             @ApiParam(value = "Tosca service template version", required = false) @RequestParam(
438                     value = "version",
439                     required = false) String version)
440             throws PfModelException {
441
442         return ResponseEntity.ok().body(provider.getNodeTemplatesWithCommonOrInstanceProperties(common, name, version));
443     }
444
445     /**
446      * Queries the elements of a specific control loop.
447      *
448      * @param requestId request ID used in ONAP logging
449      * @param name the name of the control loop definition to get
450      * @param version the version of the control loop definition to get
451      * @return the control loop element definitions
452      * @throws PfModelException on errors getting the elements of a specific control loop
453      */
454     // @formatter:off
455     @GetMapping(value = "/commission/elements",
456             produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML})
457     @ApiOperation(value = "Query details of the requested commissioned control loop element definitions",
458         notes = "Queries details of the requested commissioned control loop element definitions, "
459             + "returning all control loop elements' details",
460         response = ToscaNodeTemplate.class,
461         tags = {TAGS},
462         authorizations = @Authorization(value = AUTHORIZATION_TYPE),
463         responseHeaders = {
464             @ResponseHeader(
465                 name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION,
466                 response = String.class),
467             @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION,
468                 response = String.class),
469             @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION,
470                 response = String.class),
471             @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION,
472                 response = UUID.class)},
473         extensions = {
474             @Extension
475                 (
476                     name = EXTENSION_NAME,
477                     properties = {
478                         @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
479                         @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
480                     }
481                 )
482         }
483     )
484     @ApiResponses(
485         value = {
486             @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
487             @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
488             @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
489         }
490     )
491     // @formatter:on
492     public ResponseEntity<List<ToscaNodeTemplate>> queryElements(
493             @RequestHeader(
494                     name = REQUEST_ID_NAME,
495                     required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
496             @ApiParam(value = "Control Loop definition name", required = false) @RequestParam(
497                     value = "name",
498                     required = false) String name,
499             @ApiParam(value = "Control Loop definition version", required = false) @RequestParam(
500                     value = "version",
501                     required = false) String version)
502             throws PfModelException {
503
504         List<ToscaNodeTemplate> nodeTemplate = provider.getControlLoopDefinitions(name, version);
505         // Prevent ambiguous queries with multiple returns
506         if (nodeTemplate.size() > 1) {
507             throw new PfModelException(Status.NOT_ACCEPTABLE, "Multiple ControlLoops are not supported");
508         }
509
510         List<ToscaNodeTemplate> response = provider.getControlLoopElementDefinitions(nodeTemplate.get(0));
511         return ResponseEntity.ok().body(response);
512     }
513 }