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