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.model.AdditionalInformationDefinition;
32 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
33 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
34 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
35 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
36 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
37 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
38 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
39 import org.openecomp.sdc.be.model.operations.impl.AdditionalInformationOperation;
40 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
41 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
42 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
43 import org.openecomp.sdc.be.model.tosca.converters.StringConvertor;
44 import org.openecomp.sdc.be.model.tosca.validators.StringValidator;
45 import org.openecomp.sdc.common.log.wrappers.Logger;
46 import org.openecomp.sdc.common.util.ValidationUtils;
47 import org.openecomp.sdc.exception.ResponseFormat;
48 import org.springframework.beans.factory.annotation.Autowired;
49 import org.springframework.stereotype.Component;
51 import java.util.List;
53 @Component("additionalInformationBusinessLogic")
54 public class AdditionalInformationBusinessLogic extends BaseBusinessLogic {
56 private static final String CREATE_ADDITIONAL_INFORMATION = "CreateAdditionalInformation";
58 private static final String UPDATE_ADDITIONAL_INFORMATION = "UpdateAdditionalInformation";
60 private static final String DELETE_ADDITIONAL_INFORMATION = "DeleteAdditionalInformation";
62 private static final String GET_ADDITIONAL_INFORMATION = "GetAdditionalInformation";
64 private static final Logger log = Logger.getLogger(AdditionalInformationBusinessLogic.class.getName());
65 private static final String FAILED_TO_LOCK_COMPONENT_ERROR = "Failed to lock component {} error - {}";
67 private final AdditionalInformationOperation additionalInformationOperation;
70 public AdditionalInformationBusinessLogic(IElementOperation elementDao,
71 IGroupOperation groupOperation,
72 IGroupInstanceOperation groupInstanceOperation,
73 IGroupTypeOperation groupTypeOperation,
74 InterfaceOperation interfaceOperation,
75 InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
76 AdditionalInformationOperation additionalInformationOperation,
77 ArtifactsOperations artifactToscaOperation) {
78 super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation,
79 interfaceOperation, interfaceLifecycleTypeOperation, artifactToscaOperation);
80 this.additionalInformationOperation = additionalInformationOperation;
84 * Create new additional information on resource/service on graph
87 * @param additionalInfoParameterInfo
89 * @return Either<AdditionalInfoParameterInfo, ResponseFormat>
91 public Either<AdditionalInfoParameterInfo, ResponseFormat> createAdditionalInformation(NodeTypeEnum nodeType, String resourceId, AdditionalInfoParameterInfo additionalInfoParameterInfo, String userId) {
93 validateUserExists(userId);
94 Either<AdditionalInfoParameterInfo, ResponseFormat> result = null;
96 ResponseFormat responseFormat = verifyCanWorkOnComponent(nodeType, resourceId, userId);
97 if (responseFormat != null) {
98 result = Either.right(responseFormat);
103 StorageOperationStatus lockResult = graphLockOperation.lockComponent(resourceId, nodeType);
104 if (lockResult != StorageOperationStatus.OK) {
105 BeEcompErrorManager.getInstance().logBeFailedLockObjectError(CREATE_ADDITIONAL_INFORMATION, nodeType.getName(), resourceId);
106 log.info(FAILED_TO_LOCK_COMPONENT_ERROR, resourceId, lockResult);
107 result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
111 responseFormat = validateMaxSizeNotReached(nodeType, resourceId, additionalInfoParameterInfo);
112 if (responseFormat != null) {
113 result = Either.right(responseFormat);
118 responseFormat = validateAndConvertKey(additionalInfoParameterInfo, CREATE_ADDITIONAL_INFORMATION);
119 if (responseFormat != null) {
120 result = Either.right(responseFormat);
125 responseFormat = validateAndConvertValue(additionalInfoParameterInfo, CREATE_ADDITIONAL_INFORMATION);
126 if (responseFormat != null) {
127 result = Either.right(responseFormat);
131 Either<AdditionalInformationDefinition, StorageOperationStatus> addResult = additionalInformationOperation.createAdditionalInformationParameter(nodeType, resourceId, additionalInfoParameterInfo.getKey(),
132 additionalInfoParameterInfo.getValue(), true);
134 if (addResult.isRight()) {
135 StorageOperationStatus status = addResult.right().value();
136 BeEcompErrorManager.getInstance().logBeSystemError(CREATE_ADDITIONAL_INFORMATION);
137 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status);
138 result = Either.right(componentsUtils.getResponseFormatAdditionalProperty(actionStatus, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.Label));
142 AdditionalInformationDefinition informationDefinition = addResult.left().value();
144 AdditionalInfoParameterInfo createdAI = findAdditionInformationKey(informationDefinition.getParameters(), additionalInfoParameterInfo.getKey());
145 result = Either.left(createdAI);
150 commitOrRollback(result);
152 graphLockOperation.unlockComponent(resourceId, nodeType);
158 * Validate the value format. Format the value.
160 * @param additionalInfoParameterInfo
161 * @return null in case of success. Otherwise response format.
163 private ResponseFormat validateAndConvertValue(AdditionalInfoParameterInfo additionalInfoParameterInfo, String context) {
164 ResponseFormat result = null;
166 String value = additionalInfoParameterInfo.getValue();
167 log.debug("Going to validate additional information value {}", value);
169 Either<String, ResponseFormat> valueValidRes = validateValue(value);
170 if (valueValidRes.isRight()) {
171 BeEcompErrorManager.getInstance().logBeInvalidValueError(context, additionalInfoParameterInfo.getValue(), "additional information value", "string");
172 result = valueValidRes.right().value();
174 String newValue = valueValidRes.left().value();
175 if (log.isTraceEnabled()) {
176 if (value != null && !value.equals(newValue)) {
177 log.trace("The additional information value was normalized from {} to {}", value, newValue);
180 additionalInfoParameterInfo.setValue(newValue);
186 * @param additionalInfoParameterInfo
189 private ResponseFormat validateAndConvertKey(AdditionalInfoParameterInfo additionalInfoParameterInfo, String context) {
191 String key = additionalInfoParameterInfo.getKey();
192 log.debug("Going to validate additional information key {}", key);
194 ResponseFormat result = null;
195 ResponseFormat responseFormat;
196 Either<String, ResponseFormat> validateKeyRes = validateAndNormalizeKey(key);
197 if (validateKeyRes.isRight()) {
198 responseFormat = validateKeyRes.right().value();
199 BeEcompErrorManager.getInstance().logBeInvalidValueError(context, additionalInfoParameterInfo.getKey(), "additional information label", "string");
200 result = responseFormat;
203 String convertedKey = validateKeyRes.left().value();
205 if (log.isTraceEnabled() && key != null && !key.equals(convertedKey)) {
206 log.trace("The additional information key {} was normalized to {}", key, convertedKey);
208 additionalInfoParameterInfo.setKey(convertedKey);
214 * verify that the maximal number of additional information properties has not been reached.
218 * @param additionalInfoParameterInfo
219 * @return response format in case the maximal number has been reached.
221 private ResponseFormat validateMaxSizeNotReached(NodeTypeEnum nodeType, String componentId, AdditionalInfoParameterInfo additionalInfoParameterInfo) {
223 ResponseFormat result;
224 Integer additionalInformationMaxNumberOfKeys = ConfigurationManager.getConfigurationManager().getConfiguration().getAdditionalInformationMaxNumberOfKeys();
226 Either<Integer, StorageOperationStatus> checkRes = additionalInformationOperation.getNumberOfAdditionalInformationParameters(nodeType, componentId, true);
227 if (checkRes.isRight()) {
228 StorageOperationStatus status = checkRes.right().value();
230 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status);
231 result = componentsUtils.getResponseFormatAdditionalProperty(actionStatus, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.None);
234 Integer currentNumberOfProperties = checkRes.left().value();
235 if (currentNumberOfProperties >= additionalInformationMaxNumberOfKeys) {
236 log.info("The current number of additional information properties is {}. The maximum allowed additional information properties is {}", currentNumberOfProperties, currentNumberOfProperties);
237 result = componentsUtils.getResponseFormatAdditionalProperty(ActionStatus.ADDITIONAL_INFORMATION_MAX_NUMBER_REACHED, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.None);
245 * validate additional information value
250 private Either<String, ResponseFormat> validateValue(String value) {
252 boolean isNonEmptyString = ValidationUtils.validateStringNotEmpty(value);
253 if (!isNonEmptyString) {
254 return Either.right(componentsUtils.getResponseFormatAdditionalProperty(ActionStatus.ADDITIONAL_INFORMATION_EMPTY_STRING_NOT_ALLOWED));
257 boolean valid = StringValidator.getInstance().isValid(value, null);
259 return Either.right(componentsUtils.getResponseFormatAdditionalProperty(ActionStatus.ADDITIONAL_INFORMATION_VALUE_NOT_ALLOWED_CHARACTERS, new AdditionalInfoParameterInfo(null, value), null, AdditionalInformationEnum.Value));
262 String converted = StringConvertor.getInstance().convert(value, null, null);
264 return Either.left(converted);
267 private AdditionalInfoParameterInfo findAdditionInformationKey(List<AdditionalInfoParameterInfo> parameters, String key) {
269 for (AdditionalInfoParameterInfo infoParameterInfo : parameters) {
270 if (infoParameterInfo.getKey().equals(key)) {
271 return infoParameterInfo;
278 * validate and normalize the key
280 * @return Either<String, ResponseFormat>
282 private Either<String, ResponseFormat> validateAndNormalizeKey(String key) {
284 AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo();
285 additionalInfoParameterInfo.setKey(key);
287 String normKey = ValidationUtils.normalizeAdditionalInformation(key);
288 boolean isNonEmptyString = ValidationUtils.validateStringNotEmpty(normKey);
289 if (!isNonEmptyString) {
290 return Either.right(componentsUtils.getResponseFormatAdditionalProperty(ActionStatus.ADDITIONAL_INFORMATION_EMPTY_STRING_NOT_ALLOWED, null, null, AdditionalInformationEnum.Label));
292 boolean isValidString = ValidationUtils.validateAdditionalInformationKeyName(normKey);
293 if (!isValidString) {
294 if (!ValidationUtils.validateLength(normKey, ValidationUtils.ADDITIONAL_INFORMATION_KEY_MAX_LENGTH)) {
295 return Either.right(componentsUtils.getResponseFormatAdditionalProperty(ActionStatus.ADDITIONAL_INFORMATION_EXCEEDS_LIMIT, additionalInfoParameterInfo, null, AdditionalInformationEnum.Label));
297 return Either.right(componentsUtils.getResponseFormatAdditionalProperty(ActionStatus.ADDITIONAL_INFORMATION_KEY_NOT_ALLOWED_CHARACTERS, additionalInfoParameterInfo, null, AdditionalInformationEnum.Label));
300 return Either.left(normKey);
304 * update key and value of a given additional information.
308 * @param additionalInfoParameterInfo
312 public Either<AdditionalInfoParameterInfo, ResponseFormat> updateAdditionalInformation(NodeTypeEnum nodeType, String resourceId, AdditionalInfoParameterInfo additionalInfoParameterInfo, String userId) {
314 validateUserExists(userId);
315 Either<AdditionalInfoParameterInfo, ResponseFormat> result = null;
317 ResponseFormat responseFormat = verifyCanWorkOnComponent(nodeType, resourceId, userId);
318 if (responseFormat != null) {
319 result = Either.right(responseFormat);
323 StorageOperationStatus lockResult = graphLockOperation.lockComponent(resourceId, nodeType);
324 if (lockResult != StorageOperationStatus.OK) {
325 BeEcompErrorManager.getInstance().logBeFailedLockObjectError(UPDATE_ADDITIONAL_INFORMATION, nodeType.getName(), resourceId);
326 log.info(FAILED_TO_LOCK_COMPONENT_ERROR, resourceId, lockResult);
327 result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
333 responseFormat = validateAndConvertKey(additionalInfoParameterInfo, UPDATE_ADDITIONAL_INFORMATION);
334 if (responseFormat != null) {
335 result = Either.right(responseFormat);
339 responseFormat = validateAndConvertValue(additionalInfoParameterInfo, UPDATE_ADDITIONAL_INFORMATION);
340 if (responseFormat != null) {
341 result = Either.right(responseFormat);
345 Either<AdditionalInformationDefinition, StorageOperationStatus> addResult = additionalInformationOperation.updateAdditionalInformationParameter(nodeType, resourceId, additionalInfoParameterInfo.getUniqueId(),
346 additionalInfoParameterInfo.getKey(), additionalInfoParameterInfo.getValue(), true);
348 if (addResult.isRight()) {
349 StorageOperationStatus status = addResult.right().value();
350 BeEcompErrorManager.getInstance().logBeSystemError(UPDATE_ADDITIONAL_INFORMATION);
351 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status);
352 result = Either.right(componentsUtils.getResponseFormatAdditionalProperty(actionStatus, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.None));
355 AdditionalInformationDefinition informationDefinition = addResult.left().value();
356 AdditionalInfoParameterInfo parameterInfo = findAdditionInformationKey(informationDefinition.getParameters(), additionalInfoParameterInfo.getKey());
357 result = Either.left(parameterInfo);
362 commitOrRollback(result);
364 graphLockOperation.unlockComponent(resourceId, nodeType);
370 * Delete an additional information label
374 * @param additionalInfoParameterInfo
378 public Either<AdditionalInfoParameterInfo, ResponseFormat> deleteAdditionalInformation(NodeTypeEnum nodeType, String resourceId, AdditionalInfoParameterInfo additionalInfoParameterInfo, String userId) {
380 validateUserExists(userId);
381 Either<AdditionalInfoParameterInfo, ResponseFormat> result = null;
383 ResponseFormat responseFormat = verifyCanWorkOnComponent(nodeType, resourceId, userId);
384 if (responseFormat != null) {
385 return Either.right(responseFormat);
388 StorageOperationStatus lockResult = graphLockOperation.lockComponent(resourceId, nodeType);
389 if (lockResult != StorageOperationStatus.OK) {
390 BeEcompErrorManager.getInstance().logBeFailedLockObjectError(DELETE_ADDITIONAL_INFORMATION, nodeType.getName(), resourceId);
391 log.info(FAILED_TO_LOCK_COMPONENT_ERROR, resourceId, lockResult);
392 result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
398 Either<AdditionalInfoParameterInfo, StorageOperationStatus> findIdRes = additionalInformationOperation.getAdditionalInformationParameter(nodeType, resourceId, additionalInfoParameterInfo.getUniqueId(), true);
399 if (findIdRes.isRight()) {
400 StorageOperationStatus status = findIdRes.right().value();
401 if (status != StorageOperationStatus.NOT_FOUND) {
402 BeEcompErrorManager.getInstance().logBeSystemError(GET_ADDITIONAL_INFORMATION);
404 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status);
405 result = Either.right(componentsUtils.getResponseFormatAdditionalProperty(actionStatus, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.None));
409 AdditionalInfoParameterInfo foundAdditionalInfo = findIdRes.left().value();
411 Either<AdditionalInformationDefinition, StorageOperationStatus> addResult = additionalInformationOperation.deleteAdditionalInformationParameter(nodeType, resourceId, additionalInfoParameterInfo.getUniqueId(), true);
413 if (addResult.isRight()) {
414 StorageOperationStatus status = addResult.right().value();
415 BeEcompErrorManager.getInstance().logBeDaoSystemError(DELETE_ADDITIONAL_INFORMATION);
416 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status);
417 result = Either.right(componentsUtils.getResponseFormatAdditionalProperty(actionStatus, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.None));
420 result = Either.left(foundAdditionalInfo);
425 commitOrRollback(result);
427 graphLockOperation.unlockComponent(resourceId, nodeType);
435 * @param additionalInfoParameterInfo
439 public Either<AdditionalInfoParameterInfo, ResponseFormat> getAdditionalInformation(NodeTypeEnum nodeType, String resourceId, AdditionalInfoParameterInfo additionalInfoParameterInfo, String userId) {
441 validateUserExists(userId);
442 Either<AdditionalInfoParameterInfo, ResponseFormat> result = null;
446 Either<AdditionalInfoParameterInfo, StorageOperationStatus> findIdRes = additionalInformationOperation.getAdditionalInformationParameter(nodeType, resourceId, additionalInfoParameterInfo.getUniqueId(), true);
448 if (findIdRes.isRight()) {
449 StorageOperationStatus status = findIdRes.right().value();
450 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status);
451 result = Either.right(componentsUtils.getResponseFormatAdditionalProperty(actionStatus, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.None));
454 AdditionalInfoParameterInfo foundAdditionalInfo = findIdRes.left().value();
456 result = Either.left(foundAdditionalInfo);
461 commitOrRollback(result);
467 * Get all additional information properties of a given resource/service
474 public Either<AdditionalInformationDefinition, ResponseFormat> getAllAdditionalInformation(NodeTypeEnum nodeType, String resourceId, String userId) {
476 validateUserExists(userId);
478 Either<AdditionalInformationDefinition, ResponseFormat> result = null;
482 Either<AdditionalInformationDefinition, JanusGraphOperationStatus> findIdRes = additionalInformationOperation.getAllAdditionalInformationParameters(nodeType, resourceId, false);
483 if (findIdRes.isRight()) {
484 StorageOperationStatus status = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(findIdRes.right().value());
485 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status);
486 result = Either.right(componentsUtils.getResponseFormatAdditionalProperty(actionStatus));
488 AdditionalInformationDefinition informationDefinition = findIdRes.left().value();
489 result = Either.left(informationDefinition);
495 commitOrRollback(result);
500 private ResponseFormat verifyCanWorkOnComponent(NodeTypeEnum nodeType, String resourceId, String userId) {
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);
513 // verify that resource is checked-out and the user is the last
515 if (!ComponentValidationUtils.canWorkOnComponent(resourceId, toscaOperationFacade, userId)) {
516 return componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
520 return componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT, nodeType.getName());