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