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