c86559bb59e25a9457137c6dba461f280f56cf57
[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 fj.data.Either;
24 import org.apache.commons.lang3.tuple.ImmutablePair;
25 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
26 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
27 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
28 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
29 import org.openecomp.sdc.be.dao.titan.TitanGenericDao;
30 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
31 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
32 import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
33 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
34 import org.openecomp.sdc.be.model.ArtifactDefinition;
35 import org.openecomp.sdc.be.model.InterfaceDefinition;
36 import org.openecomp.sdc.be.model.Operation;
37 import org.openecomp.sdc.be.model.operations.api.IInterfaceLifecycleOperation;
38 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
39 import org.openecomp.sdc.be.resources.data.ArtifactData;
40 import org.openecomp.sdc.be.resources.data.InterfaceData;
41 import org.openecomp.sdc.be.resources.data.OperationData;
42 import org.openecomp.sdc.be.resources.data.ResourceMetadataData;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45 import org.springframework.stereotype.Component;
46
47 import java.util.HashMap;
48 import java.util.Iterator;
49 import java.util.List;
50 import java.util.Map;
51 import java.util.Map.Entry;
52 import java.util.Set;
53
54 @Component("interface-operation")
55 public class InterfaceLifecycleOperation implements IInterfaceLifecycleOperation {
56
57         private static Logger log = LoggerFactory.getLogger(InterfaceLifecycleOperation.class.getName());
58
59         public InterfaceLifecycleOperation() {
60                 super();
61         }
62
63         @javax.annotation.Resource
64         private ArtifactOperation artifactOperation;
65
66         @javax.annotation.Resource
67         private TitanGenericDao titanGenericDao;
68
69         @Override
70         public Either<InterfaceDefinition, StorageOperationStatus> addInterfaceToResource(InterfaceDefinition interf, String resourceId, String interfaceName, boolean inTransaction) {
71
72                 return createInterfaceOnResource(interf, resourceId, interfaceName, true, inTransaction);
73
74         }
75
76         private Either<OperationData, TitanOperationStatus> addOperationToGraph(InterfaceDefinition interf, String opName, Operation op, InterfaceData interfaceData) {
77
78                 op.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId((String) interfaceData.getUniqueId(), opName));
79                 OperationData operationData = new OperationData(op);
80
81                 log.debug("Before adding operation to graph {}", operationData);
82                 Either<OperationData, TitanOperationStatus> createOpNodeResult = titanGenericDao.createNode(operationData, OperationData.class);
83                 log.debug("After adding operation to graph {}", operationData);
84
85                 if (createOpNodeResult.isRight()) {
86                         TitanOperationStatus opStatus = createOpNodeResult.right().value();
87                         log.error("Failed to add operation {} to graph. status is {}", opName, opStatus);
88                         return Either.right(opStatus);
89                 }
90
91                 Map<String, Object> props = new HashMap<String, Object>();
92                 props.put(GraphPropertiesDictionary.NAME.getProperty(), opName);
93                 Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(interfaceData, operationData, GraphEdgeLabels.INTERFACE_OPERATION, props);
94
95                 if (createRelResult.isRight()) {
96                         TitanOperationStatus operationStatus = createOpNodeResult.right().value();
97                         log.error("Failed to associate operation {} to property {} in graph. status is {}", interfaceData.getUniqueId(), opName, operationStatus);
98
99                         return Either.right(operationStatus);
100                 }
101
102                 return Either.left(createOpNodeResult.left().value());
103
104         }
105
106         private InterfaceDefinition convertInterfaceDataToInterfaceDefinition(InterfaceData interfaceData) {
107
108                 log.debug("The object returned after create interface is {}", interfaceData);
109
110                 InterfaceDefinition interfaceDefResult = new InterfaceDefinition(interfaceData.getInterfaceDataDefinition());
111
112                 return interfaceDefResult;
113
114         }
115
116         private Operation convertOperationDataToOperation(OperationData operationData) {
117
118                 log.debug("The object returned after create operation is {}", operationData);
119
120                 Operation operationDefResult = new Operation(operationData.getOperationDataDefinition());
121
122                 return operationDefResult;
123
124         }
125
126         private Either<InterfaceData, TitanOperationStatus> addInterfaceToGraph(InterfaceDefinition interfaceInfo, String interfaceName, String resourceId) {
127
128                 InterfaceData interfaceData = new InterfaceData(interfaceInfo);
129
130                 ResourceMetadataData resourceData = new ResourceMetadataData();
131                 resourceData.getMetadataDataDefinition().setUniqueId(resourceId);
132
133                 String interfaceNameSplitted = getShortInterfaceName(interfaceInfo);
134
135                 interfaceInfo.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(resourceId, interfaceNameSplitted));
136
137                 Either<InterfaceData, TitanOperationStatus> existInterface = titanGenericDao.getNode(interfaceData.getUniqueIdKey(), interfaceData.getUniqueId(), InterfaceData.class);
138
139                 if (existInterface.isRight()) {
140
141                         return createInterfaceNodeAndRelation(interfaceNameSplitted, resourceId, interfaceData, resourceData);
142                 } else {
143                         log.debug("Interface {} already exist", interfaceData.getUniqueId());
144                         return Either.right(TitanOperationStatus.ALREADY_EXIST);
145                 }
146         }
147
148         private Either<InterfaceData, TitanOperationStatus> createInterfaceNodeAndRelation(String interfaceName, String resourceId, InterfaceData interfaceData, ResourceMetadataData resourceData) {
149                 log.debug("Before adding interface to graph {}", interfaceData);
150                 Either<InterfaceData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(interfaceData, InterfaceData.class);
151                 log.debug("After adding property to graph {}", interfaceData);
152
153                 if (createNodeResult.isRight()) {
154                         TitanOperationStatus operationStatus = createNodeResult.right().value();
155                         log.error("Failed to add interface {} to graph. status is {}", interfaceName, operationStatus);
156                         return Either.right(operationStatus);
157                 }
158
159                 Map<String, Object> props = new HashMap<String, Object>();
160                 props.put(GraphPropertiesDictionary.NAME.getProperty(), interfaceName);
161                 Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(resourceData, interfaceData, GraphEdgeLabels.INTERFACE, props);
162                 if (createRelResult.isRight()) {
163                         TitanOperationStatus operationStatus = createNodeResult.right().value();
164                         log.error("Failed to associate resource {} to property {} in graph. status is {}", resourceId, interfaceName, operationStatus);
165
166                         return Either.right(operationStatus);
167                 }
168
169                 return Either.left(createNodeResult.left().value());
170         }
171
172         private Either<OperationData, TitanOperationStatus> createOperationNodeAndRelation(String operationName, OperationData operationData, InterfaceData interfaceData) {
173                 log.debug("Before adding operation to graph {}", operationData);
174                 Either<OperationData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(operationData, OperationData.class);
175                 log.debug("After adding operation to graph {}", interfaceData);
176
177                 if (createNodeResult.isRight()) {
178                         TitanOperationStatus operationStatus = createNodeResult.right().value();
179                         log.error("Failed to add interfoperationce {} to graph. status is {}", operationName, operationStatus);
180                         return Either.right(operationStatus);
181                 }
182
183                 Map<String, Object> props = new HashMap<String, Object>();
184                 props.put(GraphPropertiesDictionary.NAME.getProperty(), operationName);
185                 Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(interfaceData, operationData, GraphEdgeLabels.INTERFACE_OPERATION, props);
186                 if (createRelResult.isRight()) {
187                         TitanOperationStatus operationStatus = createNodeResult.right().value();
188                         log.error("Failed to associate operation {} to interface {} in graph. status is {}", operationName, interfaceData.getUniqueId(), operationStatus);
189
190                         return Either.right(operationStatus);
191                 }
192
193                 return Either.left(createNodeResult.left().value());
194         }
195
196         @Override
197         public Either<Map<String, InterfaceDefinition>, StorageOperationStatus> getAllInterfacesOfResource(String resourceIdn, boolean recursively) {
198                 return getAllInterfacesOfResource(resourceIdn, recursively, false);
199         }
200
201         @Override
202         public Either<Map<String, InterfaceDefinition>, StorageOperationStatus> getAllInterfacesOfResource(String resourceId, boolean recursively, boolean inTransaction) {
203
204                 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> result = null;
205                 Map<String, InterfaceDefinition> interfaces = new HashMap<String, InterfaceDefinition>();
206                 try {
207                         if ((resourceId == null) || resourceId.isEmpty()) {
208                                 log.error("resourceId is empty");
209                                 result = Either.right(StorageOperationStatus.INVALID_ID);
210                                 return result;
211                         }
212
213                         TitanOperationStatus findInterfacesRes = TitanOperationStatus.GENERAL_ERROR;
214                         if (recursively) {
215                                 findInterfacesRes = findAllInterfacesRecursively(resourceId, interfaces);
216                         } else {
217                                 findInterfacesRes = findAllInterfacesNotRecursively(resourceId, interfaces);
218                         }
219                         if (!findInterfacesRes.equals(TitanOperationStatus.OK)) {
220                                 log.error("Failed to get all interfaces of resource {}. status is {}", resourceId, findInterfacesRes);
221                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(findInterfacesRes));
222                                 return result;
223                         }
224                         result = Either.left(interfaces);
225                         return result;
226                 } finally {
227                         if (false == inTransaction) {
228                                 if (result == null || result.isRight()) {
229                                         log.error("Going to execute rollback on graph.");
230                                         titanGenericDao.rollback();
231                                 } else {
232                                         log.debug("Going to execute commit on graph.");
233                                         titanGenericDao.commit();
234                                 }
235                         }
236                 }
237         }
238
239         private TitanOperationStatus findAllInterfacesNotRecursively(String resourceId, Map<String, InterfaceDefinition> interfaces) {
240
241                 Either<List<ImmutablePair<InterfaceData, GraphEdge>>, TitanOperationStatus> interfaceNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, GraphEdgeLabels.INTERFACE,
242                                 NodeTypeEnum.Interface, InterfaceData.class);
243
244                 if (interfaceNodes.isRight()) {
245                         TitanOperationStatus status = interfaceNodes.right().value();
246                         if (status != TitanOperationStatus.NOT_FOUND) {
247                                 return status;
248                         }
249                 } else {
250                         List<ImmutablePair<InterfaceData, GraphEdge>> interfaceList = interfaceNodes.left().value();
251                         if (interfaceList != null) {
252                                 for (ImmutablePair<InterfaceData, GraphEdge> interfacePair : interfaceList) {
253                                         String interfaceUniqueId = (String) interfacePair.getKey().getUniqueId();
254                                         Either<String, TitanOperationStatus> interfaceNameRes = getPropertyValueFromEdge(interfacePair.getValue(), GraphPropertiesDictionary.NAME);
255                                         if (interfaceNameRes.isRight()) {
256                                                 log.error("The requirement name is missing on the edge of requirement {}", interfaceUniqueId);
257                                                 return interfaceNameRes.right().value();
258                                         }
259                                         String interfaceName = interfaceNameRes.left().value();
260                                         Either<InterfaceDefinition, TitanOperationStatus> interfaceDefRes = getNonRecursiveInterface(interfacePair.getKey());
261                                         if (interfaceDefRes.isRight()) {
262                                                 TitanOperationStatus status = interfaceDefRes.right().value();
263                                                 log.error("Failed to get interface actions of interface {}", interfaceUniqueId);
264                                                 return status;
265                                         }
266
267                                         InterfaceDefinition interfaceDefinition = interfaceDefRes.left().value();
268                                         if (true == interfaces.containsKey(interfaceName)) {
269                                                 log.debug("The interface {} was already defined in dervied resource. add not overriden operations", interfaceName);
270                                                 InterfaceDefinition existInterface = interfaces.get(interfaceName);
271                                                 addMissingOperationsToInterface(interfaceDefinition, existInterface);
272                                         } else {
273                                                 interfaces.put(interfaceName, interfaceDefinition);
274                                         }
275
276                                 }
277                         }
278                 }
279                 return TitanOperationStatus.OK;
280         }
281
282         public TitanOperationStatus findAllInterfacesRecursively(String resourceId, Map<String, InterfaceDefinition> interfaces) {
283
284                 TitanOperationStatus findAllInterfacesNotRecursively = findAllInterfacesNotRecursively(resourceId, interfaces);
285                 if (!findAllInterfacesNotRecursively.equals(TitanOperationStatus.OK)) {
286                         log.error("failed to get interfaces for resource {}. status is {}", resourceId, findAllInterfacesNotRecursively);
287                 }
288
289                 Either<ImmutablePair<ResourceMetadataData, GraphEdge>, TitanOperationStatus> parentNodes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource,
290                                 ResourceMetadataData.class);
291
292                 if (parentNodes.isRight()) {
293                         TitanOperationStatus parentNodesStatus = parentNodes.right().value();
294                         if (parentNodesStatus == TitanOperationStatus.NOT_FOUND) {
295                                 log.debug("Finish to lookup for parnet interfaces");
296                                 return TitanOperationStatus.OK;
297                         } else {
298                                 log.error("Failed to find parent interfaces of resource {}. status is {}", resourceId, parentNodesStatus);
299                                 return parentNodesStatus;
300                         }
301                 }
302                 ImmutablePair<ResourceMetadataData, GraphEdge> parnetNodePair = parentNodes.left().value();
303                 String parentUniqueId = parnetNodePair.getKey().getMetadataDataDefinition().getUniqueId();
304                 TitanOperationStatus addParentIntStatus = findAllInterfacesRecursively(parentUniqueId, interfaces);
305
306                 if (addParentIntStatus != TitanOperationStatus.OK) {
307                         log.error("Failed to fetch all interfaces of resource {}", parentUniqueId);
308                         return addParentIntStatus;
309                 }
310
311                 return TitanOperationStatus.OK;
312         }
313
314         private Either<String, TitanOperationStatus> getPropertyValueFromEdge(GraphEdge edge, GraphPropertiesDictionary property) {
315                 Map<String, Object> edgeProps = edge.getProperties();
316                 String interfaceName = null;
317                 if (edgeProps != null) {
318                         interfaceName = (String) edgeProps.get(property.getProperty());
319                         if (interfaceName == null) {
320                                 return Either.right(TitanOperationStatus.INVALID_ELEMENT);
321                         }
322                 } else {
323                         return Either.right(TitanOperationStatus.INVALID_ELEMENT);
324                 }
325                 return Either.left(interfaceName);
326         }
327
328         private Either<InterfaceDefinition, TitanOperationStatus> getNonRecursiveInterface(InterfaceData interfaceData) {
329
330                 log.debug("Going to fetch the operations associate to interface {}", interfaceData.getUniqueId());
331                 InterfaceDefinition interfaceDefinition = new InterfaceDefinition(interfaceData.getInterfaceDataDefinition());
332
333                 String interfaceId = interfaceData.getUniqueId();
334                 Either<List<ImmutablePair<OperationData, GraphEdge>>, TitanOperationStatus> operationsRes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), interfaceId, GraphEdgeLabels.INTERFACE_OPERATION,
335                                 NodeTypeEnum.InterfaceOperation, OperationData.class);
336
337                 if (operationsRes.isRight()) {
338                         TitanOperationStatus status = operationsRes.right().value();
339                         if (status != TitanOperationStatus.NOT_FOUND) {
340                                 return Either.right(status);
341                         } else {
342                                 return Either.left(interfaceDefinition);
343                         }
344                 }
345
346                 List<ImmutablePair<OperationData, GraphEdge>> operationList = operationsRes.left().value();
347                 if (operationList != null && !operationList.isEmpty()) {
348                         for (ImmutablePair<OperationData, GraphEdge> operationPair : operationList) {
349                                 Operation operation = new Operation(operationPair.getKey().getOperationDataDefinition());
350                                 Either<String, TitanOperationStatus> operationNameRes = getPropertyValueFromEdge(operationPair.getValue(), GraphPropertiesDictionary.NAME);
351                                 if (operationNameRes.isRight()) {
352                                         log.error("The operation name is missing on the edge of operation {}", operationPair.getKey().getUniqueId());
353                                         return Either.right(operationNameRes.right().value());
354                                 }
355                                 String operationName = operationNameRes.left().value();
356                                 findOperationImplementation(operation);
357                                 interfaceDefinition.getOperations().put(operationName, operation);
358                         }
359                 }
360
361                 return Either.left(interfaceDefinition);
362         }
363
364         private StorageOperationStatus findOperationImplementation(Operation operation) {
365
366                 String operationId = operation.getUniqueId();
367                 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifactsRes = artifactOperation.getArtifacts(operationId, NodeTypeEnum.InterfaceOperation, true);
368                 if (artifactsRes.isRight() || artifactsRes.left().value() == null) {
369                         log.error("failed to get artifact from graph for operation id {}. status is {}", operationId, artifactsRes.right().value());
370                         return artifactsRes.right().value();
371                 } else {
372                         Map<String, ArtifactDefinition> artifacts = artifactsRes.left().value();
373                         Iterator<String> iter = artifacts.keySet().iterator();
374
375                         if (iter.hasNext()) {
376                                 operation.setImplementation(artifacts.get(iter.next()));
377                         }
378                 }
379                 return StorageOperationStatus.OK;
380         }
381
382         private StorageOperationStatus addMissingOperationsToInterface(InterfaceDefinition interfaceDefinition, InterfaceDefinition existInterface) {
383                 Map<String, Operation> existOperations = existInterface.getOperationsMap();
384                 Map<String, Operation> operations = interfaceDefinition.getOperationsMap();
385                 if (operations != null && !operations.isEmpty()) {
386                         Set<Entry<String, Operation>> operationsSet = operations.entrySet();
387                         for (Entry<String, Operation> operation : operationsSet) {
388                                 if (!existOperations.containsKey(operation.getKey())) {
389                                         existOperations.put(operation.getKey(), operation.getValue());
390                                 }
391                         }
392                 }
393                 return StorageOperationStatus.OK;
394         }
395
396         @Override
397         public Either<Operation, StorageOperationStatus> updateInterfaceOperation(String resourceId, String interfaceName, String operationName, Operation interf) {
398
399                 return updateInterfaceOperation(resourceId, interfaceName, operationName, interf, false);
400         }
401
402         @Override
403         public Either<Operation, StorageOperationStatus> updateInterfaceOperation(String resourceId, String interfaceName, String operationName, Operation operation, boolean inTransaction) {
404                 Either<Operation, StorageOperationStatus> status = updateOperationOnGraph(operation, resourceId, interfaceName, operationName);
405                 return status;
406         }
407
408         private Either<Operation, StorageOperationStatus> updateOperationOnGraph(Operation operation, String resourceId, String interfaceName, String operationName) {
409
410                 Either<List<ImmutablePair<InterfaceData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), resourceId, GraphEdgeLabels.INTERFACE, NodeTypeEnum.Interface,
411                                 InterfaceData.class);
412
413                 if (childrenNodes.isRight()) {
414                         return updateOperationFromParentNode(operation, resourceId, interfaceName, operationName);
415
416                 } else {
417                         return updateExistingOperation(resourceId, operation, interfaceName, operationName, childrenNodes);
418
419                 }
420
421         }
422
423         private Either<Operation, StorageOperationStatus> updateExistingOperation(String resourceId, Operation operation, String interfaceName, String operationName,
424                         Either<List<ImmutablePair<InterfaceData, GraphEdge>>, TitanOperationStatus> childrenNodes) {
425                 Operation newOperation = null;
426                 StorageOperationStatus storageOperationStatus = StorageOperationStatus.GENERAL_ERROR;
427
428                 for (ImmutablePair<InterfaceData, GraphEdge> interfaceDataNode : childrenNodes.left().value()) {
429
430                         GraphEdge interfaceEdge = interfaceDataNode.getRight();
431                         Map<String, Object> interfaceEdgeProp = interfaceEdge.getProperties();
432                         InterfaceData interfaceData = interfaceDataNode.getKey();
433
434                         if (interfaceEdgeProp.get(GraphPropertiesDictionary.NAME.getProperty()).equals(interfaceName)) {
435                                 Either<List<ImmutablePair<OperationData, GraphEdge>>, TitanOperationStatus> operationRes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), (String) interfaceDataNode.getLeft().getUniqueId(),
436                                                 GraphEdgeLabels.INTERFACE_OPERATION, NodeTypeEnum.InterfaceOperation, OperationData.class);
437                                 if (operationRes.isRight()) {
438                                         log.error("Failed to find operation  {} on interface {}", operationName, interfaceName);
439                                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationRes.right().value()));
440                                 } else {
441                                         List<ImmutablePair<OperationData, GraphEdge>> operations = operationRes.left().value();
442                                         for (ImmutablePair<OperationData, GraphEdge> operationPairEdge : operations) {
443                                                 GraphEdge opEdge = operationPairEdge.getRight();
444                                                 OperationData opData = operationPairEdge.getLeft();
445                                                 Map<String, Object> opEdgeProp = opEdge.getProperties();
446                                                 if (opEdgeProp.get(GraphPropertiesDictionary.NAME.getProperty()).equals(operationName)) {
447                                                         ArtifactDefinition artifact = operation.getImplementationArtifact();
448                                                         Either<ImmutablePair<ArtifactData, GraphEdge>, TitanOperationStatus> artifactRes = titanGenericDao.getChild(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), (String) opData.getUniqueId(), GraphEdgeLabels.ARTIFACT_REF,
449                                                                         NodeTypeEnum.ArtifactRef, ArtifactData.class);
450                                                         Either<ArtifactDefinition, StorageOperationStatus> artStatus;
451                                                         if (artifactRes.isRight()) {
452                                                                 artStatus = artifactOperation.addArifactToComponent(artifact, (String) operationPairEdge.getLeft().getUniqueId(), NodeTypeEnum.InterfaceOperation, true, true);
453                                                         } else {
454                                                                 artStatus = artifactOperation.updateArifactOnResource(artifact, (String) operationPairEdge.getLeft().getUniqueId(), (String) artifactRes.left().value().getLeft().getUniqueId(), NodeTypeEnum.InterfaceOperation, true);
455                                                         }
456                                                         if (artStatus.isRight()) {
457                                                                 titanGenericDao.rollback();
458                                                                 log.error("Failed to add artifact {} to interface {}", operationName, interfaceName);
459                                                                 return Either.right(artStatus.right().value());
460                                                         } else {
461                                                                 newOperation = this.convertOperationDataToOperation(opData);
462                                                                 newOperation.setImplementation(artStatus.left().value());
463
464                                                         }
465
466                                                 }
467
468                                         }
469                                         if (newOperation == null) {
470                                                 Either<InterfaceData, TitanOperationStatus> parentInterfaceStatus = findInterfaceOnParentNode(resourceId, interfaceName);
471                                                 if (parentInterfaceStatus.isRight()) {
472                                                         log.debug("Interface {} not exist", interfaceName);
473                                                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(parentInterfaceStatus.right().value()));
474                                                 }
475
476                                                 InterfaceData parentInterfaceData = parentInterfaceStatus.left().value();
477                                                 Either<List<ImmutablePair<OperationData, GraphEdge>>, TitanOperationStatus> opRes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), (String) parentInterfaceData.getUniqueId(),
478                                                                 GraphEdgeLabels.INTERFACE_OPERATION, NodeTypeEnum.InterfaceOperation, OperationData.class);
479                                                 if (opRes.isRight()) {
480                                                         log.error("Failed to find operation  {} on interface {}", operationName, interfaceName);
481                                                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationRes.right().value()));
482
483                                                 } else {
484                                                         List<ImmutablePair<OperationData, GraphEdge>> parentOperations = opRes.left().value();
485                                                         for (ImmutablePair<OperationData, GraphEdge> operationPairEdge : parentOperations) {
486                                                                 GraphEdge opEdge = operationPairEdge.getRight();
487                                                                 OperationData opData = operationPairEdge.getLeft();
488                                                                 Map<String, Object> opEdgeProp = opEdge.getProperties();
489                                                                 if (opEdgeProp.get(GraphPropertiesDictionary.NAME.getProperty()).equals(operationName)) {
490                                                                         return copyAndCreateNewOperation(operation, interfaceName, operationName, null, interfaceData, operationRes, opData);
491                                                                 }
492                                                         }
493                                                 }
494
495                                         }
496
497                                 }
498
499                         } else {
500                                 // not found
501                                 storageOperationStatus = StorageOperationStatus.ARTIFACT_NOT_FOUND;
502                         }
503
504                 }
505                 if (newOperation == null)
506                         return Either.right(storageOperationStatus);
507                 else
508                         return Either.left(newOperation);
509         }
510
511         private Either<Operation, StorageOperationStatus> copyAndCreateNewOperation(Operation operation, String interfaceName, String operationName, Operation newOperation, InterfaceData interfaceData,
512                         Either<List<ImmutablePair<OperationData, GraphEdge>>, TitanOperationStatus> operationRes, OperationData opData) {
513                 OperationDataDefinition opDataInfo = opData.getOperationDataDefinition();
514                 OperationDataDefinition newOperationInfo = new OperationDataDefinition(opDataInfo);
515                 newOperationInfo.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(interfaceData.getUniqueId(), operationName.toLowerCase()));
516                 OperationData newopData = new OperationData(newOperationInfo);
517                 Either<OperationData, TitanOperationStatus> operationStatus = createOperationNodeAndRelation(operationName, newopData, interfaceData);
518                 if (operationStatus.isRight()) {
519                         log.error("Failed to create operation  {} on interface {}", operationName, interfaceName);
520                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationRes.right().value()));
521                 }
522                 ArtifactDefinition artifact = operation.getImplementationArtifact();
523                 if (artifact != null) {
524                         Either<ArtifactDefinition, StorageOperationStatus> artStatus = artifactOperation.addArifactToComponent(artifact, (String) operationStatus.left().value().getUniqueId(), NodeTypeEnum.InterfaceOperation, true, true);
525                         if (artStatus.isRight()) {
526                                 titanGenericDao.rollback();
527                                 log.error("Failed to add artifact {} to interface {}", operationName, interfaceName);
528                         } else {
529                                 newOperation = this.convertOperationDataToOperation(opData);
530                                 newOperation.setImplementation(artStatus.left().value());
531
532                         }
533                 }
534                 return Either.left(newOperation);
535         }
536
537         private Either<Operation, StorageOperationStatus> updateOperationFromParentNode(Operation operation, String resourceId, String interfaceName, String operationName) {
538                 // Operation newOperation = null;
539                 ResourceMetadataData resourceData = new ResourceMetadataData();
540                 resourceData.getMetadataDataDefinition().setUniqueId(resourceId);
541                 Either<InterfaceData, TitanOperationStatus> parentInterfaceStatus = findInterfaceOnParentNode(resourceId, interfaceName);
542                 if (parentInterfaceStatus.isRight()) {
543                         log.debug("Interface {} not exist", interfaceName);
544                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(parentInterfaceStatus.right().value()));
545                 }
546
547                 InterfaceData interfaceData = parentInterfaceStatus.left().value();
548                 InterfaceDataDefinition intDataDefinition = interfaceData.getInterfaceDataDefinition();
549                 InterfaceDataDefinition newInterfaceInfo = new InterfaceDataDefinition(intDataDefinition);
550
551                 String interfaceNameSplitted = getShortInterfaceName(intDataDefinition);
552
553                 newInterfaceInfo.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(resourceId, interfaceNameSplitted));
554                 InterfaceData updatedInterfaceData = new InterfaceData(newInterfaceInfo);
555                 Either<InterfaceData, TitanOperationStatus> createStatus = createInterfaceNodeAndRelation(interfaceName, resourceId, updatedInterfaceData, resourceData);
556                 if (createStatus.isRight()) {
557                         log.debug("failed to create interface node  {} on resource  {}", interfaceName,  resourceId);
558                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(createStatus.right().value()));
559                 }
560
561                 InterfaceData newInterfaceNode = createStatus.left().value();
562                 Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(newInterfaceNode, interfaceData, GraphEdgeLabels.DERIVED_FROM, null);
563                 if (createRelResult.isRight()) {
564                         TitanOperationStatus operationStatus = createRelResult.right().value();
565                         log.error("Failed to associate interface {} to interface {} in graph. status is {}", interfaceData.getUniqueId(), newInterfaceNode.getUniqueId(),  operationStatus);
566
567                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationStatus));
568                 }
569                 Either<List<ImmutablePair<OperationData, GraphEdge>>, TitanOperationStatus> operationRes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), (String) interfaceData.getUniqueId(),
570                                 GraphEdgeLabels.INTERFACE_OPERATION, NodeTypeEnum.InterfaceOperation, OperationData.class);
571                 if (operationRes.isRight()) {
572                         log.error("Failed to find operation  {} on interface {}", operationName, interfaceName);
573                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationRes.right().value()));
574
575                 } else {
576                         List<ImmutablePair<OperationData, GraphEdge>> operations = operationRes.left().value();
577                         for (ImmutablePair<OperationData, GraphEdge> operationPairEdge : operations) {
578                                 GraphEdge opEdge = operationPairEdge.getRight();
579                                 OperationData opData = operationPairEdge.getLeft();
580                                 Map<String, Object> opEdgeProp = opEdge.getProperties();
581                                 if (opEdgeProp.get(GraphPropertiesDictionary.NAME.getProperty()).equals(operationName)) {
582
583                                         return copyAndCreateNewOperation(operation, interfaceName, operationName, null, // changed
584                                                                                                                                                                                                         // from
585                                                                                                                                                                                                         // newOperation
586                                                         newInterfaceNode, operationRes, opData);
587
588                                 }
589                         }
590                 }
591                 return Either.right(StorageOperationStatus.GENERAL_ERROR);
592         }
593
594         private Either<InterfaceData, TitanOperationStatus> findInterfaceOnParentNode(String resourceId, String interfaceName) {
595
596                 Either<ImmutablePair<ResourceMetadataData, GraphEdge>, TitanOperationStatus> parentRes = titanGenericDao.getChild(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), resourceId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource,
597                                 ResourceMetadataData.class);
598                 if (parentRes.isRight()) {
599                         log.debug("interface {} not found ", interfaceName);
600                         return Either.right(parentRes.right().value());
601                 }
602                 ImmutablePair<ResourceMetadataData, GraphEdge> parenNode = parentRes.left().value();
603
604                 Either<List<ImmutablePair<InterfaceData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), parenNode.getKey().getMetadataDataDefinition().getUniqueId(),
605                                 GraphEdgeLabels.INTERFACE, NodeTypeEnum.Interface, InterfaceData.class);
606                 if (childrenNodes.isRight()) {
607                         return findInterfaceOnParentNode(parenNode.getKey().getMetadataDataDefinition().getUniqueId(), interfaceName);
608
609                 } else {
610                         for (ImmutablePair<InterfaceData, GraphEdge> interfaceDataNode : childrenNodes.left().value()) {
611
612                                 GraphEdge interfaceEdge = interfaceDataNode.getRight();
613                                 Map<String, Object> interfaceEdgeProp = interfaceEdge.getProperties();
614
615                                 if (interfaceEdgeProp.get(GraphPropertiesDictionary.NAME.getProperty()).equals(interfaceName)) {
616                                         return Either.left(interfaceDataNode.getKey());
617                                 }
618
619                         }
620                         return findInterfaceOnParentNode(parenNode.getKey().getMetadataDataDefinition().getUniqueId(), interfaceName);
621                 }
622
623         }
624
625         @Override
626         public Either<InterfaceDefinition, StorageOperationStatus> createInterfaceOnResource(InterfaceDefinition interf, String resourceId, String interfaceName, boolean failIfExist, boolean inTransaction) {
627
628                 Either<InterfaceData, TitanOperationStatus> status = addInterfaceToGraph(interf, interfaceName, resourceId);
629
630                 if (status.isRight()) {
631                         titanGenericDao.rollback();
632                         log.error("Failed to add interface {} to resource {}", interfaceName, resourceId);
633                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status.right().value()));
634                 } else {
635
636                         if (false == inTransaction) {
637                                 titanGenericDao.commit();
638                         }
639                         InterfaceData interfaceData = status.left().value();
640
641                         InterfaceDefinition interfaceDefResult = convertInterfaceDataToInterfaceDefinition(interfaceData);
642                         Map<String, Operation> operations = interf.getOperationsMap();
643                         if (operations != null && !operations.isEmpty()) {
644                                 Set<String> opNames = operations.keySet();
645                                 Map<String, Operation> newOperations = new HashMap<String, Operation>();
646                                 for (String operationName : opNames) {
647
648                                         Operation op = operations.get(operationName);
649                                         Either<OperationData, TitanOperationStatus> opStatus = addOperationToGraph(interf, operationName, op, interfaceData);
650                                         if (status.isRight()) {
651                                                 titanGenericDao.rollback();
652                                                 log.error("Failed to add operation {} to interface {}", operationName, interfaceName);
653                                         } else if (status.isLeft()) {
654                                                 if (false == inTransaction) {
655                                                         titanGenericDao.commit();
656                                                 }
657                                                 OperationData opData = opStatus.left().value();
658                                                 Operation newOperation = this.convertOperationDataToOperation(opData);
659
660                                                 ArtifactDefinition art = op.getImplementationArtifact();
661                                                 if (art != null) {
662                                                         Either<ArtifactDefinition, StorageOperationStatus> artRes = artifactOperation.addArifactToComponent(art, (String) opData.getUniqueId(), NodeTypeEnum.InterfaceOperation, failIfExist, true);
663                                                         if (artRes.isRight()) {
664                                                                 titanGenericDao.rollback();
665                                                                 log.error("Failed to add artifact {} to interface {}", operationName, interfaceName);
666                                                         } else {
667                                                                 newOperation.setImplementation(artRes.left().value());
668                                                         }
669                                                         newOperations.put(operationName, newOperation);
670                                                 }
671                                         }
672                                 }
673                                 interfaceDefResult.setOperationsMap(newOperations);
674                         }
675                         log.debug("The returned InterfaceDefintion is {}", interfaceDefResult);
676                         return Either.left(interfaceDefResult);
677                 }
678
679         }
680
681         @Override
682         public Either<Operation, StorageOperationStatus> deleteInterfaceOperation(String resourceId, String interfaceName, String operationId, boolean inTransaction) {
683
684                 Either<Operation, TitanOperationStatus> status = removeOperationOnGraph(resourceId, interfaceName, operationId);
685                 if (status.isRight()) {
686                         if (false == inTransaction) {
687                                 titanGenericDao.rollback();
688                         }
689                         log.error("Failed to delete operation {} of interface {} resource {}", operationId, interfaceName, resourceId);
690                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status.right().value()));
691                 } else {
692                         if (false == inTransaction) {
693                                 titanGenericDao.commit();
694                         }
695
696                         Operation opDefResult = status.left().value();// convertOperationDataToOperation(operationData);
697                         log.debug("The returned Operation is {}", opDefResult);
698                         return Either.left(opDefResult);
699                 }
700
701         }
702
703         private Either<Operation, TitanOperationStatus> removeOperationOnGraph(String resourceId, String interfaceName, String operationId) {
704                 log.debug("Before deleting operation from graph {}", operationId);
705
706                 Either<List<ImmutablePair<InterfaceData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), resourceId, GraphEdgeLabels.INTERFACE, NodeTypeEnum.Interface,
707                                 InterfaceData.class);
708
709                 if (childrenNodes.isRight()) {
710                         log.debug("Not found interface {}", interfaceName);
711                         return Either.right(childrenNodes.right().value());
712                 }
713                 OperationData opData = null;
714                 for (ImmutablePair<InterfaceData, GraphEdge> interfaceDataNode : childrenNodes.left().value()) {
715
716                         GraphEdge interfaceEdge = interfaceDataNode.getRight();
717                         Map<String, Object> interfaceEdgeProp = interfaceEdge.getProperties();
718
719                         String interfaceSplitedName = splitType(interfaceName);
720
721                         if (interfaceEdgeProp.get(GraphPropertiesDictionary.NAME.getProperty()).equals(interfaceSplitedName)) {
722                                 Either<List<ImmutablePair<OperationData, GraphEdge>>, TitanOperationStatus> operationRes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), (String) interfaceDataNode.getLeft().getUniqueId(),
723                                                 GraphEdgeLabels.INTERFACE_OPERATION, NodeTypeEnum.InterfaceOperation, OperationData.class);
724                                 if (operationRes.isRight()) {
725                                         log.error("Failed to find operation {} on interface {}", operationId, interfaceName);
726                                         return Either.right(operationRes.right().value());
727                                 }
728                                 List<ImmutablePair<OperationData, GraphEdge>> operations = operationRes.left().value();
729
730                                 for (ImmutablePair<OperationData, GraphEdge> operationPairEdge : operations) {
731
732                                         opData = operationPairEdge.getLeft();
733                                         if (opData.getUniqueId().equals(operationId)) {
734
735                                                 Either<ImmutablePair<ArtifactData, GraphEdge>, TitanOperationStatus> artifactRes = titanGenericDao.getChild(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), (String) operationPairEdge.getLeft().getUniqueId(),
736                                                                 GraphEdgeLabels.ARTIFACT_REF, NodeTypeEnum.ArtifactRef, ArtifactData.class);
737                                                 Either<ArtifactDefinition, StorageOperationStatus> arStatus = null;
738                                                 if (artifactRes.isLeft()) {
739                                                         ArtifactData arData = artifactRes.left().value().getKey();
740                                                         arStatus = artifactOperation.removeArifactFromResource((String) operationPairEdge.getLeft().getUniqueId(), (String) arData.getUniqueId(), NodeTypeEnum.InterfaceOperation, true, true);
741                                                         if (arStatus.isRight()) {
742                                                                 log.debug("failed to delete artifact {}", arData.getUniqueId());
743                                                                 return Either.right(TitanOperationStatus.INVALID_ID);
744                                                         }
745                                                 }
746                                                 Either<OperationData, TitanOperationStatus> deleteOpStatus = titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.InterfaceOperation), opData.getUniqueId(), OperationData.class);
747                                                 if (deleteOpStatus.isRight()) {
748                                                         log.debug("failed to delete operation {}", opData.getUniqueId());
749                                                         return Either.right(TitanOperationStatus.INVALID_ID);
750                                                 }
751                                                 opData = deleteOpStatus.left().value();
752                                                 Operation operation = new Operation(opData.getOperationDataDefinition());
753                                                 if (arStatus != null) {
754                                                         operation.setImplementation(arStatus.left().value());
755                                                 }
756                                                 if (operations.size() <= 1) {
757                                                         Either<InterfaceData, TitanOperationStatus> deleteInterfaceStatus = titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Interface), interfaceDataNode.left.getUniqueId(), InterfaceData.class);
758                                                         if (deleteInterfaceStatus.isRight()) {
759                                                                 log.debug("failed to delete interface {}", interfaceDataNode.left.getUniqueId());
760                                                                 return Either.right(TitanOperationStatus.INVALID_ID);
761                                                         }
762
763                                                 }
764
765                                                 return Either.left(operation);
766
767                                         }
768                                 }
769                         }
770                 }
771
772                 log.debug("Not found operation {}", interfaceName);
773                 return Either.right(TitanOperationStatus.INVALID_ID);
774         }
775
776         private String splitType(String interfaceName) {
777                 String interfaceSplittedName;
778                 String[] packageName = interfaceName.split("\\.");
779
780                 if (packageName.length == 0) {
781                         interfaceSplittedName = interfaceName;
782                 } else {
783                         interfaceSplittedName = packageName[packageName.length - 1];
784                 }
785
786                 return interfaceSplittedName.toLowerCase();
787         }
788
789         /**
790          * FOR TEST ONLY
791          * 
792          * @param titanGenericDao
793          */
794         public void setTitanGenericDao(TitanGenericDao titanGenericDao) {
795                 this.titanGenericDao = titanGenericDao;
796         }
797
798         public void setArtifactOperation(ArtifactOperation artifactOperation) {
799                 this.artifactOperation = artifactOperation;
800         }
801
802         @Override
803         public Either<InterfaceDefinition, StorageOperationStatus> createInterfaceType(InterfaceDefinition interf, boolean inTransaction) {
804                 Either<InterfaceDefinition, StorageOperationStatus> result = null;
805                 try {
806
807                         InterfaceData interfaceData = new InterfaceData(interf);
808                         interf.setUniqueId(interf.getType().toLowerCase());
809
810                         Either<InterfaceData, TitanOperationStatus> existInterface = titanGenericDao.getNode(interfaceData.getUniqueIdKey(), interfaceData.getUniqueId(), InterfaceData.class);
811
812                         if (existInterface.isLeft()) {
813                                 // already exist
814                                 log.debug("Interface type already exist {}", interfaceData);
815                                 result = Either.right(StorageOperationStatus.ENTITY_ALREADY_EXISTS);
816                                 return result;
817                         }
818
819                         log.debug("Before adding interface type to graph {}", interfaceData);
820                         Either<InterfaceData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(interfaceData, InterfaceData.class);
821                         log.debug("After adding property type to graph {}", interfaceData);
822
823                         if (createNodeResult.isRight()) {
824                                 TitanOperationStatus operationStatus = createNodeResult.right().value();
825                                 log.error("Failed to add interface {} to graph. status is {}", interf.getType(), operationStatus);
826                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationStatus));
827                                 return result;
828                         }
829
830                         InterfaceDefinition interfaceDefResult = convertInterfaceDataToInterfaceDefinition(interfaceData);
831                         Map<String, Operation> operations = interf.getOperationsMap();
832
833                         if (operations != null && !operations.isEmpty()) {
834                                 Map<String, Operation> newOperations = new HashMap<String, Operation>();
835
836                                 for (Map.Entry<String, Operation> operation : operations.entrySet()) {
837                                         Either<OperationData, TitanOperationStatus> opStatus = addOperationToGraph(interf, operation.getKey(), operation.getValue(), interfaceData);
838                                         if (opStatus.isRight()) {
839                                                 titanGenericDao.rollback();
840                                                 log.error("Failed to add operation {} to interface {}", operation.getKey(), interf.getType());
841
842                                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(opStatus.right().value()));
843                                                 return result;
844                                         } else {
845                                                 OperationData opData = opStatus.left().value();
846                                                 Operation newOperation = this.convertOperationDataToOperation(opData);
847                                                 newOperations.put(operation.getKey(), newOperation);
848                                         }
849                                 }
850                                 interfaceDefResult.setOperationsMap(newOperations);
851                         }
852                         result = Either.left(interfaceDefResult);
853                         return result;
854                 } finally {
855                         if (false == inTransaction) {
856                                 if (result == null || result.isRight()) {
857                                         log.error("Going to execute rollback on graph.");
858                                         titanGenericDao.rollback();
859                                 } else {
860                                         log.debug("Going to execute commit on graph.");
861                                         titanGenericDao.commit();
862                                 }
863                         }
864                 }
865
866         }
867
868         @Override
869         public Either<InterfaceDefinition, StorageOperationStatus> getInterface(String interfaceId) {
870                 Either<InterfaceData, TitanOperationStatus> getResult = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Interface), interfaceId, InterfaceData.class);
871                 if (getResult.isLeft()) {
872                         InterfaceData interfaceData = getResult.left().value();
873                         return Either.left(convertInterfaceDataToInterfaceDefinition(interfaceData));
874                 } else {
875                         TitanOperationStatus titanStatus = getResult.right().value();
876                         log.debug("Node with id {} was not found in the graph. status: {}", interfaceId, titanStatus);
877                         StorageOperationStatus storageOperationStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(titanStatus);
878                         return Either.right(storageOperationStatus);
879                 }
880         }
881
882         public String getShortInterfaceName(InterfaceDataDefinition interfaceDefinition) {
883                 String[] packageName = interfaceDefinition.getType().split("\\.");
884                 String interfaceName;
885                 if (packageName.length == 0) {
886                         interfaceName = interfaceDefinition.getType();
887                 } else {
888                         interfaceName = packageName[packageName.length - 1];
889                 }
890                 return interfaceName.toLowerCase();
891         }
892
893         /** 
894          * 
895          */
896         public Either<InterfaceDefinition, StorageOperationStatus> createInterfaceType(InterfaceDefinition interf) {
897                 return createInterfaceType(interf, false);
898         }
899
900 }