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