UT-AdditionalInfoOperation2
[sdc.git] / catalog-model / src / main / java / org / openecomp / sdc / be / model / operations / impl / AdditionalInformationOperation.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
21 package org.openecomp.sdc.be.model.operations.impl;
22
23 import com.thinkaurelius.titan.core.TitanVertex;
24 import fj.data.Either;
25 import org.apache.commons.lang3.tuple.ImmutablePair;
26 import org.apache.tinkerpop.gremlin.structure.Vertex;
27 import org.openecomp.sdc.be.config.BeEcompErrorManager;
28 import org.openecomp.sdc.be.dao.graph.GraphElementFactory;
29 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
30 import org.openecomp.sdc.be.dao.graph.datatype.GraphElementTypeEnum;
31 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
32 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
33 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
34 import org.openecomp.sdc.be.dao.titan.TitanGenericDao;
35 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
36 import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterDataDefinition;
37 import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterInfo;
38 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
39 import org.openecomp.sdc.be.model.AdditionalInformationDefinition;
40 import org.openecomp.sdc.be.model.operations.api.IAdditionalInformationOperation;
41 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
42 import org.openecomp.sdc.be.resources.data.AdditionalInfoParameterData;
43 import org.openecomp.sdc.be.resources.data.ResourceMetadataData;
44 import org.openecomp.sdc.be.resources.data.ServiceMetadataData;
45 import org.openecomp.sdc.be.resources.data.UniqueIdData;
46 import org.openecomp.sdc.common.log.wrappers.Logger;
47 import org.springframework.stereotype.Component;
48
49 import java.util.ArrayList;
50 import java.util.HashMap;
51 import java.util.List;
52 import java.util.Map;
53 import java.util.Map.Entry;
54
55 @Component("additional-information-operation")
56 public class AdditionalInformationOperation implements IAdditionalInformationOperation {
57
58     private static final Logger log = Logger.getLogger(AdditionalInformationOperation.class.getName());
59
60     @javax.annotation.Resource
61     private TitanGenericDao titanGenericDao;
62
63     private static final String GOING_TO_EXECUTE_COMMIT_ON_GRAPH = "Going to execute commit on graph.";
64         private static final String GOING_TO_EXECUTE_ROLLBACK_ON_GRAPH = "Going to execute rollback on graph.";
65         private static final String ADDITIONAL_INFORMATION_OF = "additional information of ";
66         public static final String EMPTY_VALUE = null;
67
68     public AdditionalInformationOperation() {
69         super();
70     }
71
72
73     @Override
74     public Either<AdditionalInformationDefinition, TitanOperationStatus> addAdditionalInformationParameter(NodeTypeEnum nodeType, String componentId, String key, String value) {
75
76         TitanOperationStatus verifyNodeTypeVsComponent = verifyNodeTypeVsComponent(nodeType, componentId);
77         if (verifyNodeTypeVsComponent != TitanOperationStatus.OK) {
78             return Either.right(verifyNodeTypeVsComponent);
79         }
80
81         Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> getResult = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId, GraphEdgeLabels.ADDITIONAL_INFORMATION,
82                 NodeTypeEnum.AdditionalInfoParameters, AdditionalInfoParameterData.class);
83
84         if (getResult.isRight()) {
85             TitanOperationStatus status = getResult.right().value();
86             return Either.right(status);
87         }
88
89         ImmutablePair<AdditionalInfoParameterData, GraphEdge> immutablePair = getResult.left().value();
90         AdditionalInfoParameterData parameterData = immutablePair.getLeft();
91         Map<String, String> parameters = parameterData.getParameters();
92         if (parameters == null) {
93             parameters = new HashMap<>();
94             parameterData.setParameters(parameters);
95         }
96         Map<String, String> idToKey = parameterData.getIdToKey();
97         if (idToKey == null) {
98             idToKey = new HashMap<>();
99             parameterData.setIdToKey(idToKey);
100         }
101
102         Integer lastCreatedCounter = parameterData.getAdditionalInfoParameterDataDefinition().getLastCreatedCounter();
103         lastCreatedCounter++;
104
105         if (parameters.containsKey(key)) {
106             log.debug("The key {} already exists under component {}", key, componentId);
107             return Either.right(TitanOperationStatus.ALREADY_EXIST);
108         }
109
110         idToKey.put(String.valueOf(lastCreatedCounter), key);
111         parameters.put(key, value);
112         parameterData.getAdditionalInfoParameterDataDefinition().setLastCreatedCounter(lastCreatedCounter);
113
114         Either<AdditionalInfoParameterData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(parameterData, AdditionalInfoParameterData.class);
115
116         if (updateNode.isRight()) {
117             TitanOperationStatus status = updateNode.right().value();
118             BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("UpdateAdditionalInformationParameter", ADDITIONAL_INFORMATION_OF + nodeType.getName() + " " + componentId, String.valueOf(status));
119             return Either.right(status);
120         }
121
122         AdditionalInformationDefinition informationDefinition = createInformationDefinitionFromNode(componentId, parameters, idToKey, updateNode.left().value());
123
124         return Either.left(informationDefinition);
125
126     }
127
128     @Override
129     public Either<AdditionalInformationDefinition, TitanOperationStatus> updateAdditionalInformationParameter(NodeTypeEnum nodeType, String componentId, String id, String key, String value) {
130
131         TitanOperationStatus verifyNodeTypeVsComponent = verifyNodeTypeVsComponent(nodeType, componentId);
132         if (verifyNodeTypeVsComponent != TitanOperationStatus.OK) {
133             return Either.right(verifyNodeTypeVsComponent);
134         }
135
136         Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> getResult = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId, GraphEdgeLabels.ADDITIONAL_INFORMATION,
137                 NodeTypeEnum.AdditionalInfoParameters, AdditionalInfoParameterData.class);
138
139         if (getResult.isRight()) {
140             TitanOperationStatus status = getResult.right().value();
141             return Either.right(status);
142         }
143
144         ImmutablePair<AdditionalInfoParameterData, GraphEdge> immutablePair = getResult.left().value();
145         AdditionalInfoParameterData parameterData = immutablePair.getLeft();
146         Map<String, String> parameters = parameterData.getParameters();
147         Map<String, String> idToKey = parameterData.getIdToKey();
148         if (idToKey == null || !idToKey.containsKey(id)) {
149             return Either.right(TitanOperationStatus.INVALID_ID);
150         }
151
152         String origKey = idToKey.get(id);
153
154         if (!origKey.equals(key)) {
155             if (parameters.containsKey(key)) {
156                 log.debug("The key {} already exists", key);
157                 return Either.right(TitanOperationStatus.ALREADY_EXIST);
158             }
159             String removed = parameters.remove(origKey);
160             log.trace("The key-value {} = {} was removed from additionalInformation", origKey, removed);
161         }
162         parameters.put(key, value);
163         idToKey.put(id, key);
164
165         Either<AdditionalInfoParameterData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(parameterData, AdditionalInfoParameterData.class);
166
167         if (updateNode.isRight()) {
168             TitanOperationStatus status = updateNode.right().value();
169             BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("UpdateAdditionalInformationParameter", "additional information of resource " + componentId, String.valueOf(status));
170             return Either.right(status);
171         }
172
173         AdditionalInformationDefinition informationDefinition = createInformationDefinitionFromNode(componentId, parameters, idToKey, updateNode.left().value());
174
175         return Either.left(informationDefinition);
176
177     }
178
179     @Override
180     public Either<AdditionalInformationDefinition, TitanOperationStatus> deleteAdditionalInformationParameter(NodeTypeEnum nodeType, String componentId, String id) {
181
182         TitanOperationStatus verifyNodeTypeVsComponent = verifyNodeTypeVsComponent(nodeType, componentId);
183         if (verifyNodeTypeVsComponent != TitanOperationStatus.OK) {
184             return Either.right(verifyNodeTypeVsComponent);
185         }
186
187         Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> getResult = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId, GraphEdgeLabels.ADDITIONAL_INFORMATION,
188                 NodeTypeEnum.AdditionalInfoParameters, AdditionalInfoParameterData.class);
189
190         if (getResult.isRight()) {
191             TitanOperationStatus status = getResult.right().value();
192             return Either.right(status);
193         }
194
195         ImmutablePair<AdditionalInfoParameterData, GraphEdge> immutablePair = getResult.left().value();
196         AdditionalInfoParameterData parameterData = immutablePair.getLeft();
197         Map<String, String> parameters = parameterData.getParameters();
198         Map<String, String> idToKey = parameterData.getIdToKey();
199
200         if (idToKey == null || !idToKey.containsKey(id)) {
201             return Either.right(TitanOperationStatus.INVALID_ID);
202         }
203
204         String key = idToKey.get(id);
205         String removedKey = idToKey.remove(id);
206         String removedValue = parameters.remove(key);
207         log.trace("The key-value {} = {} was removed from additionalInformation", removedKey, removedValue);
208
209         Either<AdditionalInfoParameterData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(parameterData, AdditionalInfoParameterData.class);
210
211         if (updateNode.isRight()) {
212             TitanOperationStatus status = updateNode.right().value();
213             BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("DeleteAdditionalInformationParameter", ADDITIONAL_INFORMATION_OF + nodeType.getName() + " " + componentId, String.valueOf(status));
214             return Either.right(status);
215         }
216
217         AdditionalInformationDefinition informationDefinition = createInformationDefinitionFromNode(componentId, parameters, idToKey, updateNode.left().value());
218
219         return Either.left(informationDefinition);
220
221     }
222
223     private AdditionalInformationDefinition createInformationDefinitionFromNode(String resourceId, Map<String, String> parameters, Map<String, String> idToKey, AdditionalInfoParameterData additionalInfoParameterData) {
224         AdditionalInfoParameterDataDefinition dataDefinition = additionalInfoParameterData.getAdditionalInfoParameterDataDefinition();
225
226         return new AdditionalInformationDefinition(dataDefinition, resourceId, convertParameters(parameters, idToKey));
227     }
228
229     private List<AdditionalInfoParameterInfo> convertParameters(Map<String, String> parameters, Map<String, String> idToKey) {
230
231         List<AdditionalInfoParameterInfo> list = new ArrayList<>();
232
233         if (parameters != null) {
234             for (Entry<String, String> idToKeyEntry : idToKey.entrySet()) {
235
236                 String id = idToKeyEntry.getKey();
237                 String key = idToKeyEntry.getValue();
238
239                 String value = parameters.get(key);
240
241                 AdditionalInfoParameterInfo parameterInfo = new AdditionalInfoParameterInfo(id, key, value);
242                 list.add(parameterInfo);
243             }
244
245         }
246
247         return list;
248     }
249
250     @Override
251     public Either<AdditionalInfoParameterData, TitanOperationStatus> addAdditionalInformationNode(NodeTypeEnum nodeType, String componentId) {
252
253         UniqueIdData from = new UniqueIdData(nodeType, componentId);
254
255         String uniqueId = UniqueIdBuilder.buildAdditionalInformationUniqueId(componentId);
256         AdditionalInfoParameterDataDefinition additionalInfoParameterDataDefinition = new AdditionalInfoParameterDataDefinition();
257         additionalInfoParameterDataDefinition.setUniqueId(uniqueId);
258
259         AdditionalInfoParameterData additionalInfoParameterData = new AdditionalInfoParameterData(additionalInfoParameterDataDefinition, new HashMap<>(), new HashMap<>());
260
261         Either<AdditionalInfoParameterData, TitanOperationStatus> createNode = titanGenericDao.createNode(additionalInfoParameterData, AdditionalInfoParameterData.class);
262         if (createNode.isRight()) {
263             TitanOperationStatus status = createNode.right().value();
264             BeEcompErrorManager.getInstance().logBeFailedCreateNodeError("AddAdditionalInformationNode", uniqueId, String.valueOf(status));
265             return Either.right(status);
266         }
267
268         AdditionalInfoParameterData to = createNode.left().value();
269
270         Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(from, to, GraphEdgeLabels.ADDITIONAL_INFORMATION, null);
271         if (createRelation.isRight()) {
272             TitanOperationStatus status = createRelation.right().value();
273             return Either.right(status);
274         }
275
276         return Either.left(to);
277     }
278
279     @Override
280     public Either<TitanVertex, TitanOperationStatus> addAdditionalInformationNode(NodeTypeEnum nodeType, String componentId, TitanVertex metadataVertex) {
281
282         String uniqueId = UniqueIdBuilder.buildAdditionalInformationUniqueId(componentId);
283         AdditionalInfoParameterDataDefinition additionalInfoParameterDataDefinition = new AdditionalInfoParameterDataDefinition();
284         additionalInfoParameterDataDefinition.setUniqueId(uniqueId);
285
286         AdditionalInfoParameterData additionalInfoParameterData = new AdditionalInfoParameterData(additionalInfoParameterDataDefinition, new HashMap<>(), new HashMap<>());
287
288         Either<TitanVertex, TitanOperationStatus> createNode = titanGenericDao.createNode(additionalInfoParameterData);
289         if (createNode.isRight()) {
290             TitanOperationStatus status = createNode.right().value();
291             BeEcompErrorManager.getInstance().logBeFailedCreateNodeError("AddAdditionalInformationNode", uniqueId, String.valueOf(status));
292             return Either.right(status);
293         }
294
295         TitanVertex additionalInfoVertex = createNode.left().value();
296
297         TitanOperationStatus createRelation = titanGenericDao.createEdge(metadataVertex, additionalInfoVertex, GraphEdgeLabels.ADDITIONAL_INFORMATION, null);
298
299         if (!createRelation.equals(TitanOperationStatus.OK)) {
300             return Either.right(createRelation);
301         }
302         return Either.left(additionalInfoVertex);
303     }
304
305     public Either<AdditionalInformationDefinition, TitanOperationStatus> addAdditionalInformationNode(NodeTypeEnum nodeType, String componentId, AdditionalInformationDefinition parameters) {
306
307         Either<AdditionalInfoParameterData, TitanOperationStatus> status = this.addAdditionalInformationNode(nodeType, componentId);
308
309         if (status.isRight()) {
310             return Either.right(status.right().value());
311         }
312
313         AdditionalInfoParameterData parameterData = status.left().value();
314
315         populateParameterNodeWithParameters(parameterData, parameters);
316
317         Either<AdditionalInfoParameterData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(parameterData, AdditionalInfoParameterData.class);
318
319         if (updateNode.isRight()) {
320             return Either.right(updateNode.right().value());
321         }
322
323         AdditionalInformationDefinition informationDefinition = convertAdditionalInformationDataToDefinition(updateNode.left().value(), componentId);
324
325         return Either.left(informationDefinition);
326     }
327
328     public TitanOperationStatus addAdditionalInformationNode(NodeTypeEnum nodeType, String componentId, AdditionalInformationDefinition parameters, TitanVertex metadataVertex) {
329
330         Either<TitanVertex, TitanOperationStatus> status = this.addAdditionalInformationNode(nodeType, componentId, metadataVertex);
331
332         if (status.isRight()) {
333             return status.right().value();
334         }
335         TitanVertex additionalInfoVertex = status.left().value();
336
337         Map<String, Object> newProp = titanGenericDao.getProperties(additionalInfoVertex);
338         AdditionalInfoParameterData parameterData = GraphElementFactory.createElement(NodeTypeEnum.AdditionalInfoParameters.getName(), GraphElementTypeEnum.Node, newProp, AdditionalInfoParameterData.class);
339
340         populateParameterNodeWithParameters(parameterData, parameters);
341
342         return titanGenericDao.updateVertex(parameterData, additionalInfoVertex);
343     }
344
345     private void populateParameterNodeWithParameters(AdditionalInfoParameterData parameterData, AdditionalInformationDefinition aiDefinition) {
346
347         if (aiDefinition != null) {
348
349             Integer lastCreatedCounter = aiDefinition.getLastCreatedCounter();
350             parameterData.getAdditionalInfoParameterDataDefinition().setLastCreatedCounter(lastCreatedCounter);
351             log.trace("Set last created counter of additional information to {}", lastCreatedCounter);
352
353             List<AdditionalInfoParameterInfo> parameters = aiDefinition.getParameters();
354             if (parameters != null) {
355
356                 Map<String, String> idToKey = new HashMap<>();
357                 Map<String, String> parametersMap = new HashMap<>();
358                 for (AdditionalInfoParameterInfo additionalInfoParameterInfo : parameters) {
359                     String uniqueId = additionalInfoParameterInfo.getUniqueId();
360                     String key = additionalInfoParameterInfo.getKey();
361                     String value = additionalInfoParameterInfo.getValue();
362
363                     if (key != null && !key.isEmpty()) {
364                         idToKey.put(uniqueId, key);
365                         parametersMap.put(key, value);
366                     }
367                 }
368                 parameterData.setIdToKey(idToKey);
369                 parameterData.setParameters(parametersMap);
370             }
371         }
372
373     }
374
375     @Override
376     public TitanOperationStatus findResourceAllAdditionalInformationRecursively(String uniqueId, List<AdditionalInformationDefinition> properties) {
377
378         log.trace("Going to fetch additional information under resource {}", uniqueId);
379         TitanOperationStatus resourceCapabilitiesStatus = findAdditionalInformationOfNode(NodeTypeEnum.Resource, uniqueId, properties);
380
381         if (!resourceCapabilitiesStatus.equals(TitanOperationStatus.OK)) {
382             return resourceCapabilitiesStatus;
383         }
384
385         Either<ImmutablePair<ResourceMetadataData, GraphEdge>, TitanOperationStatus> parentNodes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), uniqueId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource,
386                 ResourceMetadataData.class);
387
388         if (parentNodes.isRight()) {
389             TitanOperationStatus parentNodesStatus = parentNodes.right().value();
390             if (!parentNodesStatus.equals(TitanOperationStatus.NOT_FOUND)) {
391                 log.error("Failed to find parent additional information of resource {}. status is {}", uniqueId, parentNodesStatus);
392                 return parentNodesStatus;
393             }
394         }
395
396         if (parentNodes.isLeft()) {
397             ImmutablePair<ResourceMetadataData, GraphEdge> parnetNodePair = parentNodes.left().value();
398             String parentUniqueId = parnetNodePair.getKey().getMetadataDataDefinition().getUniqueId();
399             TitanOperationStatus addParentIntStatus = findResourceAllAdditionalInformationRecursively(parentUniqueId, properties);
400
401             if (addParentIntStatus != TitanOperationStatus.OK) {
402                 log.error("Failed to find all resource additional information of resource {}", parentUniqueId);
403                 return addParentIntStatus;
404             }
405         }
406         return TitanOperationStatus.OK;
407
408     }
409
410     @Override
411     public TitanOperationStatus findServiceAllAdditionalInformationRecursively(String uniqueId, List<AdditionalInformationDefinition> properties) {
412
413         log.trace("Going to fetch additional information under service {}", uniqueId);
414         TitanOperationStatus resourceCapabilitiesStatus = findAdditionalInformationOfNode(NodeTypeEnum.Service, uniqueId, properties);
415
416         if (!resourceCapabilitiesStatus.equals(TitanOperationStatus.OK)) {
417             return resourceCapabilitiesStatus;
418         }
419
420         Either<ImmutablePair<ServiceMetadataData, GraphEdge>, TitanOperationStatus> parentNodes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Service), uniqueId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Service,
421                 ServiceMetadataData.class);
422
423         if (parentNodes.isRight()) {
424             TitanOperationStatus parentNodesStatus = parentNodes.right().value();
425             if (!parentNodesStatus.equals(TitanOperationStatus.NOT_FOUND)) {
426                 log.error("Failed to find parent additional information of resource {}. status is {}", uniqueId, parentNodesStatus);
427                 return parentNodesStatus;
428             }
429         }
430
431         if (parentNodes.isLeft()) {
432             ImmutablePair<ServiceMetadataData, GraphEdge> parnetNodePair = parentNodes.left().value();
433             String parentUniqueId = parnetNodePair.getKey().getMetadataDataDefinition().getUniqueId();
434             TitanOperationStatus addParentIntStatus = findServiceAllAdditionalInformationRecursively(parentUniqueId, properties);
435
436             if (addParentIntStatus != TitanOperationStatus.OK) {
437                 log.error("Failed to find all resource additional information of resource {}", parentUniqueId);
438                 return addParentIntStatus;
439             }
440         }
441         return TitanOperationStatus.OK;
442
443     }
444
445     private TitanOperationStatus findAdditionalInformationOfNode(NodeTypeEnum nodeType, String uniqueId, List<AdditionalInformationDefinition> properties) {
446
447         Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> childNode = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, GraphEdgeLabels.ADDITIONAL_INFORMATION,
448                 NodeTypeEnum.AdditionalInfoParameters, AdditionalInfoParameterData.class);
449
450         if (childNode.isRight()) {
451             TitanOperationStatus status = childNode.right().value();
452             if (status == TitanOperationStatus.NOT_FOUND) {
453                 status = TitanOperationStatus.OK;
454             }
455             return status;
456         }
457
458         ImmutablePair<AdditionalInfoParameterData, GraphEdge> immutablePair = childNode.left().value();
459         AdditionalInfoParameterData propertyData = immutablePair.getKey();
460
461         Map<String, String> parameters = propertyData.getParameters();
462         if (parameters != null && !parameters.isEmpty()) {
463             AdditionalInformationDefinition additionalInfoDef = this.convertAdditionalInformationDataToDefinition(propertyData, uniqueId);
464             properties.add(additionalInfoDef);
465         }
466
467         return TitanOperationStatus.OK;
468
469     }
470
471     private AdditionalInformationDefinition convertAdditionalInformationDataToDefinition(AdditionalInfoParameterData additionalInfoData, String uniqueId) {
472
473         Map<String, String> parameters = additionalInfoData.getParameters();
474         Map<String, String> idToKey = additionalInfoData.getIdToKey();
475
476         return new AdditionalInformationDefinition(additionalInfoData.getAdditionalInfoParameterDataDefinition(), uniqueId, convertParameters(parameters, idToKey));
477     }
478
479     @Override
480     public Either<AdditionalInformationDefinition, StorageOperationStatus> createAdditionalInformationParameter(NodeTypeEnum nodeType, String resourceId, String key, String value, boolean inTransaction) {
481
482         Either<AdditionalInformationDefinition, StorageOperationStatus> result = null;
483
484         try {
485
486             Either<AdditionalInformationDefinition, TitanOperationStatus> either = this.addAdditionalInformationParameter(nodeType, resourceId, key, value);
487
488             if (either.isRight()) {
489                 TitanOperationStatus status = either.right().value();
490                 log.debug("Failed to add additional information property {} to component {}. Status is {}", key, resourceId, status);
491                 BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("CreateAdditionalInformationParameter", ADDITIONAL_INFORMATION_OF + nodeType.getName() + " " + resourceId, String.valueOf(status));
492                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
493             } else {
494                 AdditionalInformationDefinition additionalInformationDefinition = either.left().value();
495                 result = Either.left(additionalInformationDefinition);
496             }
497
498             return result;
499         } finally {
500             commitOrRollback(inTransaction, result);
501         }
502
503     }
504
505     @Override
506     public Either<AdditionalInformationDefinition, StorageOperationStatus> updateAdditionalInformationParameter(NodeTypeEnum nodeType, String resourceId, String id, String key, String value, boolean inTransaction) {
507
508         Either<AdditionalInformationDefinition, StorageOperationStatus> result = null;
509
510         try {
511
512             Either<AdditionalInformationDefinition, TitanOperationStatus> either = this.updateAdditionalInformationParameter(nodeType, resourceId, id, key, value);
513
514             if (either.isRight()) {
515                 log.info("Failed to update additional information property {} to component {}", key, resourceId);
516                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value()));
517             } else {
518                 AdditionalInformationDefinition additionalInformationDefinition = either.left().value();
519                 result = Either.left(additionalInformationDefinition);
520             }
521
522             return result;
523
524         } finally {
525             commitOrRollback(inTransaction, result);
526         }
527
528     }
529
530     @Override
531     public Either<AdditionalInformationDefinition, StorageOperationStatus> deleteAdditionalInformationParameter(NodeTypeEnum nodeType, String resourceId, String id, boolean inTransaction) {
532
533         Either<AdditionalInformationDefinition, StorageOperationStatus> result = null;
534
535         try {
536
537             Either<AdditionalInformationDefinition, TitanOperationStatus> either = this.deleteAdditionalInformationParameter(nodeType, resourceId, id);
538
539             if (either.isRight()) {
540                 log.error("Failed to delete additional information id {} to component {}", id, resourceId);
541                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value()));
542             } else {
543                 AdditionalInformationDefinition additionalInformationDefinition = either.left().value();
544                 result = Either.left(additionalInformationDefinition);
545             }
546
547             return result;
548
549         } finally {
550             commitOrRollback(inTransaction, result);
551         }
552
553     }
554
555     @Override
556     public Either<Integer, StorageOperationStatus> getNumberOfAdditionalInformationParameters(NodeTypeEnum nodeType, String resourceId, boolean inTransaction) {
557
558         Either<Integer, StorageOperationStatus> result = null;
559
560         try {
561
562             Either<Integer, TitanOperationStatus> either = this.getNumberOfParameters(nodeType, resourceId);
563
564             if (either.isRight()) {
565                 log.error("Failed to get the number of additional information properties in component {}", resourceId);
566                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value()));
567             } else {
568                 Integer counter = either.left().value();
569                 result = Either.left(counter);
570             }
571
572             return result;
573         } finally {
574             if (!inTransaction) {
575                 if (result == null || result.isRight()) {
576                     log.error(GOING_TO_EXECUTE_ROLLBACK_ON_GRAPH);
577                     titanGenericDao.rollback();
578                 } else {
579                     log.debug(GOING_TO_EXECUTE_COMMIT_ON_GRAPH);
580                     titanGenericDao.commit();
581                 }
582             }
583         }
584
585     }
586
587     @Override
588     public Either<Integer, TitanOperationStatus> getNumberOfParameters(NodeTypeEnum nodeType, String resourceId) {
589
590         Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> getResult = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), resourceId, GraphEdgeLabels.ADDITIONAL_INFORMATION,
591                 NodeTypeEnum.AdditionalInfoParameters, AdditionalInfoParameterData.class);
592
593         if (getResult.isRight()) {
594             TitanOperationStatus status = getResult.right().value();
595             return Either.right(status);
596         }
597
598         ImmutablePair<AdditionalInfoParameterData, GraphEdge> immutablePair = getResult.left().value();
599         AdditionalInfoParameterData parameterData = immutablePair.getLeft();
600         Map<String, String> parameters = parameterData.getParameters();
601
602         Integer counter = 0;
603         if (parameters != null) {
604             counter = parameters.size();
605         }
606
607         return Either.left(counter);
608
609     }
610
611     @Override
612     public Either<AdditionalInfoParameterInfo, TitanOperationStatus> getAdditionalInformationParameter(NodeTypeEnum nodeType, String componentId, String id) {
613
614         TitanOperationStatus verifyNodeTypeVsComponent = verifyNodeTypeVsComponent(nodeType, componentId);
615         if (verifyNodeTypeVsComponent != TitanOperationStatus.OK) {
616             return Either.right(verifyNodeTypeVsComponent);
617         }
618
619         Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> getResult = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId, GraphEdgeLabels.ADDITIONAL_INFORMATION,
620                 NodeTypeEnum.AdditionalInfoParameters, AdditionalInfoParameterData.class);
621
622         if (getResult.isRight()) {
623             TitanOperationStatus status = getResult.right().value();
624             return Either.right(status);
625         }
626
627         ImmutablePair<AdditionalInfoParameterData, GraphEdge> immutablePair = getResult.left().value();
628         AdditionalInfoParameterData parameterData = immutablePair.getLeft();
629         Map<String, String> parameters = parameterData.getParameters();
630         Map<String, String> idToKey = parameterData.getIdToKey();
631
632         if (idToKey == null || !idToKey.containsKey(id)) {
633             return Either.right(TitanOperationStatus.INVALID_ID);
634         }
635
636         String key = idToKey.get(id);
637         String value = parameters.get(key);
638
639         log.trace("The key-value {} = {} was retrieved for id {}", key, value, id);
640
641         Either<AdditionalInfoParameterData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(parameterData, AdditionalInfoParameterData.class);
642
643         if (updateNode.isRight()) {
644             TitanOperationStatus status = updateNode.right().value();
645             if (status != TitanOperationStatus.NOT_FOUND) {
646                 BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("GetAdditionnalInformationParameter", ADDITIONAL_INFORMATION_OF + nodeType.getName() + " " + componentId, String.valueOf(status));
647             }
648             return Either.right(status);
649         }
650
651         AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(id, key, value);
652
653         return Either.left(additionalInfoParameterInfo);
654
655     }
656
657     @Override
658     public Either<AdditionalInformationDefinition, TitanOperationStatus> getAllAdditionalInformationParameters(NodeTypeEnum nodeType, String componentId, boolean ignoreVerification) {
659
660         if (!ignoreVerification) {
661             TitanOperationStatus verifyNodeTypeVsComponent = verifyNodeTypeVsComponent(nodeType, componentId);
662             if (verifyNodeTypeVsComponent != TitanOperationStatus.OK) {
663                 return Either.right(verifyNodeTypeVsComponent);
664             }
665         }
666
667         Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> getResult = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId, GraphEdgeLabels.ADDITIONAL_INFORMATION,
668                 NodeTypeEnum.AdditionalInfoParameters, AdditionalInfoParameterData.class);
669
670         if (getResult.isRight()) {
671             TitanOperationStatus status = getResult.right().value();
672             if (status != TitanOperationStatus.NOT_FOUND) {
673                 BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("GetAdditionnalInformationParameters", ADDITIONAL_INFORMATION_OF + nodeType.getName() + " " + componentId, String.valueOf(status));
674             }
675             return Either.right(status);
676         }
677
678         ImmutablePair<AdditionalInfoParameterData, GraphEdge> immutablePair = getResult.left().value();
679         AdditionalInfoParameterData parameterData = immutablePair.getLeft();
680         Map<String, String> parameters = parameterData.getParameters();
681         Map<String, String> idToKey = parameterData.getIdToKey();
682
683         AdditionalInformationDefinition informationDefinition = createInformationDefinitionFromNode(componentId, parameters, idToKey, parameterData);
684
685         return Either.left(informationDefinition);
686
687     }
688
689     @Override
690     public Either<AdditionalInformationDefinition, StorageOperationStatus> getAllAdditionalInformationParameters(NodeTypeEnum nodeType, String resourceId, boolean ignoreVerification, boolean inTransaction) {
691
692         Either<AdditionalInformationDefinition, StorageOperationStatus> result = null;
693
694         try {
695
696             Either<AdditionalInformationDefinition, TitanOperationStatus> either = this.getAllAdditionalInformationParameters(nodeType, resourceId, ignoreVerification);
697
698             if (either.isRight()) {
699                 TitanOperationStatus status = either.right().value();
700                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
701             } else {
702                 AdditionalInformationDefinition additionalInformationDefinition = either.left().value();
703                 result = Either.left(additionalInformationDefinition);
704             }
705
706             return result;
707
708         } finally {
709             commitOrRollback(inTransaction, result);
710         }
711
712     }
713
714     private void commitOrRollback(boolean inTransaction, Either<? extends Object, StorageOperationStatus> result) {
715
716         if (!inTransaction) {
717             if (result == null || result.isRight()) {
718                 log.error(GOING_TO_EXECUTE_ROLLBACK_ON_GRAPH);
719                 titanGenericDao.rollback();
720             } else {
721                 log.debug(GOING_TO_EXECUTE_COMMIT_ON_GRAPH);
722                 titanGenericDao.commit();
723             }
724         }
725     }
726     
727
728     @Override
729     public Either<AdditionalInfoParameterInfo, StorageOperationStatus> getAdditionalInformationParameter(NodeTypeEnum nodeType, String resourceId, String id, boolean inTransaction) {
730
731         Either<AdditionalInfoParameterInfo, StorageOperationStatus> result = null;
732
733         try {
734
735             Either<AdditionalInfoParameterInfo, TitanOperationStatus> either = this.getAdditionalInformationParameter(nodeType, resourceId, id);
736
737             if (either.isRight()) {
738                 log.error("Failed to fetch additional information property with id {} of component {}", id, resourceId);
739                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value()));
740             } else {
741                 AdditionalInfoParameterInfo additionalInformationDefinition = either.left().value();
742                 result = Either.left(additionalInformationDefinition);
743             }
744
745             return result;
746
747         } finally {
748             commitOrRollback(inTransaction, result);
749         }
750     }
751
752     @Override
753     public Either<AdditionalInformationDefinition, StorageOperationStatus> deleteAllAdditionalInformationParameters(NodeTypeEnum nodeType, String resourceId, boolean inTransaction) {
754
755         Either<AdditionalInformationDefinition, StorageOperationStatus> result = null;
756
757         try {
758
759             Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> getResult = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), resourceId, GraphEdgeLabels.ADDITIONAL_INFORMATION,
760                     NodeTypeEnum.AdditionalInfoParameters, AdditionalInfoParameterData.class);
761
762             if (getResult.isRight()) {
763                 TitanOperationStatus status = getResult.right().value();
764                 if (status == TitanOperationStatus.NOT_FOUND) {
765                     return Either.right(StorageOperationStatus.OK);
766                 } else {
767                     BeEcompErrorManager.getInstance().logBeFailedDeleteNodeError("DeleteAdditionalInformationNode", ADDITIONAL_INFORMATION_OF + nodeType.getName() + " " + resourceId, String.valueOf(status));
768                     result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
769                 }
770                 return result;
771             }
772
773             ImmutablePair<AdditionalInfoParameterData, GraphEdge> value = getResult.left().value();
774             AdditionalInfoParameterData parameterData = value.getLeft();
775
776             Either<AdditionalInfoParameterData, TitanOperationStatus> deleteNodeRes = titanGenericDao.deleteNode(parameterData, AdditionalInfoParameterData.class);
777             if (deleteNodeRes.isRight()) {
778                 TitanOperationStatus status = getResult.right().value();
779                 BeEcompErrorManager.getInstance().logBeFailedDeleteNodeError("DeleteAdditionalInformationNode", (String) parameterData.getUniqueId(), String.valueOf(status));
780                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
781                 return result;
782             }
783
784             AdditionalInformationDefinition informationDefinition = convertAdditionalInformationDataToDefinition(deleteNodeRes.left().value(), resourceId);
785
786             result = Either.left(informationDefinition);
787
788             return result;
789
790         } finally {
791             commitOrRollback(inTransaction, result);
792         }
793     }
794
795     private TitanOperationStatus verifyNodeTypeVsComponent(NodeTypeEnum nodeType, String componentId) {
796         Either<TitanVertex, TitanOperationStatus> vertexByProperty = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId);
797         if (vertexByProperty.isRight()) {
798             TitanOperationStatus status = vertexByProperty.right().value();
799             if (status == TitanOperationStatus.NOT_FOUND) {
800                 status = TitanOperationStatus.INVALID_ID;
801             }
802             return status;
803         } else {
804             Vertex v = vertexByProperty.left().value();
805             String label = (String) v.property(GraphPropertiesDictionary.LABEL.getProperty()).value();
806             if (label != null) {
807                 if (!label.equals(nodeType.getName())) {
808                     log.debug("The node type {} is not appropriate to component {}", nodeType, componentId);
809                     return TitanOperationStatus.INVALID_ID;
810                 }
811             } else {
812                 log.debug("The node type {}  with id {} does not have a label property.", nodeType, componentId);
813                 return TitanOperationStatus.INVALID_ID;
814             }
815         }
816         return TitanOperationStatus.OK;
817     }
818
819 }