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