2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2021 Pantheon.tech
4 * Modifications Copyright (C) 2021-2022 Nordix Foundation
5 * Modifications Copyright (C) 2021 highstreet technologies GmbH
6 * Modifications Copyright (C) 2021-2022 Bell Canada
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
20 * SPDX-License-Identifier: Apache-2.0
21 * ============LICENSE_END=========================================================
24 package org.onap.cps.ncmp.rest.controller;
26 import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.CREATE;
27 import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.DELETE;
28 import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.PATCH;
29 import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.UPDATE;
31 import java.util.List;
34 import java.util.UUID;
35 import java.util.stream.Collectors;
36 import javax.validation.Valid;
37 import javax.validation.constraints.NotNull;
38 import lombok.RequiredArgsConstructor;
39 import lombok.extern.slf4j.Slf4j;
40 import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
41 import org.onap.cps.ncmp.api.impl.exception.InvalidTopicException;
42 import org.onap.cps.ncmp.api.inventory.CompositeState;
43 import org.onap.cps.ncmp.api.models.CmHandleQueryApiParameters;
44 import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
45 import org.onap.cps.ncmp.rest.api.NetworkCmProxyApi;
46 import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor;
47 import org.onap.cps.ncmp.rest.mapper.CmHandleStateMapper;
48 import org.onap.cps.ncmp.rest.model.CmHandlePublicProperties;
49 import org.onap.cps.ncmp.rest.model.CmHandleQueryParameters;
50 import org.onap.cps.ncmp.rest.model.RestModuleReference;
51 import org.onap.cps.ncmp.rest.model.RestOutputCmHandle;
52 import org.onap.cps.ncmp.rest.model.RestOutputCmHandleCompositeState;
53 import org.onap.cps.ncmp.rest.model.RestOutputCmHandlePublicProperties;
54 import org.onap.cps.ncmp.rest.util.DeprecationHelper;
55 import org.onap.cps.utils.CpsValidator;
56 import org.onap.cps.utils.JsonObjectMapper;
57 import org.springframework.beans.factory.annotation.Value;
58 import org.springframework.http.HttpStatus;
59 import org.springframework.http.ResponseEntity;
60 import org.springframework.web.bind.annotation.RequestMapping;
61 import org.springframework.web.bind.annotation.RestController;
65 @RequestMapping("${rest.api.ncmp-base-path}")
66 @RequiredArgsConstructor
67 public class NetworkCmProxyController implements NetworkCmProxyApi {
69 private static final String NO_BODY = null;
70 private static final String NO_REQUEST_ID = null;
71 private static final String NO_TOPIC = null;
72 private final NetworkCmProxyDataService networkCmProxyDataService;
73 private final JsonObjectMapper jsonObjectMapper;
75 private final DeprecationHelper deprecationHelper;
76 private final NcmpRestInputMapper ncmpRestInputMapper;
77 private final CmHandleStateMapper cmHandleStateMapper;
78 private final CpsNcmpTaskExecutor cpsNcmpTaskExecutor;
79 @Value("${notification.async.executor.time-out-value-in-ms:2000}")
80 private int timeOutInMilliSeconds;
81 @Value("${notification.enabled:true}")
82 private boolean asyncEnabled;
85 * Get resource data from operational datastore.
87 * @param cmHandle cm handle identifier
88 * @param resourceIdentifier resource identifier
89 * @param optionsParamInQuery options query parameter
90 * @param topicParamInQuery topic query parameter
91 * @return {@code ResponseEntity} response from dmi plugin
94 public ResponseEntity<Object> getResourceDataOperationalForCmHandle(final String cmHandle,
95 final @NotNull @Valid String resourceIdentifier,
96 final @Valid String optionsParamInQuery,
97 final @Valid String topicParamInQuery) {
98 if (asyncEnabled && isValidTopic(topicParamInQuery)) {
99 final String requestId = UUID.randomUUID().toString();
100 log.info("Received Async passthrough-operational request with id {}", requestId);
101 cpsNcmpTaskExecutor.executeTask(() ->
102 networkCmProxyDataService.getResourceDataOperationalForCmHandle(
103 cmHandle, resourceIdentifier, optionsParamInQuery, topicParamInQuery, requestId
104 ), timeOutInMilliSeconds
106 return ResponseEntity.ok(Map.of("requestId", requestId));
108 log.warn("Asynchronous messaging is currently disabled for passthrough-operational."
109 + " Will use synchronous operation.");
112 final Object responseObject = networkCmProxyDataService.getResourceDataOperationalForCmHandle(
113 cmHandle, resourceIdentifier, optionsParamInQuery, NO_TOPIC, NO_REQUEST_ID);
115 return ResponseEntity.ok(responseObject);
119 * Get resource data from pass-through running datastore.
121 * @param cmHandle cm handle identifier
122 * @param resourceIdentifier resource identifier
123 * @param optionsParamInQuery options query parameter
124 * @param topicParamInQuery topic query parameter
125 * @return {@code ResponseEntity} response from dmi plugin
128 public ResponseEntity<Object> getResourceDataRunningForCmHandle(final String cmHandle,
129 final @NotNull @Valid String resourceIdentifier,
130 final @Valid String optionsParamInQuery,
131 final @Valid String topicParamInQuery) {
132 if (asyncEnabled && isValidTopic(topicParamInQuery)) {
133 final String requestId = UUID.randomUUID().toString();
134 log.info("Received Async passthrough-running request with id {}", requestId);
135 cpsNcmpTaskExecutor.executeTask(() ->
136 networkCmProxyDataService.getResourceDataPassThroughRunningForCmHandle(
137 cmHandle, resourceIdentifier, optionsParamInQuery, topicParamInQuery, requestId
138 ), timeOutInMilliSeconds
140 return ResponseEntity.ok(Map.of("requestId", requestId));
142 log.warn("Asynchronous messaging is currently disabled for passthrough-running."
143 + " Will use synchronous operation.");
146 final Object responseObject = networkCmProxyDataService.getResourceDataPassThroughRunningForCmHandle(
147 cmHandle, resourceIdentifier, optionsParamInQuery, NO_TOPIC, NO_REQUEST_ID);
149 return ResponseEntity.ok(responseObject);
153 public ResponseEntity<Object> patchResourceDataRunningForCmHandle(final String resourceIdentifier,
154 final String cmHandle,
155 final Object requestBody, final String contentType) {
156 final Object responseObject = networkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle(cmHandle,
157 resourceIdentifier, PATCH, jsonObjectMapper.asJsonString(requestBody), contentType);
158 return ResponseEntity.ok(responseObject);
162 * Create resource data in datastore pass-through running for given cm-handle.
164 * @param resourceIdentifier resource identifier
165 * @param cmHandle cm handle identifier
166 * @param requestBody the request body
167 * @param contentType content type of body
168 * @return {@code ResponseEntity} response from dmi plugin
171 public ResponseEntity<Void> createResourceDataRunningForCmHandle(final String resourceIdentifier,
172 final String cmHandle, final Object requestBody, final String contentType) {
173 networkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle(cmHandle,
174 resourceIdentifier, CREATE, jsonObjectMapper.asJsonString(requestBody), contentType);
175 return new ResponseEntity<>(HttpStatus.CREATED);
179 * Update resource data in datastore pass-through running for given cm-handle.
181 * @param resourceIdentifier resource identifier
182 * @param cmHandle cm handle identifier
183 * @param requestBody the request body
184 * @param contentType content type of the body
185 * @return response entity
188 public ResponseEntity<Object> updateResourceDataRunningForCmHandle(final String resourceIdentifier,
189 final String cmHandle,
190 final Object requestBody,
191 final String contentType) {
192 networkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle(cmHandle,
193 resourceIdentifier, UPDATE, jsonObjectMapper.asJsonString(requestBody), contentType);
194 return new ResponseEntity<>(HttpStatus.OK);
199 * Delete resource data in datastore pass-through running for a given cm-handle.
201 * @param resourceIdentifier resource identifier
202 * @param cmHandle cm handle identifier
203 * @param contentType content type of the body
204 * @return response entity no content if request is successful
207 public ResponseEntity<Void> deleteResourceDataRunningForCmHandle(final String cmHandle,
208 final String resourceIdentifier,
209 final String contentType) {
210 networkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle(cmHandle,
211 resourceIdentifier, DELETE, NO_BODY, contentType);
212 return new ResponseEntity<>(HttpStatus.NO_CONTENT);
216 * Query and return cm handles that match the given query parameters.
218 * @param cmHandleQueryParameters the cm handle query parameters
219 * @return collection of cm handles
222 @SuppressWarnings("deprecation") // mapOldConditionProperties method will be removed in Release 12
223 public ResponseEntity<List<RestOutputCmHandle>> searchCmHandles(
224 final CmHandleQueryParameters cmHandleQueryParameters) {
225 final CmHandleQueryApiParameters cmHandleQueryApiParameters =
226 deprecationHelper.mapOldConditionProperties(cmHandleQueryParameters);
227 final Set<NcmpServiceCmHandle> cmHandles = networkCmProxyDataService
228 .executeCmHandleSearch(cmHandleQueryApiParameters);
229 final List<RestOutputCmHandle> outputCmHandles =
230 cmHandles.stream().map(this::toRestOutputCmHandle).collect(Collectors.toList());
231 return ResponseEntity.ok(outputCmHandles);
235 * Query and return cm handle ids that match the given query parameters.
237 * @param cmHandleQueryParameters the cm handle query parameters
238 * @return collection of cm handle ids
241 public ResponseEntity<List<String>> searchCmHandleIds(
242 final CmHandleQueryParameters cmHandleQueryParameters) {
243 final CmHandleQueryApiParameters cmHandleQueryApiParameters =
244 jsonObjectMapper.convertToValueType(cmHandleQueryParameters, CmHandleQueryApiParameters.class);
245 final Set<String> cmHandleIds = networkCmProxyDataService.executeCmHandleIdSearch(cmHandleQueryApiParameters);
246 return ResponseEntity.ok(List.copyOf(cmHandleIds));
250 * Search for Cm Handle and Properties by Name.
251 * @param cmHandleId cm-handle identifier
252 * @return cm handle and its properties
255 public ResponseEntity<RestOutputCmHandle> retrieveCmHandleDetailsById(final String cmHandleId) {
256 final NcmpServiceCmHandle ncmpServiceCmHandle = networkCmProxyDataService.getNcmpServiceCmHandle(cmHandleId);
257 final RestOutputCmHandle restOutputCmHandle = toRestOutputCmHandle(ncmpServiceCmHandle);
258 return ResponseEntity.ok(restOutputCmHandle);
262 * Get Cm Handle Properties by Cm Handle Id.
263 * @param cmHandleId cm-handle identifier
264 * @return cm handle properties
267 public ResponseEntity<RestOutputCmHandlePublicProperties> getCmHandlePublicPropertiesByCmHandleId(
268 final String cmHandleId) {
269 final CmHandlePublicProperties cmHandlePublicProperties = new CmHandlePublicProperties();
270 cmHandlePublicProperties.add(networkCmProxyDataService.getCmHandlePublicProperties(cmHandleId));
271 final RestOutputCmHandlePublicProperties restOutputCmHandlePublicProperties =
272 new RestOutputCmHandlePublicProperties();
273 restOutputCmHandlePublicProperties.setPublicCmHandleProperties(cmHandlePublicProperties);
274 return ResponseEntity.ok(restOutputCmHandlePublicProperties);
278 * Get Cm Handle State by Cm Handle Id.
279 * @param cmHandleId cm-handle identifier
280 * @return cm handle state
283 public ResponseEntity<RestOutputCmHandleCompositeState> getCmHandleStateByCmHandleId(
284 final String cmHandleId) {
285 final CompositeState cmHandleState = networkCmProxyDataService.getCmHandleCompositeState(cmHandleId);
286 final RestOutputCmHandleCompositeState restOutputCmHandleCompositeState =
287 new RestOutputCmHandleCompositeState();
288 restOutputCmHandleCompositeState.setState(cmHandleStateMapper.toCmHandleCompositeState(cmHandleState));
289 return ResponseEntity.ok(restOutputCmHandleCompositeState);
293 * Return module references for a cm handle.
295 * @param cmHandle the cm handle
296 * @return module references for cm handle. Namespace will be always blank because restConf does not include this.
298 public ResponseEntity<List<RestModuleReference>> getModuleReferencesByCmHandle(final String cmHandle) {
299 final List<RestModuleReference> restModuleReferences =
300 networkCmProxyDataService.getYangResourcesModuleReferences(cmHandle).stream()
301 .map(ncmpRestInputMapper::toRestModuleReference)
302 .collect(Collectors.toList());
303 return new ResponseEntity<>(restModuleReferences, HttpStatus.OK);
306 private RestOutputCmHandle toRestOutputCmHandle(final NcmpServiceCmHandle ncmpServiceCmHandle) {
307 final RestOutputCmHandle restOutputCmHandle = new RestOutputCmHandle();
308 final CmHandlePublicProperties cmHandlePublicProperties = new CmHandlePublicProperties();
309 restOutputCmHandle.setCmHandle(ncmpServiceCmHandle.getCmHandleId());
310 cmHandlePublicProperties.add(ncmpServiceCmHandle.getPublicProperties());
311 restOutputCmHandle.setPublicCmHandleProperties(cmHandlePublicProperties);
312 restOutputCmHandle.setState(cmHandleStateMapper.toCmHandleCompositeState(
313 ncmpServiceCmHandle.getCompositeState()));
314 return restOutputCmHandle;
317 private static boolean isValidTopic(final String topicName) {
318 if (topicName == null) {
321 if (CpsValidator.validateTopicName(topicName)) {
324 throw new InvalidTopicException("Topic name " + topicName + " is invalid", "invalid topic");