c3efa610fcc7e763f1fd8d4a4a43586b62af29e9
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / AdditionalInformationBusinessLogic.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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=========================================================
19  */
20 package org.openecomp.sdc.be.components.impl;
21
22 import fj.data.Either;
23 import java.util.List;
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;
50
51 @Component("additionalInformationBusinessLogic")
52 public class AdditionalInformationBusinessLogic extends BaseBusinessLogic {
53
54     private static final String CREATE_ADDITIONAL_INFORMATION = "CreateAdditionalInformation";
55     private static final String UPDATE_ADDITIONAL_INFORMATION = "UpdateAdditionalInformation";
56     private static final String DELETE_ADDITIONAL_INFORMATION = "DeleteAdditionalInformation";
57     private static final String GET_ADDITIONAL_INFORMATION = "GetAdditionalInformation";
58     private static final Logger log = Logger.getLogger(AdditionalInformationBusinessLogic.class.getName());
59     private static final String FAILED_TO_LOCK_COMPONENT_ERROR = "Failed to lock component {} error - {}";
60     private final AdditionalInformationOperation additionalInformationOperation;
61
62     @Autowired
63     public AdditionalInformationBusinessLogic(IElementOperation elementDao, IGroupOperation groupOperation,
64                                               IGroupInstanceOperation groupInstanceOperation, IGroupTypeOperation groupTypeOperation,
65                                               InterfaceOperation interfaceOperation, InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
66                                               AdditionalInformationOperation additionalInformationOperation,
67                                               ArtifactsOperations artifactToscaOperation) {
68         super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation,
69             artifactToscaOperation);
70         this.additionalInformationOperation = additionalInformationOperation;
71     }
72
73     /**
74      * Create new additional information on resource/service on graph
75      *
76      * @param nodeType
77      * @param resourceId
78      * @param additionalInfoParameterInfo
79      * @param userId
80      * @return Either<AdditionalInfoParameterInfo, ResponseFormat>
81      */
82     public Either<AdditionalInfoParameterInfo, ResponseFormat> createAdditionalInformation(NodeTypeEnum nodeType, String resourceId,
83                                                                                            AdditionalInfoParameterInfo additionalInfoParameterInfo,
84                                                                                            String userId) {
85         validateUserExists(userId);
86         Either<AdditionalInfoParameterInfo, ResponseFormat> result = null;
87         ResponseFormat responseFormat = verifyCanWorkOnComponent(nodeType, resourceId, userId);
88         if (responseFormat != null) {
89             result = Either.right(responseFormat);
90             return result;
91         }
92         // lock component
93         StorageOperationStatus lockResult = graphLockOperation.lockComponent(resourceId, nodeType);
94         if (lockResult != StorageOperationStatus.OK) {
95             BeEcompErrorManager.getInstance().logBeFailedLockObjectError(CREATE_ADDITIONAL_INFORMATION, nodeType.getName(), resourceId);
96             log.info(FAILED_TO_LOCK_COMPONENT_ERROR, resourceId, lockResult);
97             result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
98             return result;
99         }
100         try {
101             responseFormat = validateMaxSizeNotReached(nodeType, resourceId, additionalInfoParameterInfo);
102             if (responseFormat != null) {
103                 result = Either.right(responseFormat);
104                 return result;
105             }
106             // validate label
107             responseFormat = validateAndConvertKey(additionalInfoParameterInfo, CREATE_ADDITIONAL_INFORMATION);
108             if (responseFormat != null) {
109                 result = Either.right(responseFormat);
110                 return result;
111             }
112             // validate value
113             responseFormat = validateAndConvertValue(additionalInfoParameterInfo, CREATE_ADDITIONAL_INFORMATION);
114             if (responseFormat != null) {
115                 result = Either.right(responseFormat);
116                 return result;
117             }
118             Either<AdditionalInformationDefinition, StorageOperationStatus> addResult = additionalInformationOperation
119                 .createAdditionalInformationParameter(nodeType, resourceId, additionalInfoParameterInfo.getKey(),
120                     additionalInfoParameterInfo.getValue(), true);
121             if (addResult.isRight()) {
122                 StorageOperationStatus status = addResult.right().value();
123                 BeEcompErrorManager.getInstance().logBeSystemError(CREATE_ADDITIONAL_INFORMATION);
124                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status);
125                 result = Either.right(componentsUtils
126                     .getResponseFormatAdditionalProperty(actionStatus, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.Label));
127                 return result;
128             } else {
129                 AdditionalInformationDefinition informationDefinition = addResult.left().value();
130                 AdditionalInfoParameterInfo createdAI = findAdditionInformationKey(informationDefinition.getParameters(),
131                     additionalInfoParameterInfo.getKey());
132                 result = Either.left(createdAI);
133                 return result;
134             }
135         } finally {
136             commitOrRollback(result);
137             // unlock component
138             graphLockOperation.unlockComponent(resourceId, nodeType);
139         }
140     }
141
142     /**
143      * Validate the value format. Format the value.
144      *
145      * @param additionalInfoParameterInfo
146      * @return null in case of success. Otherwise response format.
147      */
148     private ResponseFormat validateAndConvertValue(AdditionalInfoParameterInfo additionalInfoParameterInfo, String context) {
149         ResponseFormat result = null;
150         String value = additionalInfoParameterInfo.getValue();
151         log.debug("Going to validate additional information value {}", value);
152         Either<String, ResponseFormat> valueValidRes = validateValue(value);
153         if (valueValidRes.isRight()) {
154             BeEcompErrorManager.getInstance()
155                 .logBeInvalidValueError(context, additionalInfoParameterInfo.getValue(), "additional information value", "string");
156             result = valueValidRes.right().value();
157         } else {
158             String newValue = valueValidRes.left().value();
159             if (log.isTraceEnabled()) {
160                 if (value != null && !value.equals(newValue)) {
161                     log.trace("The additional information value was normalized from {} to {}", value, newValue);
162                 }
163             }
164             additionalInfoParameterInfo.setValue(newValue);
165         }
166         return result;
167     }
168
169     /**
170      * @param additionalInfoParameterInfo
171      * @return
172      */
173     private ResponseFormat validateAndConvertKey(AdditionalInfoParameterInfo additionalInfoParameterInfo, String context) {
174         String key = additionalInfoParameterInfo.getKey();
175         log.debug("Going to validate additional information key {}", key);
176         ResponseFormat result = null;
177         ResponseFormat responseFormat;
178         Either<String, ResponseFormat> validateKeyRes = validateAndNormalizeKey(key);
179         if (validateKeyRes.isRight()) {
180             responseFormat = validateKeyRes.right().value();
181             BeEcompErrorManager.getInstance()
182                 .logBeInvalidValueError(context, additionalInfoParameterInfo.getKey(), "additional information label", "string");
183             result = responseFormat;
184         } else {
185             String convertedKey = validateKeyRes.left().value();
186             if (log.isTraceEnabled() && key != null && !key.equals(convertedKey)) {
187                 log.trace("The additional information key {} was normalized to {}", key, convertedKey);
188             }
189             additionalInfoParameterInfo.setKey(convertedKey);
190         }
191         return result;
192     }
193
194     /**
195      * verify that the maximal number of additional information properties has not been reached.
196      *
197      * @param nodeType
198      * @param componentId
199      * @param additionalInfoParameterInfo
200      * @return response format in case the maximal number has been reached.
201      */
202     private ResponseFormat validateMaxSizeNotReached(NodeTypeEnum nodeType, String componentId,
203                                                      AdditionalInfoParameterInfo additionalInfoParameterInfo) {
204         ResponseFormat result;
205         Integer additionalInformationMaxNumberOfKeys = ConfigurationManager.getConfigurationManager().getConfiguration()
206             .getAdditionalInformationMaxNumberOfKeys();
207         Either<Integer, StorageOperationStatus> checkRes = additionalInformationOperation
208             .getNumberOfAdditionalInformationParameters(nodeType, componentId, true);
209         if (checkRes.isRight()) {
210             StorageOperationStatus status = checkRes.right().value();
211             ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status);
212             result = componentsUtils
213                 .getResponseFormatAdditionalProperty(actionStatus, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.None);
214             return result;
215         }
216         Integer currentNumberOfProperties = checkRes.left().value();
217         if (currentNumberOfProperties >= additionalInformationMaxNumberOfKeys) {
218             log.info("The current number of additional information properties is {}. The maximum allowed additional information properties is {}",
219                 currentNumberOfProperties, currentNumberOfProperties);
220             result = componentsUtils
221                 .getResponseFormatAdditionalProperty(ActionStatus.ADDITIONAL_INFORMATION_MAX_NUMBER_REACHED, additionalInfoParameterInfo, nodeType,
222                     AdditionalInformationEnum.None);
223             return result;
224         }
225         return null;
226     }
227
228     /**
229      * validate additional information value
230      *
231      * @param value
232      * @return
233      */
234     private Either<String, ResponseFormat> validateValue(String value) {
235         boolean isNonEmptyString = ValidationUtils.validateStringNotEmpty(value);
236         if (!isNonEmptyString) {
237             return Either.right(componentsUtils.getResponseFormatAdditionalProperty(ActionStatus.ADDITIONAL_INFORMATION_EMPTY_STRING_NOT_ALLOWED));
238         }
239         boolean valid = StringValidator.getInstance().isValid(value, null);
240         if (!valid) {
241             return Either.right(componentsUtils.getResponseFormatAdditionalProperty(ActionStatus.ADDITIONAL_INFORMATION_VALUE_NOT_ALLOWED_CHARACTERS,
242                 new AdditionalInfoParameterInfo(null, value), null, AdditionalInformationEnum.Value));
243         }
244         String converted = StringConvertor.getInstance().convert(value, null, null);
245         return Either.left(converted);
246     }
247
248     private AdditionalInfoParameterInfo findAdditionInformationKey(List<AdditionalInfoParameterInfo> parameters, String key) {
249         for (AdditionalInfoParameterInfo infoParameterInfo : parameters) {
250             if (infoParameterInfo.getKey().equals(key)) {
251                 return infoParameterInfo;
252             }
253         }
254         return null;
255     }
256
257     /**
258      * validate and normalize the key
259      *
260      * @param key
261      * @return Either<String, ResponseFormat>
262      */
263     private Either<String, ResponseFormat> validateAndNormalizeKey(String key) {
264         AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo();
265         additionalInfoParameterInfo.setKey(key);
266         String normKey = ValidationUtils.normalizeAdditionalInformation(key);
267         boolean isNonEmptyString = ValidationUtils.validateStringNotEmpty(normKey);
268         if (!isNonEmptyString) {
269             return Either.right(componentsUtils
270                 .getResponseFormatAdditionalProperty(ActionStatus.ADDITIONAL_INFORMATION_EMPTY_STRING_NOT_ALLOWED, null, null,
271                     AdditionalInformationEnum.Label));
272         }
273         boolean isValidString = ValidationUtils.validateAdditionalInformationKeyName(normKey);
274         if (!isValidString) {
275             if (!ValidationUtils.validateLength(normKey, ValidationUtils.ADDITIONAL_INFORMATION_KEY_MAX_LENGTH)) {
276                 return Either.right(componentsUtils
277                     .getResponseFormatAdditionalProperty(ActionStatus.ADDITIONAL_INFORMATION_EXCEEDS_LIMIT, additionalInfoParameterInfo, null,
278                         AdditionalInformationEnum.Label));
279             }
280             return Either.right(componentsUtils
281                 .getResponseFormatAdditionalProperty(ActionStatus.ADDITIONAL_INFORMATION_KEY_NOT_ALLOWED_CHARACTERS, additionalInfoParameterInfo,
282                     null, AdditionalInformationEnum.Label));
283         }
284         return Either.left(normKey);
285     }
286
287     /**
288      * update key and value of a given additional information.
289      *
290      * @param nodeType
291      * @param resourceId
292      * @param additionalInfoParameterInfo
293      * @param userId
294      * @return
295      */
296     public Either<AdditionalInfoParameterInfo, ResponseFormat> updateAdditionalInformation(NodeTypeEnum nodeType, String resourceId,
297                                                                                            AdditionalInfoParameterInfo additionalInfoParameterInfo,
298                                                                                            String userId) {
299         validateUserExists(userId);
300         Either<AdditionalInfoParameterInfo, ResponseFormat> result = null;
301         ResponseFormat responseFormat = verifyCanWorkOnComponent(nodeType, resourceId, userId);
302         if (responseFormat != null) {
303             result = Either.right(responseFormat);
304             return result;
305         }
306         // lock component
307         StorageOperationStatus lockResult = graphLockOperation.lockComponent(resourceId, nodeType);
308         if (lockResult != StorageOperationStatus.OK) {
309             BeEcompErrorManager.getInstance().logBeFailedLockObjectError(UPDATE_ADDITIONAL_INFORMATION, nodeType.getName(), resourceId);
310             log.info(FAILED_TO_LOCK_COMPONENT_ERROR, resourceId, lockResult);
311             result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
312             return result;
313         }
314         try {
315             // validate input
316             responseFormat = validateAndConvertKey(additionalInfoParameterInfo, UPDATE_ADDITIONAL_INFORMATION);
317             if (responseFormat != null) {
318                 result = Either.right(responseFormat);
319                 return result;
320             }
321             responseFormat = validateAndConvertValue(additionalInfoParameterInfo, UPDATE_ADDITIONAL_INFORMATION);
322             if (responseFormat != null) {
323                 result = Either.right(responseFormat);
324                 return result;
325             }
326             Either<AdditionalInformationDefinition, StorageOperationStatus> addResult = additionalInformationOperation
327                 .updateAdditionalInformationParameter(nodeType, resourceId, additionalInfoParameterInfo.getUniqueId(),
328                     additionalInfoParameterInfo.getKey(), additionalInfoParameterInfo.getValue(), true);
329             if (addResult.isRight()) {
330                 StorageOperationStatus status = addResult.right().value();
331                 BeEcompErrorManager.getInstance().logBeSystemError(UPDATE_ADDITIONAL_INFORMATION);
332                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status);
333                 result = Either.right(componentsUtils
334                     .getResponseFormatAdditionalProperty(actionStatus, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.None));
335                 return result;
336             } else {
337                 AdditionalInformationDefinition informationDefinition = addResult.left().value();
338                 AdditionalInfoParameterInfo parameterInfo = findAdditionInformationKey(informationDefinition.getParameters(),
339                     additionalInfoParameterInfo.getKey());
340                 result = Either.left(parameterInfo);
341                 return result;
342             }
343         } finally {
344             commitOrRollback(result);
345             // unlock component
346             graphLockOperation.unlockComponent(resourceId, nodeType);
347         }
348     }
349
350     /**
351      * Delete an additional information label
352      *
353      * @param nodeType
354      * @param resourceId
355      * @param additionalInfoParameterInfo
356      * @param userId
357      * @return
358      */
359     public Either<AdditionalInfoParameterInfo, ResponseFormat> deleteAdditionalInformation(NodeTypeEnum nodeType, String resourceId,
360                                                                                            AdditionalInfoParameterInfo additionalInfoParameterInfo,
361                                                                                            String userId) {
362         validateUserExists(userId);
363         Either<AdditionalInfoParameterInfo, ResponseFormat> result = null;
364         ResponseFormat responseFormat = verifyCanWorkOnComponent(nodeType, resourceId, userId);
365         if (responseFormat != null) {
366             return Either.right(responseFormat);
367         }
368         // lock component
369         StorageOperationStatus lockResult = graphLockOperation.lockComponent(resourceId, nodeType);
370         if (lockResult != StorageOperationStatus.OK) {
371             BeEcompErrorManager.getInstance().logBeFailedLockObjectError(DELETE_ADDITIONAL_INFORMATION, nodeType.getName(), resourceId);
372             log.info(FAILED_TO_LOCK_COMPONENT_ERROR, resourceId, lockResult);
373             result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
374             return result;
375         }
376         try {
377             Either<AdditionalInfoParameterInfo, StorageOperationStatus> findIdRes = additionalInformationOperation
378                 .getAdditionalInformationParameter(nodeType, resourceId, additionalInfoParameterInfo.getUniqueId(), true);
379             if (findIdRes.isRight()) {
380                 StorageOperationStatus status = findIdRes.right().value();
381                 if (status != StorageOperationStatus.NOT_FOUND) {
382                     BeEcompErrorManager.getInstance().logBeSystemError(GET_ADDITIONAL_INFORMATION);
383                 }
384                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status);
385                 result = Either.right(componentsUtils
386                     .getResponseFormatAdditionalProperty(actionStatus, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.None));
387                 return result;
388             }
389             AdditionalInfoParameterInfo foundAdditionalInfo = findIdRes.left().value();
390             Either<AdditionalInformationDefinition, StorageOperationStatus> addResult = additionalInformationOperation
391                 .deleteAdditionalInformationParameter(nodeType, resourceId, additionalInfoParameterInfo.getUniqueId(), true);
392             if (addResult.isRight()) {
393                 StorageOperationStatus status = addResult.right().value();
394                 BeEcompErrorManager.getInstance().logBeDaoSystemError(DELETE_ADDITIONAL_INFORMATION);
395                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status);
396                 result = Either.right(componentsUtils
397                     .getResponseFormatAdditionalProperty(actionStatus, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.None));
398                 return result;
399             } else {
400                 result = Either.left(foundAdditionalInfo);
401                 return result;
402             }
403         } finally {
404             commitOrRollback(result);
405             // unlock component
406             graphLockOperation.unlockComponent(resourceId, nodeType);
407         }
408     }
409
410     /**
411      * @param nodeType
412      * @param resourceId
413      * @param additionalInfoParameterInfo
414      * @param userId
415      * @return
416      */
417     public Either<AdditionalInfoParameterInfo, ResponseFormat> getAdditionalInformation(NodeTypeEnum nodeType, String resourceId,
418                                                                                         AdditionalInfoParameterInfo additionalInfoParameterInfo,
419                                                                                         String userId) {
420         validateUserExists(userId);
421         Either<AdditionalInfoParameterInfo, ResponseFormat> result = null;
422         try {
423             Either<AdditionalInfoParameterInfo, StorageOperationStatus> findIdRes = additionalInformationOperation
424                 .getAdditionalInformationParameter(nodeType, resourceId, additionalInfoParameterInfo.getUniqueId(), true);
425             if (findIdRes.isRight()) {
426                 StorageOperationStatus status = findIdRes.right().value();
427                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status);
428                 result = Either.right(componentsUtils
429                     .getResponseFormatAdditionalProperty(actionStatus, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.None));
430             }
431             AdditionalInfoParameterInfo foundAdditionalInfo = findIdRes.left().value();
432             result = Either.left(foundAdditionalInfo);
433             return result;
434         } finally {
435             commitOrRollback(result);
436         }
437     }
438
439     /**
440      * Get all additional information properties of a given resource/service
441      *
442      * @param nodeType
443      * @param resourceId
444      * @param userId
445      * @return
446      */
447     public Either<AdditionalInformationDefinition, ResponseFormat> getAllAdditionalInformation(NodeTypeEnum nodeType, String resourceId,
448                                                                                                String userId) {
449         validateUserExists(userId);
450         Either<AdditionalInformationDefinition, ResponseFormat> result = null;
451         try {
452             Either<AdditionalInformationDefinition, JanusGraphOperationStatus> findIdRes = additionalInformationOperation
453                 .getAllAdditionalInformationParameters(nodeType, resourceId, false);
454             if (findIdRes.isRight()) {
455                 StorageOperationStatus status = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(findIdRes.right().value());
456                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status);
457                 result = Either.right(componentsUtils.getResponseFormatAdditionalProperty(actionStatus));
458             } else {
459                 AdditionalInformationDefinition informationDefinition = findIdRes.left().value();
460                 result = Either.left(informationDefinition);
461             }
462             return result;
463         } finally {
464             commitOrRollback(result);
465         }
466     }
467
468     private ResponseFormat verifyCanWorkOnComponent(NodeTypeEnum nodeType, String resourceId, String userId) {
469         switch (nodeType) {
470             case Resource:
471                 // verify that resource is checked-out and the user is the last
472
473                 // updater
474                 if (!ComponentValidationUtils.canWorkOnComponent(resourceId, toscaOperationFacade, userId)) {
475                     return componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
476                 }
477                 break;
478             case Service:
479                 // verify that resource is checked-out and the user is the last
480
481                 // updater
482                 if (!ComponentValidationUtils.canWorkOnComponent(resourceId, toscaOperationFacade, userId)) {
483                     return componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
484                 }
485                 break;
486             default:
487                 return componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT, nodeType.getName());
488         }
489         return null;
490     }
491 }