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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.clamp.controlloop.runtime.main.rest;
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.UUID;
33 import org.onap.policy.clamp.controlloop.models.messages.rest.commissioning.CommissioningResponse;
34 import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningProvider;
35 import org.onap.policy.clamp.controlloop.runtime.main.web.AbstractRestController;
36 import org.onap.policy.models.base.PfModelException;
37 import org.onap.policy.models.base.PfModelRuntimeException;
38 import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
39 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42 import org.springframework.http.HttpStatus;
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;
54 * Class to provide REST end points for creating, deleting, querying commissioned control loops.
57 public class CommissioningController extends AbstractRestController {
59 private static final Logger LOGGER = LoggerFactory.getLogger(CommissioningController.class);
61 private final CommissioningProvider provider;
64 * Create Commissioning Controller.
66 * @param provider the CommissioningProvider
68 public CommissioningController(CommissioningProvider provider) {
69 this.provider = provider;
73 * Creates a control loop definition.
75 * @param requestId request ID used in ONAP logging
76 * @param body the body of control loop following TOSCA definition
80 @PostMapping(value = "/commission",
81 consumes = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML},
82 produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML})
84 value = "Commissions control loop definitions",
85 notes = "Commissions control loop definitions, returning the commissioned control loop definition IDs",
86 response = CommissioningResponse.class,
87 tags = {"Control Loop Commissioning API"},
88 authorizations = @Authorization(value = AUTHORIZATION_TYPE),
91 name = VERSION_MINOR_NAME,
92 description = VERSION_MINOR_DESCRIPTION,
93 response = String.class),
95 name = VERSION_PATCH_NAME,
96 description = VERSION_PATCH_DESCRIPTION,
97 response = String.class),
99 name = VERSION_LATEST_NAME,
100 description = VERSION_LATEST_DESCRIPTION,
101 response = String.class),
103 name = REQUEST_ID_NAME,
104 description = REQUEST_ID_HDR_DESCRIPTION,
105 response = UUID.class)
110 name = EXTENSION_NAME,
112 @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
113 @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
120 @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
121 @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
122 @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
126 public ResponseEntity<CommissioningResponse> create(
128 name = REQUEST_ID_NAME,
129 required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
130 @ApiParam(value = "Entity Body of Control Loop", required = true) @RequestBody ToscaServiceTemplate body) {
132 return ResponseEntity.ok().body(provider.createControlLoopDefinitions(body));
134 } catch (PfModelRuntimeException | PfModelException e) {
135 LOGGER.warn("Commissioning of the control loops failed", e);
136 var resp = new CommissioningResponse();
137 resp.setErrorDetails(e.getErrorResponse().getErrorMessage());
138 return ResponseEntity.status(e.getErrorResponse().getResponseCode().getStatusCode()).body(resp);
144 * Deletes a control loop definition.
146 * @param requestId request ID used in ONAP logging
147 * @param name the name of the control loop definition to delete
148 * @param version the version of the control loop definition to delete
152 @DeleteMapping(value = "/commission",
153 produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML})
154 @ApiOperation(value = "Delete a commissioned control loop",
155 notes = "Deletes a Commissioned Control Loop, returning optional error details",
156 response = CommissioningResponse.class,
157 tags = {"Clamp Control Loop Commissioning API"},
158 authorizations = @Authorization(value = AUTHORIZATION_TYPE),
161 name = VERSION_MINOR_NAME,
162 description = VERSION_MINOR_DESCRIPTION,
163 response = String.class),
165 name = VERSION_PATCH_NAME,
166 description = VERSION_PATCH_DESCRIPTION,
167 response = String.class),
169 name = VERSION_LATEST_NAME,
170 description = VERSION_LATEST_DESCRIPTION,
171 response = String.class),
173 name = REQUEST_ID_NAME,
174 description = REQUEST_ID_HDR_DESCRIPTION,
175 response = UUID.class)},
179 name = EXTENSION_NAME,
181 @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
182 @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
189 @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
190 @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
191 @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
195 public ResponseEntity<CommissioningResponse> delete(
197 name = REQUEST_ID_NAME,
198 required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
199 @ApiParam(value = "Control Loop definition name", required = true) @RequestParam(
200 value = "name") String name,
202 value = "Control Loop definition version",
203 required = true) @RequestParam("version") String version) {
206 return ResponseEntity.ok().body(provider.deleteControlLoopDefinition(name, version));
208 } catch (PfModelRuntimeException | PfModelException e) {
209 LOGGER.warn("Decommisssioning of control loop failed", e);
210 var resp = new CommissioningResponse();
211 resp.setErrorDetails(e.getErrorResponse().getErrorMessage());
212 return ResponseEntity.status(e.getErrorResponse().getResponseCode().getStatusCode()).body(resp);
218 * Queries details of all or specific control loop definitions.
220 * @param requestId request ID used in ONAP logging
221 * @param name the name of the control loop definition to get, null for all definitions
222 * @param version the version of the control loop definition to get, null for all definitions
223 * @return the control loop definitions
226 @GetMapping(value = "/commission",
227 produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML})
228 @ApiOperation(value = "Query details of the requested commissioned control loop definitions",
229 notes = "Queries details of the requested commissioned control loop definitions, "
230 + "returning all control loop details",
231 response = ToscaNodeTemplate.class,
232 tags = {"Clamp Control Loop Commissioning API"},
233 authorizations = @Authorization(value = AUTHORIZATION_TYPE),
236 name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION,
237 response = String.class),
238 @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION,
239 response = String.class),
240 @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION,
241 response = String.class),
242 @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION,
243 response = UUID.class)},
247 name = EXTENSION_NAME,
249 @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
250 @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
257 @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
258 @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
259 @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
263 public ResponseEntity<?> query(
265 name = REQUEST_ID_NAME,
266 required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
267 @ApiParam(value = "Control Loop definition name", required = false) @RequestParam(
269 required = false) String name,
270 @ApiParam(value = "Control Loop definition version", required = false) @RequestParam(
272 required = false) String version) {
275 return ResponseEntity.ok().body(provider.getControlLoopDefinitions(name, version));
277 } catch (PfModelRuntimeException | PfModelException e) {
278 LOGGER.warn("Get of control loop definitions failed", e);
279 var resp = new CommissioningResponse();
280 resp.setErrorDetails(e.getErrorResponse().getErrorMessage());
281 return ResponseEntity.status(e.getErrorResponse().getResponseCode().getStatusCode()).body(resp);
287 * Retrieves the Tosca Service Template.
289 * @param requestId request ID used in ONAP logging
290 * @param name the name of the tosca service template to retrieve
291 * @param version the version of the tosca service template to get
292 * @return the specified tosca service template
295 @GetMapping(value = "/commission/toscaservicetemplate",
296 produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML})
297 @ApiOperation(value = "Query details of the requested tosca service templates",
298 notes = "Queries details of the requested commissioned tosca service template, "
299 + "returning all tosca service template details",
300 response = ToscaServiceTemplate.class,
301 tags = {"Clamp Control Loop Commissioning API"},
302 authorizations = @Authorization(value = AUTHORIZATION_TYPE),
305 name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION,
306 response = String.class),
307 @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION,
308 response = String.class),
309 @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION,
310 response = String.class),
311 @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION,
312 response = UUID.class)},
316 name = EXTENSION_NAME,
318 @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
319 @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
326 @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
327 @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
328 @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
332 public ResponseEntity<?> queryToscaServiceTemplate(
334 name = REQUEST_ID_NAME,
335 required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
336 @ApiParam(value = "Tosca service template name", required = false) @RequestParam(
338 required = false) String name,
339 @ApiParam(value = "Tosca service template version", required = true) @RequestParam(
341 required = false) String version) {
344 return ResponseEntity.ok().body(provider.getToscaServiceTemplate(name, version));
346 } catch (PfModelRuntimeException | PfModelException e) {
347 LOGGER.warn("Get of tosca service template failed", e);
348 var resp = new CommissioningResponse();
349 resp.setErrorDetails(e.getErrorResponse().getErrorMessage());
350 return ResponseEntity.status(e.getErrorResponse().getResponseCode().getStatusCode()).body(resp);
356 * Queries the elements of a specific control loop.
358 * @param requestId request ID used in ONAP logging
359 * @param name the name of the control loop definition to get
360 * @param version the version of the control loop definition to get
361 * @return the control loop element definitions
364 @GetMapping(value = "/commission/elements",
365 produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML})
366 @ApiOperation(value = "Query details of the requested commissioned control loop element definitions",
367 notes = "Queries details of the requested commissioned control loop element definitions, "
368 + "returning all control loop elements' details",
369 response = ToscaNodeTemplate.class,
370 tags = {"Clamp Control Loop Commissioning API"},
371 authorizations = @Authorization(value = AUTHORIZATION_TYPE),
374 name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION,
375 response = String.class),
376 @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION,
377 response = String.class),
378 @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION,
379 response = String.class),
380 @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION,
381 response = UUID.class)},
385 name = EXTENSION_NAME,
387 @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
388 @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)
395 @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
396 @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
397 @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)
401 public ResponseEntity<?> queryElements(
403 name = REQUEST_ID_NAME,
404 required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
405 @ApiParam(value = "Control Loop definition name", required = false) @RequestParam(
407 required = false) String name,
408 @ApiParam(value = "Control Loop definition version", required = true) @RequestParam(
410 required = false) String version) {
413 List<ToscaNodeTemplate> nodeTemplate = provider.getControlLoopDefinitions(name, version);
414 // Prevent ambiguous queries with multiple returns
415 if (nodeTemplate.size() > 1) {
416 var resp = new CommissioningResponse();
417 resp.setErrorDetails("Multiple ControlLoops are not supported");
418 return ResponseEntity.status(HttpStatus.NOT_ACCEPTABLE).body(resp);
421 List<ToscaNodeTemplate> response = provider.getControlLoopElementDefinitions(nodeTemplate.get(0));
422 return ResponseEntity.ok().body(response);
424 } catch (PfModelRuntimeException | PfModelException e) {
425 LOGGER.warn("Get of control loop element definitions failed", e);
426 var resp = new CommissioningResponse();
427 resp.setErrorDetails(e.getErrorResponse().getErrorMessage());
428 return ResponseEntity.status(e.getErrorResponse().getResponseCode().getStatusCode()).body(resp);