5a8275f8acdbca1d61c8f03fd5d372585dd16a40
[policy/clamp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2021 Nordix Foundation.
4  *  Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
5  * ================================================================================
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * SPDX-License-Identifier: Apache-2.0
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.clamp.controlloop.runtime.main.rest;
23
24 import io.swagger.annotations.ApiOperation;
25 import io.swagger.annotations.ApiParam;
26 import io.swagger.annotations.ApiResponse;
27 import io.swagger.annotations.ApiResponses;
28 import io.swagger.annotations.Authorization;
29 import io.swagger.annotations.Extension;
30 import io.swagger.annotations.ExtensionProperty;
31 import io.swagger.annotations.ResponseHeader;
32 import java.util.UUID;
33 import lombok.RequiredArgsConstructor;
34 import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException;
35 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops;
36 import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.ControlLoopOrderStateResponse;
37 import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstancePropertiesResponse;
38 import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationCommand;
39 import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationResponse;
40 import org.onap.policy.clamp.controlloop.runtime.instantiation.ControlLoopInstantiationProvider;
41 import org.onap.policy.clamp.controlloop.runtime.main.web.AbstractRestController;
42 import org.onap.policy.models.base.PfModelException;
43 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
44 import org.springframework.http.MediaType;
45 import org.springframework.http.ResponseEntity;
46 import org.springframework.web.bind.annotation.DeleteMapping;
47 import org.springframework.web.bind.annotation.GetMapping;
48 import org.springframework.web.bind.annotation.PostMapping;
49 import org.springframework.web.bind.annotation.PutMapping;
50 import org.springframework.web.bind.annotation.RequestBody;
51 import org.springframework.web.bind.annotation.RequestHeader;
52 import org.springframework.web.bind.annotation.RequestParam;
53 import org.springframework.web.bind.annotation.RestController;
54
55 /**
56  * Class to provide REST end points for creating, deleting, query and commanding a control loop definition.
57  */
58 @RestController
59 @RequiredArgsConstructor
60 public class InstantiationController extends AbstractRestController {
61
62     private static final String TAGS = "Clamp Control Loop Instantiation API";
63
64     // The CL provider for instantiation requests
65     private final ControlLoopInstantiationProvider provider;
66
67     /**
68      * Creates a control loop.
69      *
70      * @param requestId request ID used in ONAP logging
71      * @param controlLoops the control loops
72      * @return a response
73      * @throws PfModelException on errors creating a control loop
74      */
75     // @formatter:off
76     @PostMapping(value = "/instantiation",
77             produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML},
78             consumes = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML})
79     @ApiOperation(
80             value = "Commissions control loop definitions",
81             notes = "Commissions control loop definitions, returning the control loop IDs",
82             response = InstantiationResponse.class,
83             tags = {TAGS},
84             authorizations = @Authorization(value = AUTHORIZATION_TYPE),
85             responseHeaders = {
86                 @ResponseHeader(
87                     name = VERSION_MINOR_NAME,
88                     description = VERSION_MINOR_DESCRIPTION,
89                     response = String.class),
90                 @ResponseHeader(
91                     name = VERSION_PATCH_NAME,
92                     description = VERSION_PATCH_DESCRIPTION,
93                     response = String.class),
94                 @ResponseHeader(
95                     name = VERSION_LATEST_NAME,
96                     description = VERSION_LATEST_DESCRIPTION,
97                     response = String.class),
98                 @ResponseHeader(
99                     name = REQUEST_ID_NAME,
100                     description = REQUEST_ID_HDR_DESCRIPTION,
101                     response = UUID.class)
102                 },
103             extensions = {
104                 @Extension
105                     (
106                         name = EXTENSION_NAME,
107                         properties = {
108                             @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
109                             @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
110                         }
111                     )
112             }
113         )
114     @ApiResponses(
115             value = {
116                 @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
117                 @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
118                 @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
119             }
120         )
121     // @formatter:on
122     public ResponseEntity<InstantiationResponse> create(
123             @RequestHeader(
124                     name = REQUEST_ID_NAME,
125                     required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
126             @ApiParam(value = "Entity Body of Control Loop", required = true) @RequestBody ControlLoops controlLoops)
127             throws PfModelException {
128
129         return ResponseEntity.ok().body(provider.createControlLoops(controlLoops));
130     }
131
132     /**
133      * Saves instance properties.
134      *
135      * @param requestId request ID used in ONAP logging
136      * @param body the body of control loop following TOSCA definition
137      * @return a response
138      */
139     // @formatter:off
140     @PostMapping(value = "/instanceProperties",
141         consumes = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML},
142         produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML})
143     @ApiOperation(
144         value = "Saves instance properties",
145         notes = "Saves instance properties, returning the saved instances properties and it's version",
146         response = InstancePropertiesResponse.class,
147         tags = {TAGS},
148         authorizations = @Authorization(value = AUTHORIZATION_TYPE),
149         responseHeaders = {
150             @ResponseHeader(
151                 name = VERSION_MINOR_NAME,
152                 description = VERSION_MINOR_DESCRIPTION,
153                 response = String.class),
154             @ResponseHeader(
155                 name = VERSION_PATCH_NAME,
156                 description = VERSION_PATCH_DESCRIPTION,
157                 response = String.class),
158             @ResponseHeader(
159                 name = VERSION_LATEST_NAME,
160                 description = VERSION_LATEST_DESCRIPTION,
161                 response = String.class),
162             @ResponseHeader(
163                 name = REQUEST_ID_NAME,
164                 description = REQUEST_ID_HDR_DESCRIPTION,
165                 response = UUID.class)
166         },
167         extensions = {
168             @Extension
169                 (
170                     name = EXTENSION_NAME,
171                     properties = {
172                         @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
173                         @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
174                     }
175                 )
176         }
177     )
178     @ApiResponses(
179         value = {
180             @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
181             @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
182             @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
183         }
184     )
185     // @formatter:on
186     public ResponseEntity<InstancePropertiesResponse> createInstanceProperties(
187             @RequestHeader(
188                 name = REQUEST_ID_NAME,
189                 required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
190             @ApiParam(value = "Body of instance properties", required = true) @RequestBody ToscaServiceTemplate body) {
191
192         return ResponseEntity.ok().body(provider.saveInstanceProperties(body));
193     }
194
195     /**
196      * Queries details of all control loops.
197      *
198      * @param requestId request ID used in ONAP logging
199      * @param name the name of the control loop to get, null for all control loops
200      * @param version the version of the control loop to get, null for all control loops
201      * @return the control loops
202      * @throws PfModelException on errors getting commissioning of control loop
203      */
204     // @formatter:off
205     @GetMapping(value = "/instantiation",
206             produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML})
207     @ApiOperation(value = "Query details of the requested control loops",
208             notes = "Queries details of the requested control loops, returning all control loop details",
209             response = ControlLoops.class,
210             tags = {TAGS},
211             authorizations = @Authorization(value = AUTHORIZATION_TYPE),
212             responseHeaders = {
213                 @ResponseHeader(
214                     name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION,
215                     response = String.class),
216                 @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION,
217                     response = String.class),
218                 @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION,
219                     response = String.class),
220                 @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION,
221                     response = UUID.class)},
222             extensions = {
223                 @Extension
224                      (
225                          name = EXTENSION_NAME,
226                          properties = {
227                              @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
228                              @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
229                          }
230                     )
231                 }
232         )
233     @ApiResponses(
234             value = {
235                 @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
236                 @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
237                 @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
238             }
239         )
240     // @formatter:on
241     public ResponseEntity<ControlLoops> query(
242             @RequestHeader(
243                     name = REQUEST_ID_NAME,
244                     required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
245             @ApiParam(value = "Control Loop definition name", required = false) @RequestParam(
246                     value = "name",
247                     required = false) String name,
248             @ApiParam(value = "Control Loop definition version", required = false) @RequestParam(
249                     value = "version",
250                     required = false) String version)
251             throws PfModelException {
252
253         return ResponseEntity.ok().body(provider.getControlLoops(name, version));
254     }
255
256     /**
257      * Updates a control loop.
258      *
259      * @param requestId request ID used in ONAP logging
260      * @param controlLoops the control loops
261      * @return a response
262      * @throws PfModelException on errors updating of control loops
263      */
264     // @formatter:off
265     @PutMapping(value = "/instantiation",
266             produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML},
267             consumes = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML})
268     @ApiOperation(
269             value = "Updates control loop definitions",
270             notes = "Updates control loop definitions, returning the updated control loop definition IDs",
271             response = InstantiationResponse.class,
272             tags = {TAGS},
273             authorizations = @Authorization(value = AUTHORIZATION_TYPE),
274             responseHeaders = {
275                 @ResponseHeader(
276                     name = VERSION_MINOR_NAME,
277                     description = VERSION_MINOR_DESCRIPTION,
278                     response = String.class),
279                 @ResponseHeader(
280                     name = VERSION_PATCH_NAME,
281                     description = VERSION_PATCH_DESCRIPTION,
282                     response = String.class),
283                 @ResponseHeader(
284                     name = VERSION_LATEST_NAME,
285                     description = VERSION_LATEST_DESCRIPTION,
286                     response = String.class),
287                 @ResponseHeader(
288                     name = REQUEST_ID_NAME,
289                     description = REQUEST_ID_HDR_DESCRIPTION,
290                     response = UUID.class)
291             },
292             extensions = {
293                 @Extension
294                     (
295                         name = EXTENSION_NAME,
296                         properties = {
297                             @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
298                             @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
299                         }
300                     )
301             }
302         )
303     @ApiResponses(
304             value = {
305                 @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
306                 @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
307                 @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
308             }
309         )
310     // @formatter:on
311     public ResponseEntity<InstantiationResponse> update(
312             @RequestHeader(
313                     name = REQUEST_ID_NAME,
314                     required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
315             @ApiParam(value = "Entity Body of Control Loop", required = true) @RequestBody ControlLoops controlLoops)
316             throws PfModelException {
317
318         return ResponseEntity.ok().body(provider.updateControlLoops(controlLoops));
319     }
320
321     /**
322      * Deletes a control loop definition.
323      *
324      * @param requestId request ID used in ONAP logging
325      * @param name the name of the control loop to delete
326      * @param version the version of the control loop to delete
327      * @return a response
328      * @throws PfModelException on errors deleting of control loop
329      */
330     // @formatter:off
331     @DeleteMapping(value = "/instantiation",
332             produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML})
333     @ApiOperation(value = "Delete a control loop",
334             notes = "Deletes a control loop, returning optional error details",
335             response = InstantiationResponse.class,
336             tags = {TAGS},
337             authorizations = @Authorization(value = AUTHORIZATION_TYPE),
338             responseHeaders = {
339                 @ResponseHeader(
340                     name = VERSION_MINOR_NAME,
341                     description = VERSION_MINOR_DESCRIPTION,
342                     response = String.class),
343                 @ResponseHeader(
344                     name = VERSION_PATCH_NAME,
345                     description = VERSION_PATCH_DESCRIPTION,
346                     response = String.class),
347                 @ResponseHeader(
348                     name = VERSION_LATEST_NAME,
349                     description = VERSION_LATEST_DESCRIPTION,
350                     response = String.class),
351                 @ResponseHeader(
352                     name = REQUEST_ID_NAME,
353                     description = REQUEST_ID_HDR_DESCRIPTION,
354                     response = UUID.class)},
355             extensions = {
356                 @Extension
357                     (
358                         name = EXTENSION_NAME,
359                         properties = {
360                             @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
361                             @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
362                         }
363                     )
364                 }
365         )
366     @ApiResponses(
367         value = {
368             @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
369             @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
370             @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
371         }
372     )
373     // @formatter:on
374
375     public ResponseEntity<InstantiationResponse> delete(
376             @RequestHeader(
377                     name = REQUEST_ID_NAME,
378                     required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
379             @ApiParam(value = "Control Loop definition name", required = true) @RequestParam("name") String name,
380             @ApiParam(value = "Control Loop definition version") @RequestParam(
381                     value = "version",
382                     required = false) String version)
383             throws PfModelException {
384
385         return ResponseEntity.ok().body(provider.deleteControlLoop(name, version));
386     }
387
388     /**
389      * Issues control loop commands to control loops.
390      *
391      * @param requestId request ID used in ONAP logging
392      * @param command the command to issue to control loops
393      * @return the control loop definitions
394      * @throws PfModelException on errors issuing a command
395      * @throws ControlLoopException on errors issuing a command
396      */
397     // @formatter:off
398     @PutMapping(value = "/instantiation/command",
399             produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML},
400             consumes = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML})
401     @ApiOperation(value = "Issue a command to the requested control loops",
402             notes = "Issues a command to a control loop, ordering a state change on the control loop",
403             response = InstantiationResponse.class,
404             tags = {TAGS},
405             authorizations = @Authorization(value = AUTHORIZATION_TYPE),
406             responseHeaders = {
407                 @ResponseHeader(
408                     name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION,
409                     response = String.class),
410                 @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION,
411                     response = String.class),
412                 @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION,
413                     response = String.class),
414                 @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION,
415                     response = UUID.class)},
416             extensions = {
417                 @Extension
418                     (
419                         name = EXTENSION_NAME,
420                         properties = {
421                             @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
422                             @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
423                         }
424                     )
425                 }
426         )
427     @ApiResponses(
428             value = {
429                 @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
430                 @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
431                 @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
432             }
433         )
434     // @formatter:on
435     public ResponseEntity<InstantiationResponse> issueControlLoopCommand(
436             @RequestHeader(
437                     name = REQUEST_ID_NAME,
438                     required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
439             @ApiParam(
440                     value = "Entity Body of control loop command",
441                     required = true) @RequestBody InstantiationCommand command)
442             throws ControlLoopException, PfModelException {
443
444         return ResponseEntity.accepted().body(provider.issueControlLoopCommand(command));
445     }
446
447     /**
448      * Queries details of all control loops.
449      *
450      * @param requestId request ID used in ONAP logging
451      * @param name the name of the control loop to get, null for all control loops
452      * @param version the version of the control loop to get, null for all control loops
453      * @return the control loops
454      * @throws PfModelException on errors getting commissioning of control loop
455      */
456     // @formatter:off
457     @GetMapping(value = "/instantiationState",
458         produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML})
459     @ApiOperation(value = "Query details of the requested control loops",
460         notes = "Queries details of the requested control loops, returning all control loop details",
461         response = ControlLoops.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<ControlLoopOrderStateResponse> getInstantiationOrderState(
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         return ResponseEntity.ok().body(provider.getInstantiationOrderState(name, version));
506     }
507 }