2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.sdc.be.components.impl;
23 import fj.data.Either;
24 import org.openecomp.sdc.be.config.BeEcompErrorManager;
25 import org.openecomp.sdc.be.config.ConfigurationManager;
26 import org.openecomp.sdc.be.dao.api.ActionStatus;
27 import org.openecomp.sdc.be.dao.graph.datatype.AdditionalInformationEnum;
28 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
29 import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterInfo;
30 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
31 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
32 import org.openecomp.sdc.be.model.AdditionalInformationDefinition;
33 import org.openecomp.sdc.be.model.operations.api.IAdditionalInformationOperation;
34 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
35 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
36 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
37 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
38 import org.openecomp.sdc.be.model.tosca.converters.StringConvertor;
39 import org.openecomp.sdc.be.model.tosca.validators.StringValidator;
40 import org.openecomp.sdc.common.api.Constants;
41 import org.openecomp.sdc.common.log.wrappers.Logger;
42 import org.openecomp.sdc.common.util.ValidationUtils;
43 import org.openecomp.sdc.exception.ResponseFormat;
44 import org.springframework.stereotype.Component;
45 import org.springframework.web.context.WebApplicationContext;
47 import javax.servlet.ServletContext;
48 import java.util.List;
50 @Component("additionalInformationBusinessLogic")
51 public class AdditionalInformationBusinessLogic extends BaseBusinessLogic {
53 private static final String CREATE_ADDITIONAL_INFORMATION = "CreateAdditionalInformation";
55 private static final String UPDATE_ADDITIONAL_INFORMATION = "UpdateAdditionalInformation";
57 private static final String DELETE_ADDITIONAL_INFORMATION = "DeleteAdditionalInformation";
59 private static final String GET_ADDITIONAL_INFORMATION = "GetAdditionalInformation";
61 private static final Logger log = Logger.getLogger(AdditionalInformationBusinessLogic.class.getName());
62 private static final String FAILED_TO_LOCK_COMPONENT_ERROR = "Failed to lock component {} error - {}";
64 @javax.annotation.Resource
65 private IAdditionalInformationOperation additionalInformationOperation = null;
67 protected static IElementOperation getElementDao(Class<IElementOperation> class1, ServletContext context) {
68 WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
70 WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
72 return webApplicationContext.getBean(class1);
76 * Create new additional information on resource/service on graph
79 * @param additionalInfoParameterInfo
81 * @return Either<AdditionalInfoParameterInfo, ResponseFormat>
83 public Either<AdditionalInfoParameterInfo, ResponseFormat> createAdditionalInformation(NodeTypeEnum nodeType, String resourceId, AdditionalInfoParameterInfo additionalInfoParameterInfo, String userId) {
85 validateUserExists(userId, "create Additional Information", false);
86 Either<AdditionalInfoParameterInfo, ResponseFormat> result = null;
88 ResponseFormat responseFormat = verifyCanWorkOnComponent(nodeType, resourceId, userId);
89 if (responseFormat != null) {
90 result = Either.right(responseFormat);
95 StorageOperationStatus lockResult = graphLockOperation.lockComponent(resourceId, nodeType);
96 if (!lockResult.equals(StorageOperationStatus.OK)) {
97 BeEcompErrorManager.getInstance().logBeFailedLockObjectError(CREATE_ADDITIONAL_INFORMATION, nodeType.getName(), resourceId);
98 log.info(FAILED_TO_LOCK_COMPONENT_ERROR, resourceId, lockResult);
99 result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
103 responseFormat = validateMaxSizeNotReached(nodeType, resourceId, additionalInfoParameterInfo);
104 if (responseFormat != null) {
105 result = Either.right(responseFormat);
110 responseFormat = validateAndConvertKey(additionalInfoParameterInfo, CREATE_ADDITIONAL_INFORMATION);
111 if (responseFormat != null) {
112 result = Either.right(responseFormat);
117 responseFormat = validateAndConvertValue(additionalInfoParameterInfo, CREATE_ADDITIONAL_INFORMATION);
118 if (responseFormat != null) {
119 result = Either.right(responseFormat);
123 Either<AdditionalInformationDefinition, StorageOperationStatus> addResult = additionalInformationOperation.createAdditionalInformationParameter(nodeType, resourceId, additionalInfoParameterInfo.getKey(),
124 additionalInfoParameterInfo.getValue(), true);
126 if (addResult.isRight()) {
127 StorageOperationStatus status = addResult.right().value();
128 BeEcompErrorManager.getInstance().logBeSystemError(CREATE_ADDITIONAL_INFORMATION);
129 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status);
130 result = Either.right(componentsUtils.getResponseFormatAdditionalProperty(actionStatus, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.Label));
134 AdditionalInformationDefinition informationDefinition = addResult.left().value();
136 AdditionalInfoParameterInfo createdAI = findAdditionInformationKey(informationDefinition.getParameters(), additionalInfoParameterInfo.getKey());
137 result = Either.left(createdAI);
142 commitOrRollback(result);
144 graphLockOperation.unlockComponent(resourceId, nodeType);
150 * Validate the value format. Format the value.
152 * @param additionalInfoParameterInfo
153 * @return null in case of success. Otherwise response format.
155 private ResponseFormat validateAndConvertValue(AdditionalInfoParameterInfo additionalInfoParameterInfo, String context) {
156 ResponseFormat result = null;
158 String value = additionalInfoParameterInfo.getValue();
159 log.debug("Going to validate additional information value {}", value);
161 Either<String, ResponseFormat> valueValidRes = validateValue(value);
162 if (valueValidRes.isRight()) {
163 BeEcompErrorManager.getInstance().logBeInvalidValueError(context, additionalInfoParameterInfo.getValue(), "additional information value", "string");
164 result = valueValidRes.right().value();
166 String newValue = valueValidRes.left().value();
167 if (log.isTraceEnabled()) {
168 if (value != null && !value.equals(newValue)) {
169 log.trace("The additional information value was normalized from {} to {}", value, newValue);
172 additionalInfoParameterInfo.setValue(newValue);
178 * @param additionalInfoParameterInfo
181 private ResponseFormat validateAndConvertKey(AdditionalInfoParameterInfo additionalInfoParameterInfo, String context) {
183 String key = additionalInfoParameterInfo.getKey();
184 log.debug("Going to validate additional information key {}", key);
186 ResponseFormat result = null;
187 ResponseFormat responseFormat;
188 Either<String, ResponseFormat> validateKeyRes = validateAndNormalizeKey(key);
189 if (validateKeyRes.isRight()) {
190 responseFormat = validateKeyRes.right().value();
191 BeEcompErrorManager.getInstance().logBeInvalidValueError(context, additionalInfoParameterInfo.getKey(), "additional information label", "string");
192 result = responseFormat;
195 String convertedKey = validateKeyRes.left().value();
197 if (log.isTraceEnabled() && key != null && !key.equals(convertedKey)) {
198 log.trace("The additional information key {} was normalized to {}", key, convertedKey);
200 additionalInfoParameterInfo.setKey(convertedKey);
206 * verify that the maximal number of additional information properties has not been reached.
210 * @param additionalInfoParameterInfo
211 * @return response format in case the maximal number has been reached.
213 private ResponseFormat validateMaxSizeNotReached(NodeTypeEnum nodeType, String componentId, AdditionalInfoParameterInfo additionalInfoParameterInfo) {
215 ResponseFormat result;
216 Integer additionalInformationMaxNumberOfKeys = ConfigurationManager.getConfigurationManager().getConfiguration().getAdditionalInformationMaxNumberOfKeys();
218 Either<Integer, StorageOperationStatus> checkRes = additionalInformationOperation.getNumberOfAdditionalInformationParameters(nodeType, componentId, true);
219 if (checkRes.isRight()) {
220 StorageOperationStatus status = checkRes.right().value();
222 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status);
223 result = componentsUtils.getResponseFormatAdditionalProperty(actionStatus, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.None);
226 Integer currentNumberOfProperties = checkRes.left().value();
227 if (currentNumberOfProperties >= additionalInformationMaxNumberOfKeys) {
228 log.info("The current number of additional information properties is {}. The maximum allowed additional information properties is {}", currentNumberOfProperties, currentNumberOfProperties);
229 result = componentsUtils.getResponseFormatAdditionalProperty(ActionStatus.ADDITIONAL_INFORMATION_MAX_NUMBER_REACHED, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.None);
237 * validate additional information value
242 private Either<String, ResponseFormat> validateValue(String value) {
244 boolean isNonEmptyString = ValidationUtils.validateStringNotEmpty(value);
245 if (!isNonEmptyString) {
246 return Either.right(componentsUtils.getResponseFormatAdditionalProperty(ActionStatus.ADDITIONAL_INFORMATION_EMPTY_STRING_NOT_ALLOWED));
249 boolean valid = StringValidator.getInstance().isValid(value, null);
251 return Either.right(componentsUtils.getResponseFormatAdditionalProperty(ActionStatus.ADDITIONAL_INFORMATION_VALUE_NOT_ALLOWED_CHARACTERS, new AdditionalInfoParameterInfo(null, value), null, AdditionalInformationEnum.Value));
254 String converted = StringConvertor.getInstance().convert(value, null, null);
256 return Either.left(converted);
259 private AdditionalInfoParameterInfo findAdditionInformationKey(List<AdditionalInfoParameterInfo> parameters, String key) {
261 for (AdditionalInfoParameterInfo infoParameterInfo : parameters) {
262 if (infoParameterInfo.getKey().equals(key)) {
263 return infoParameterInfo;
270 * validate and normalize the key
272 * @return Either<String, ResponseFormat>
274 private Either<String, ResponseFormat> validateAndNormalizeKey(String key) {
276 AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo();
277 additionalInfoParameterInfo.setKey(key);
279 String normKey = ValidationUtils.normalizeAdditionalInformation(key);
280 boolean isNonEmptyString = ValidationUtils.validateStringNotEmpty(normKey);
281 if (!isNonEmptyString) {
282 return Either.right(componentsUtils.getResponseFormatAdditionalProperty(ActionStatus.ADDITIONAL_INFORMATION_EMPTY_STRING_NOT_ALLOWED, null, null, AdditionalInformationEnum.Label));
284 boolean isValidString = ValidationUtils.validateAdditionalInformationKeyName(normKey);
285 if (!isValidString) {
286 if (!ValidationUtils.validateLength(normKey, ValidationUtils.ADDITIONAL_INFORMATION_KEY_MAX_LENGTH)) {
287 return Either.right(componentsUtils.getResponseFormatAdditionalProperty(ActionStatus.ADDITIONAL_INFORMATION_EXCEEDS_LIMIT, additionalInfoParameterInfo, null, AdditionalInformationEnum.Label));
289 return Either.right(componentsUtils.getResponseFormatAdditionalProperty(ActionStatus.ADDITIONAL_INFORMATION_KEY_NOT_ALLOWED_CHARACTERS, additionalInfoParameterInfo, null, AdditionalInformationEnum.Label));
292 return Either.left(normKey);
296 * update key and value of a given additional information.
300 * @param additionalInfoParameterInfo
304 public Either<AdditionalInfoParameterInfo, ResponseFormat> updateAdditionalInformation(NodeTypeEnum nodeType, String resourceId, AdditionalInfoParameterInfo additionalInfoParameterInfo, String userId) {
306 validateUserExists(userId, "create Additional Information", false);
307 Either<AdditionalInfoParameterInfo, ResponseFormat> result = null;
309 ResponseFormat responseFormat = verifyCanWorkOnComponent(nodeType, resourceId, userId);
310 if (responseFormat != null) {
311 result = Either.right(responseFormat);
315 StorageOperationStatus lockResult = graphLockOperation.lockComponent(resourceId, nodeType);
316 if (!lockResult.equals(StorageOperationStatus.OK)) {
317 BeEcompErrorManager.getInstance().logBeFailedLockObjectError(UPDATE_ADDITIONAL_INFORMATION, nodeType.getName(), resourceId);
318 log.info(FAILED_TO_LOCK_COMPONENT_ERROR, resourceId, lockResult);
319 result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
325 responseFormat = validateAndConvertKey(additionalInfoParameterInfo, UPDATE_ADDITIONAL_INFORMATION);
326 if (responseFormat != null) {
327 result = Either.right(responseFormat);
331 responseFormat = validateAndConvertValue(additionalInfoParameterInfo, UPDATE_ADDITIONAL_INFORMATION);
332 if (responseFormat != null) {
333 result = Either.right(responseFormat);
337 Either<AdditionalInformationDefinition, StorageOperationStatus> addResult = additionalInformationOperation.updateAdditionalInformationParameter(nodeType, resourceId, additionalInfoParameterInfo.getUniqueId(),
338 additionalInfoParameterInfo.getKey(), additionalInfoParameterInfo.getValue(), true);
340 if (addResult.isRight()) {
341 StorageOperationStatus status = addResult.right().value();
342 BeEcompErrorManager.getInstance().logBeSystemError(UPDATE_ADDITIONAL_INFORMATION);
343 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status);
344 result = Either.right(componentsUtils.getResponseFormatAdditionalProperty(actionStatus, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.None));
347 AdditionalInformationDefinition informationDefinition = addResult.left().value();
348 AdditionalInfoParameterInfo parameterInfo = findAdditionInformationKey(informationDefinition.getParameters(), additionalInfoParameterInfo.getKey());
349 result = Either.left(parameterInfo);
354 commitOrRollback(result);
356 graphLockOperation.unlockComponent(resourceId, nodeType);
362 * Delete an additional information label
366 * @param additionalInfoParameterInfo
370 public Either<AdditionalInfoParameterInfo, ResponseFormat> deleteAdditionalInformation(NodeTypeEnum nodeType, String resourceId, AdditionalInfoParameterInfo additionalInfoParameterInfo, String userId) {
372 validateUserExists(userId, "delete Additional Information", false);
373 Either<AdditionalInfoParameterInfo, ResponseFormat> result = null;
375 ResponseFormat responseFormat = verifyCanWorkOnComponent(nodeType, resourceId, userId);
376 if (responseFormat != null) {
377 return Either.right(responseFormat);
380 StorageOperationStatus lockResult = graphLockOperation.lockComponent(resourceId, nodeType);
381 if (!lockResult.equals(StorageOperationStatus.OK)) {
382 BeEcompErrorManager.getInstance().logBeFailedLockObjectError(DELETE_ADDITIONAL_INFORMATION, nodeType.getName(), resourceId);
383 log.info(FAILED_TO_LOCK_COMPONENT_ERROR, resourceId, lockResult);
384 result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
390 Either<AdditionalInfoParameterInfo, StorageOperationStatus> findIdRes = additionalInformationOperation.getAdditionalInformationParameter(nodeType, resourceId, additionalInfoParameterInfo.getUniqueId(), true);
391 if (findIdRes.isRight()) {
392 StorageOperationStatus status = findIdRes.right().value();
393 if (status != StorageOperationStatus.NOT_FOUND) {
394 BeEcompErrorManager.getInstance().logBeSystemError(GET_ADDITIONAL_INFORMATION);
396 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status);
397 result = Either.right(componentsUtils.getResponseFormatAdditionalProperty(actionStatus, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.None));
401 AdditionalInfoParameterInfo foundAdditionalInfo = findIdRes.left().value();
403 Either<AdditionalInformationDefinition, StorageOperationStatus> addResult = additionalInformationOperation.deleteAdditionalInformationParameter(nodeType, resourceId, additionalInfoParameterInfo.getUniqueId(), true);
405 if (addResult.isRight()) {
406 StorageOperationStatus status = addResult.right().value();
407 BeEcompErrorManager.getInstance().logBeDaoSystemError(DELETE_ADDITIONAL_INFORMATION);
408 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status);
409 result = Either.right(componentsUtils.getResponseFormatAdditionalProperty(actionStatus, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.None));
412 result = Either.left(foundAdditionalInfo);
417 commitOrRollback(result);
419 graphLockOperation.unlockComponent(resourceId, nodeType);
427 * @param additionalInfoParameterInfo
431 public Either<AdditionalInfoParameterInfo, ResponseFormat> getAdditionalInformation(NodeTypeEnum nodeType, String resourceId, AdditionalInfoParameterInfo additionalInfoParameterInfo, String userId) {
433 validateUserExists(userId, "get Additional Information", false);
434 Either<AdditionalInfoParameterInfo, ResponseFormat> result = null;
438 Either<AdditionalInfoParameterInfo, StorageOperationStatus> findIdRes = additionalInformationOperation.getAdditionalInformationParameter(nodeType, resourceId, additionalInfoParameterInfo.getUniqueId(), true);
440 if (findIdRes.isRight()) {
441 StorageOperationStatus status = findIdRes.right().value();
442 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status);
443 result = Either.right(componentsUtils.getResponseFormatAdditionalProperty(actionStatus, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.None));
446 AdditionalInfoParameterInfo foundAdditionalInfo = findIdRes.left().value();
448 result = Either.left(foundAdditionalInfo);
453 commitOrRollback(result);
459 * Get all additional information properties of a given resource/service
466 public Either<AdditionalInformationDefinition, ResponseFormat> getAllAdditionalInformation(NodeTypeEnum nodeType, String resourceId, String userId) {
468 validateUserExists(userId, "get All Additional Information", false);
470 Either<AdditionalInformationDefinition, ResponseFormat> result = null;
474 Either<AdditionalInformationDefinition, JanusGraphOperationStatus> findIdRes = additionalInformationOperation.getAllAdditionalInformationParameters(nodeType, resourceId, false);
475 if (findIdRes.isRight()) {
476 StorageOperationStatus status = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(findIdRes.right().value());
477 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status);
478 result = Either.right(componentsUtils.getResponseFormatAdditionalProperty(actionStatus));
480 AdditionalInformationDefinition informationDefinition = findIdRes.left().value();
481 result = Either.left(informationDefinition);
487 commitOrRollback(result);
492 private ResponseFormat verifyCanWorkOnComponent(NodeTypeEnum nodeType, String resourceId, String userId) {
497 // verify that resource is checked-out and the user is the last
499 if (!ComponentValidationUtils.canWorkOnComponent(resourceId, toscaOperationFacade, userId)) {
500 return componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
505 // verify that resource is checked-out and the user is the last
507 if (!ComponentValidationUtils.canWorkOnComponent(resourceId, toscaOperationFacade, userId)) {
508 return componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
512 return componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT, nodeType.getName());