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