e01d4c238cb515a5c8568b0bf6b5ff110e0f22f3
[sdc.git] /
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
21 package org.openecomp.sdc.be.components.impl;
22
23 import java.util.List;
24
25 import javax.servlet.ServletContext;
26
27 import org.openecomp.sdc.be.config.BeEcompErrorManager;
28 import org.openecomp.sdc.be.config.ConfigurationManager;
29 import org.openecomp.sdc.be.dao.api.ActionStatus;
30 import org.openecomp.sdc.be.dao.graph.datatype.AdditionalInformationEnum;
31 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
32 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
33 import org.openecomp.sdc.be.impl.ComponentsUtils;
34 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
35 import org.openecomp.sdc.be.model.AdditionalInfoParameterInfo;
36 import org.openecomp.sdc.be.model.AdditionalInformationDefinition;
37 import org.openecomp.sdc.be.model.User;
38 import org.openecomp.sdc.be.model.operations.api.IAdditionalInformationOperation;
39 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
40 import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation;
41 import org.openecomp.sdc.be.model.operations.api.IResourceOperation;
42 import org.openecomp.sdc.be.model.operations.api.IServiceOperation;
43 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
44 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
45 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
46 import org.openecomp.sdc.be.model.tosca.converters.StringConvertor;
47 import org.openecomp.sdc.be.model.tosca.validators.StringValidator;
48 import org.openecomp.sdc.common.api.Constants;
49 import org.openecomp.sdc.common.config.EcompErrorName;
50 import org.openecomp.sdc.common.util.ValidationUtils;
51 import org.openecomp.sdc.exception.ResponseFormat;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54 import org.springframework.stereotype.Component;
55 import org.springframework.web.context.WebApplicationContext;
56
57 import fj.data.Either;
58
59 @Component("additionalInformationBusinessLogic")
60 public class AdditionalInformationBusinessLogic extends BaseBusinessLogic {
61
62         private static final String CREATE_ADDITIONAL_INFORMATION = "CreateAdditionalInformation";
63
64         private static final String UPDATE_ADDITIONAL_INFORMATION = "UpdateAdditionalInformation";
65
66         private static final String DELETE_ADDITIONAL_INFORMATION = "DeleteAdditionalInformation";
67
68         private static final String GET_ADDITIONAL_INFORMATION = "GetAdditionalInformation";
69
70         private static Logger log = LoggerFactory.getLogger(AdditionalInformationBusinessLogic.class.getName());
71
72         @javax.annotation.Resource
73         private IAdditionalInformationOperation additionalInformationOperation = null;
74
75         @javax.annotation.Resource
76         private IResourceOperation resourceOperation;
77
78         @javax.annotation.Resource
79         private IServiceOperation serviceOperation;
80
81         @javax.annotation.Resource
82         private IGraphLockOperation graphLockOperation;
83
84         @javax.annotation.Resource
85         private ComponentsUtils componentsUtils;
86
87         protected static IElementOperation getElementDao(Class<IElementOperation> class1, ServletContext context) {
88                 WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
89
90                 WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
91
92                 return webApplicationContext.getBean(class1);
93         }
94
95         /**
96          * Create new additional information on resource/service on graph
97          * 
98          * @param resourceId
99          * @param propertyName
100          * @param newPropertyDefinition
101          * @param userId
102          * @return Either<PropertyDefinition, ActionStatus>
103          */
104         public Either<AdditionalInfoParameterInfo, ResponseFormat> createAdditionalInformation(NodeTypeEnum nodeType, String resourceId, AdditionalInfoParameterInfo additionalInfoParameterInfo, String additionalInformationUid, String userId) {
105
106                 Either<User, ResponseFormat> resp = validateUserExists(userId, "create Additional Information", false);
107                 if (resp.isRight()) {
108                         return Either.right(resp.right().value());
109                 }
110                 Either<AdditionalInfoParameterInfo, ResponseFormat> result = null;
111
112                 ResponseFormat responseFormat = verifyCanWorkOnComponent(nodeType, resourceId, userId);
113                 if (responseFormat != null) {
114                         result = Either.right(responseFormat);
115                         return result;
116                 }
117
118                 // lock component
119                 StorageOperationStatus lockResult = graphLockOperation.lockComponent(resourceId, nodeType);
120                 if (!lockResult.equals(StorageOperationStatus.OK)) {
121                         BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedLockObjectError, CREATE_ADDITIONAL_INFORMATION);
122                         BeEcompErrorManager.getInstance().logBeFailedLockObjectError(CREATE_ADDITIONAL_INFORMATION, nodeType.getName(), resourceId);
123                         log.info("Failed to lock component {} error - {}", resourceId, lockResult);
124                         result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
125                         return result;
126                 }
127                 try {
128                         responseFormat = validateMaxSizeNotReached(nodeType, resourceId, additionalInfoParameterInfo);
129                         if (responseFormat != null) {
130                                 result = Either.right(responseFormat);
131                                 return result;
132                         }
133
134                         // validate label
135                         responseFormat = validateAndConvertKey(additionalInfoParameterInfo, CREATE_ADDITIONAL_INFORMATION);
136                         if (responseFormat != null) {
137                                 result = Either.right(responseFormat);
138                                 return result;
139                         }
140
141                         // validate value
142                         responseFormat = validateAndConvertValue(additionalInfoParameterInfo, CREATE_ADDITIONAL_INFORMATION);
143                         if (responseFormat != null) {
144                                 result = Either.right(responseFormat);
145                                 return result;
146                         }
147
148                         Either<AdditionalInformationDefinition, StorageOperationStatus> addResult = additionalInformationOperation.createAdditionalInformationParameter(nodeType, resourceId, additionalInfoParameterInfo.getKey(),
149                                         additionalInfoParameterInfo.getValue(), true);
150
151                         if (addResult.isRight()) {
152                                 StorageOperationStatus status = addResult.right().value();
153                                 BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, CREATE_ADDITIONAL_INFORMATION);
154                                 BeEcompErrorManager.getInstance().logBeSystemError(CREATE_ADDITIONAL_INFORMATION);
155                                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status);
156                                 result = Either.right(componentsUtils.getResponseFormatAdditionalProperty(actionStatus, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.Label));
157                                 return result;
158
159                         } else {
160                                 AdditionalInformationDefinition informationDefinition = addResult.left().value();
161
162                                 AdditionalInfoParameterInfo createdAI = findAdditionInformationKey(informationDefinition.getParameters(), additionalInfoParameterInfo.getKey());
163                                 result = Either.left(createdAI);
164                                 return result;
165                         }
166
167                 } finally {
168                         commitOrRollback(result);
169                         // unlock component
170                         graphLockOperation.unlockComponent(resourceId, nodeType);
171                 }
172
173         }
174
175         /**
176          * Validate the value format. Format the value.
177          * 
178          * @param additionalInfoParameterInfo
179          * @return null in case of success. Otherwise response format.
180          */
181         private ResponseFormat validateAndConvertValue(AdditionalInfoParameterInfo additionalInfoParameterInfo, String context) {
182                 ResponseFormat result = null;
183
184                 String value = additionalInfoParameterInfo.getValue();
185                 log.debug("Going to validate additional information value {}", value);
186
187                 Either<String, ResponseFormat> valueValidRes = validateValue(value);
188                 if (valueValidRes.isRight()) {
189                         BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeInvalidValueError, context, additionalInfoParameterInfo.getValue(), "additional information value", "string");
190                         BeEcompErrorManager.getInstance().logBeInvalidValueError(context, additionalInfoParameterInfo.getValue(), "additional information value", "string");
191                         result = valueValidRes.right().value();
192                 } else {
193                         String newValue = valueValidRes.left().value();
194                         if (log.isTraceEnabled()) {
195                                 if (value != null && false == value.equals(newValue)) {
196                                         log.trace("The additional information value was normalized from {} to {}", value, newValue);
197                                 }
198                         }
199                         additionalInfoParameterInfo.setValue(newValue);
200                 }
201                 return result;
202         }
203
204         /**
205          * @param additionalInfoParameterInfo
206          * @return
207          */
208         private ResponseFormat validateAndConvertKey(AdditionalInfoParameterInfo additionalInfoParameterInfo, String context) {
209
210                 String key = additionalInfoParameterInfo.getKey();
211                 log.debug("Going to validate additional information key {}", key);
212
213                 ResponseFormat result = null;
214                 ResponseFormat responseFormat;
215                 Either<String, ResponseFormat> validateKeyRes = validateAndNormalizeKey(key);
216                 if (validateKeyRes.isRight()) {
217                         responseFormat = validateKeyRes.right().value();
218                         BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeInvalidValueError, context, additionalInfoParameterInfo.getKey(), "additional information label", "string");
219                         BeEcompErrorManager.getInstance().logBeInvalidValueError(context, additionalInfoParameterInfo.getKey(), "additional information label", "string");
220                         result = responseFormat;
221
222                 } else {
223                         String convertedKey = validateKeyRes.left().value();
224
225                         if (log.isTraceEnabled()) {
226                                 if (key != null && false == key.equals(convertedKey)) {
227                                         log.trace("The additional information key {} was normalized to {}", key, convertedKey);
228                                 }
229                         }
230                         additionalInfoParameterInfo.setKey(convertedKey);
231                 }
232                 return result;
233         }
234
235         /**
236          * verify that the maximal number of additional information properties has not been reached.
237          * 
238          * @param nodeType
239          * @param componentId
240          * @param additionalInfoParameterInfo
241          * @return response format in case the maximal number has been reached.
242          */
243         private ResponseFormat validateMaxSizeNotReached(NodeTypeEnum nodeType, String componentId, AdditionalInfoParameterInfo additionalInfoParameterInfo) {
244
245                 ResponseFormat result;
246                 Integer additionalInformationMaxNumberOfKeys = ConfigurationManager.getConfigurationManager().getConfiguration().getAdditionalInformationMaxNumberOfKeys();
247
248                 Either<Integer, StorageOperationStatus> checkRes = additionalInformationOperation.getNumberOfAdditionalInformationParameters(nodeType, componentId, true);
249                 if (checkRes.isRight()) {
250                         StorageOperationStatus status = checkRes.right().value();
251
252                         ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status);
253                         result = componentsUtils.getResponseFormatAdditionalProperty(actionStatus, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.None);
254                         return result;
255                 }
256                 Integer currentNumberOfProperties = checkRes.left().value();
257                 if (currentNumberOfProperties >= additionalInformationMaxNumberOfKeys) {
258                         log.info("The current number of additional information properties is {}. The maximum allowed additional information properties is {}", currentNumberOfProperties, currentNumberOfProperties);
259                         result = componentsUtils.getResponseFormatAdditionalProperty(ActionStatus.ADDITIONAL_INFORMATION_MAX_NUMBER_REACHED, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.None);
260                         return result;
261                 }
262
263                 return null;
264         }
265
266         /**
267          * validate additional information value
268          * 
269          * @param value
270          * @return
271          */
272         private Either<String, ResponseFormat> validateValue(String value) {
273
274                 boolean isNonEmptyString = ValidationUtils.validateStringNotEmpty(value);
275                 if (false == isNonEmptyString) {
276                         return Either.right(componentsUtils.getResponseFormatAdditionalProperty(ActionStatus.ADDITIONAL_INFORMATION_EMPTY_STRING_NOT_ALLOWED));
277                 }
278
279                 boolean valid = StringValidator.getInstance().isValid(value, null);
280                 if (false == valid) {
281                         return Either.right(componentsUtils.getResponseFormatAdditionalProperty(ActionStatus.ADDITIONAL_INFORMATION_VALUE_NOT_ALLOWED_CHARACTERS, new AdditionalInfoParameterInfo(null, value), null, AdditionalInformationEnum.Value));
282                 }
283
284                 String converted = StringConvertor.getInstance().convert(value, null, null);
285
286                 return Either.left(converted);
287         }
288
289         private AdditionalInfoParameterInfo findAdditionInformationKey(List<AdditionalInfoParameterInfo> parameters, String key) {
290
291                 for (AdditionalInfoParameterInfo infoParameterInfo : parameters) {
292                         if (infoParameterInfo.getKey().equals(key)) {
293                                 return infoParameterInfo;
294                         }
295                 }
296                 return null;
297         }
298
299         /**
300          * validate and normalize the key
301          * 
302          * @param additionalInfoParameterInfo
303          * @return
304          */
305         private Either<String, ResponseFormat> validateAndNormalizeKey(String key) {
306
307                 AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo();
308                 additionalInfoParameterInfo.setKey(key);
309
310                 key = ValidationUtils.normalizeAdditionalInformation(key);
311                 boolean isNonEmptyString = ValidationUtils.validateStringNotEmpty(key);
312                 if (false == isNonEmptyString) {
313                         return Either.right(componentsUtils.getResponseFormatAdditionalProperty(ActionStatus.ADDITIONAL_INFORMATION_EMPTY_STRING_NOT_ALLOWED, null, null, AdditionalInformationEnum.Label));
314                 }
315                 boolean isValidString = ValidationUtils.validateAdditionalInformationKeyName(key);
316                 if (false == isValidString) {
317                         if (false == ValidationUtils.validateLength(key, ValidationUtils.ADDITIONAL_INFORMATION_KEY_MAX_LENGTH)) {
318                                 return Either.right(componentsUtils.getResponseFormatAdditionalProperty(ActionStatus.ADDITIONAL_INFORMATION_EXCEEDS_LIMIT, additionalInfoParameterInfo, null, AdditionalInformationEnum.Label));
319                         }
320                         return Either.right(componentsUtils.getResponseFormatAdditionalProperty(ActionStatus.ADDITIONAL_INFORMATION_KEY_NOT_ALLOWED_CHARACTERS, additionalInfoParameterInfo, null, AdditionalInformationEnum.Label));
321                 }
322
323                 return Either.left(key);
324         }
325
326         /**
327          * update key and value of a given additional information.
328          * 
329          * @param nodeType
330          * @param resourceId
331          * @param additionalInfoParameterInfo
332          * @param additionalInformationUid
333          *            - Future use
334          * @param userId
335          * @return
336          */
337         public Either<AdditionalInfoParameterInfo, ResponseFormat> updateAdditionalInformation(NodeTypeEnum nodeType, String resourceId, AdditionalInfoParameterInfo additionalInfoParameterInfo, String additionalInformationUid, String userId) {
338
339                 Either<User, ResponseFormat> resp = validateUserExists(userId, "create Additional Information", false);
340                 if (resp.isRight()) {
341                         return Either.right(resp.right().value());
342                 }
343                 Either<AdditionalInfoParameterInfo, ResponseFormat> result = null;
344
345                 ResponseFormat responseFormat = verifyCanWorkOnComponent(nodeType, resourceId, userId);
346                 if (responseFormat != null) {
347                         result = Either.right(responseFormat);
348                         return result;
349                 }
350                 // lock component
351                 StorageOperationStatus lockResult = graphLockOperation.lockComponent(resourceId, nodeType);
352                 if (!lockResult.equals(StorageOperationStatus.OK)) {
353                         BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedLockObjectError, UPDATE_ADDITIONAL_INFORMATION);
354                         BeEcompErrorManager.getInstance().logBeFailedLockObjectError(UPDATE_ADDITIONAL_INFORMATION, nodeType.getName(), resourceId);
355                         log.info("Failed to lock component {} error - {}", resourceId, lockResult);
356                         result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
357                         return result;
358                 }
359                 try {
360
361                         // validate input
362                         responseFormat = validateAndConvertKey(additionalInfoParameterInfo, UPDATE_ADDITIONAL_INFORMATION);
363                         if (responseFormat != null) {
364                                 result = Either.right(responseFormat);
365                                 return result;
366                         }
367
368                         responseFormat = validateAndConvertValue(additionalInfoParameterInfo, UPDATE_ADDITIONAL_INFORMATION);
369                         if (responseFormat != null) {
370                                 result = Either.right(responseFormat);
371                                 return result;
372                         }
373
374                         Either<AdditionalInformationDefinition, StorageOperationStatus> addResult = additionalInformationOperation.updateAdditionalInformationParameter(nodeType, resourceId, additionalInfoParameterInfo.getUniqueId(),
375                                         additionalInfoParameterInfo.getKey(), additionalInfoParameterInfo.getValue(), true);
376
377                         if (addResult.isRight()) {
378                                 StorageOperationStatus status = addResult.right().value();
379                                 BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, UPDATE_ADDITIONAL_INFORMATION);
380                                 BeEcompErrorManager.getInstance().logBeSystemError(UPDATE_ADDITIONAL_INFORMATION);
381                                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status);
382                                 result = Either.right(componentsUtils.getResponseFormatAdditionalProperty(actionStatus, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.None));
383                                 return result;
384                         } else {
385                                 AdditionalInformationDefinition informationDefinition = addResult.left().value();
386                                 AdditionalInfoParameterInfo parameterInfo = findAdditionInformationKey(informationDefinition.getParameters(), additionalInfoParameterInfo.getKey());
387                                 result = Either.left(parameterInfo);
388                                 return result;
389                         }
390
391                 } finally {
392                         commitOrRollback(result);
393                         // unlock component
394                         graphLockOperation.unlockComponent(resourceId, nodeType);
395                 }
396
397         }
398
399         /**
400          * Delete an additional information label
401          * 
402          * @param nodeType
403          * @param resourceId
404          * @param additionalInfoParameterInfo
405          * @param additionalInformationUid
406          *            - Null. Future use.
407          * @param userId
408          * @return
409          */
410         public Either<AdditionalInfoParameterInfo, ResponseFormat> deleteAdditionalInformation(NodeTypeEnum nodeType, String resourceId, AdditionalInfoParameterInfo additionalInfoParameterInfo, String additionalInformationUid, String userId) {
411
412                 Either<User, ResponseFormat> resp = validateUserExists(userId, "delete Additional Information", false);
413                 if (resp.isRight()) {
414                         return Either.right(resp.right().value());
415                 }
416                 Either<AdditionalInfoParameterInfo, ResponseFormat> result = null;
417
418                 ResponseFormat responseFormat = verifyCanWorkOnComponent(nodeType, resourceId, userId);
419                 if (responseFormat != null) {
420                         return Either.right(responseFormat);
421                 }
422                 // lock component
423                 StorageOperationStatus lockResult = graphLockOperation.lockComponent(resourceId, nodeType);
424                 if (!lockResult.equals(StorageOperationStatus.OK)) {
425                         BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedLockObjectError, DELETE_ADDITIONAL_INFORMATION);
426                         BeEcompErrorManager.getInstance().logBeFailedLockObjectError(DELETE_ADDITIONAL_INFORMATION, nodeType.getName(), resourceId);
427                         log.info("Failed to lock component {} error - {}", resourceId, lockResult);
428                         result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
429                         return result;
430                 }
431
432                 try {
433
434                         Either<AdditionalInfoParameterInfo, StorageOperationStatus> findIdRes = additionalInformationOperation.getAdditionalInformationParameter(nodeType, resourceId, additionalInfoParameterInfo.getUniqueId(), true);
435                         if (findIdRes.isRight()) {
436                                 StorageOperationStatus status = findIdRes.right().value();
437                                 if (status != StorageOperationStatus.NOT_FOUND) {
438                                         BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, GET_ADDITIONAL_INFORMATION);
439                                         BeEcompErrorManager.getInstance().logBeSystemError(GET_ADDITIONAL_INFORMATION);
440                                 }
441                                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status);
442                                 result = Either.right(componentsUtils.getResponseFormatAdditionalProperty(actionStatus, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.None));
443                                 return result;
444                         }
445
446                         AdditionalInfoParameterInfo foundAdditionalInfo = findIdRes.left().value();
447
448                         Either<AdditionalInformationDefinition, StorageOperationStatus> addResult = additionalInformationOperation.deleteAdditionalInformationParameter(nodeType, resourceId, additionalInfoParameterInfo.getUniqueId(), true);
449
450                         if (addResult.isRight()) {
451                                 StorageOperationStatus status = addResult.right().value();
452                                 BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, DELETE_ADDITIONAL_INFORMATION);
453                                 BeEcompErrorManager.getInstance().logBeDaoSystemError(DELETE_ADDITIONAL_INFORMATION);
454                                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status);
455                                 result = Either.right(componentsUtils.getResponseFormatAdditionalProperty(actionStatus, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.None));
456                                 return result;
457                         } else {
458                                 result = Either.left(foundAdditionalInfo);
459                                 return result;
460                         }
461
462                 } finally {
463                         commitOrRollback(result);
464                         // unlock component
465                         graphLockOperation.unlockComponent(resourceId, nodeType);
466                 }
467
468         }
469
470         /**
471          * @param nodeType
472          * @param resourceId
473          * @param additionalInfoParameterInfo
474          * @param additionalInformationUid
475          * @param userId
476          * @return
477          */
478         public Either<AdditionalInfoParameterInfo, ResponseFormat> getAdditionalInformation(NodeTypeEnum nodeType, String resourceId, AdditionalInfoParameterInfo additionalInfoParameterInfo, String additionalInformationUid, String userId) {
479
480                 Either<User, ResponseFormat> resp = validateUserExists(userId, "get Additional Information", false);
481                 if (resp.isRight()) {
482                         return Either.right(resp.right().value());
483                 }
484                 Either<AdditionalInfoParameterInfo, ResponseFormat> result = null;
485
486                 try {
487
488                         Either<AdditionalInfoParameterInfo, StorageOperationStatus> findIdRes = additionalInformationOperation.getAdditionalInformationParameter(nodeType, resourceId, additionalInfoParameterInfo.getUniqueId(), true);
489
490                         if (findIdRes.isRight()) {
491                                 StorageOperationStatus status = findIdRes.right().value();
492                                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status);
493                                 result = Either.right(componentsUtils.getResponseFormatAdditionalProperty(actionStatus, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.None));
494                         }
495
496                         AdditionalInfoParameterInfo foundAdditionalInfo = findIdRes.left().value();
497
498                         result = Either.left(foundAdditionalInfo);
499
500                         return result;
501
502                 } finally {
503                         commitOrRollback(result);
504                 }
505
506         }
507
508         /**
509          * Get all additional information properties of a given resource/service
510          * 
511          * @param nodeType
512          * @param resourceId
513          * @param additionalInformationUid
514          *            - Future use
515          * @param userId
516          * @return
517          */
518         public Either<AdditionalInformationDefinition, ResponseFormat> getAllAdditionalInformation(NodeTypeEnum nodeType, String resourceId, String additionalInformationUid, String userId) {
519
520                 Either<User, ResponseFormat> resp = validateUserExists(userId, "get All Additional Information", false);
521                 if (resp.isRight()) {
522                         return Either.right(resp.right().value());
523                 }
524
525                 Either<AdditionalInformationDefinition, ResponseFormat> result = null;
526
527                 try {
528
529                         Either<AdditionalInformationDefinition, TitanOperationStatus> findIdRes = additionalInformationOperation.getAllAdditionalInformationParameters(nodeType, resourceId, false);
530                         if (findIdRes.isRight()) {
531                                 StorageOperationStatus status = DaoStatusConverter.convertTitanStatusToStorageStatus(findIdRes.right().value());
532                                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status);
533                                 result = Either.right(componentsUtils.getResponseFormatAdditionalProperty(actionStatus));
534                         } else {
535                                 AdditionalInformationDefinition informationDefinition = findIdRes.left().value();
536                                 result = Either.left(informationDefinition);
537                         }
538
539                         return result;
540
541                 } finally {
542                         commitOrRollback(result);
543                 }
544
545         }
546
547         private ResponseFormat verifyCanWorkOnComponent(NodeTypeEnum nodeType, String resourceId, String userId) {
548
549                 switch (nodeType) {
550                 case Resource:
551
552                         // verify that resource is checked-out and the user is the last
553                         // updater
554                         if (!ComponentValidationUtils.canWorkOnResource(resourceId, resourceOperation, userId)) {
555                                 return componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
556                         }
557                         break;
558                 case Service:
559
560                         // verify that resource is checked-out and the user is the last
561                         // updater
562                         if (!ComponentValidationUtils.canWorkOnService(resourceId, serviceOperation, userId)) {
563                                 return componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
564                         }
565                         break;
566                 default:
567                         return componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT, nodeType.getName());
568                 }
569
570                 return null;
571         }
572
573 }