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