500 error at WFD artifact-deliveries api
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / InterfaceOperationBusinessLogic.java
1 /*
2  * Copyright © 2016-2018 European Support Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17
18 package org.openecomp.sdc.be.components.impl;
19
20 import com.google.gson.Gson;
21 import fj.data.Either;
22 import org.apache.commons.collections4.CollectionUtils;
23 import org.apache.commons.collections4.MapUtils;
24 import org.apache.commons.lang3.tuple.ImmutablePair;
25 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
26 import org.openecomp.sdc.be.components.utils.InterfaceOperationUtils;
27 import org.openecomp.sdc.be.components.validation.InterfaceOperationValidation;
28 import org.openecomp.sdc.be.dao.api.ActionStatus;
29 import org.openecomp.sdc.be.dao.cassandra.ArtifactCassandraDao;
30 import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus;
31 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
32 import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
33 import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
34 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
35 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
36 import org.openecomp.sdc.be.model.ArtifactDefinition;
37 import org.openecomp.sdc.be.model.CapabilityDefinition;
38 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
39 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
40 import org.openecomp.sdc.be.model.InputDefinition;
41 import org.openecomp.sdc.be.model.InterfaceDefinition;
42 import org.openecomp.sdc.be.model.Operation;
43 import org.openecomp.sdc.be.model.User;
44 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
45 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
46 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
47 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
48 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
49 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
50 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
51 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
52 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
53 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
54 import org.openecomp.sdc.exception.ResponseFormat;
55 import org.slf4j.Logger;
56 import org.slf4j.LoggerFactory;
57 import org.springframework.beans.factory.annotation.Autowired;
58 import org.springframework.stereotype.Component;
59
60 import java.util.ArrayList;
61 import java.util.Collection;
62 import java.util.Collections;
63 import java.util.HashMap;
64 import java.util.List;
65 import java.util.Map;
66 import java.util.Objects;
67 import java.util.Optional;
68 import java.util.UUID;
69 import java.util.stream.Collectors;
70
71 import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.createMappedCapabilityPropertyDefaultValue;
72 import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.createMappedInputPropertyDefaultValue;
73 import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.createMappedOutputDefaultValue;
74 import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.getInterfaceDefinitionFromComponentByInterfaceId;
75 import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.getInterfaceDefinitionFromComponentByInterfaceType;
76 import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.getOperationFromInterfaceDefinition;
77 import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.isOperationInputMappedToComponentInput;
78 import static org.openecomp.sdc.be.components.utils.PropertiesUtils.getPropertyCapabilityFromAllCapProps;
79 import static org.openecomp.sdc.be.components.utils.PropertiesUtils.isCapabilityProperty;
80 import static org.openecomp.sdc.be.tosca.InterfacesOperationsConverter.SELF;
81
82 @Component("interfaceOperationBusinessLogic")
83 public class InterfaceOperationBusinessLogic extends BaseBusinessLogic {
84
85     private static final Logger LOGGER = LoggerFactory.getLogger(InterfaceOperationBusinessLogic.class);
86     private static final String EXCEPTION_OCCURRED_DURING_INTERFACE_OPERATION =
87             "Exception occurred during {}. Response is {}";
88     private static final String DELETE_INTERFACE_OPERATION = "deleteInterfaceOperation";
89     private static final String GET_INTERFACE_OPERATION = "getInterfaceOperation";
90     private static final String CREATE_INTERFACE_OPERATION = "createInterfaceOperation";
91     private static final String UPDATE_INTERFACE_OPERATION = "updateInterfaceOperation";
92
93     private final ArtifactCassandraDao artifactCassandraDao;
94     private final InterfaceOperationValidation interfaceOperationValidation;
95
96     @Autowired
97     public InterfaceOperationBusinessLogic(IElementOperation elementDao,
98         IGroupOperation groupOperation,
99         IGroupInstanceOperation groupInstanceOperation,
100         IGroupTypeOperation groupTypeOperation,
101         InterfaceOperation interfaceOperation,
102         InterfaceLifecycleOperation interfaceLifecycleTypeOperation, ArtifactCassandraDao artifactCassandraDao,
103         InterfaceOperationValidation interfaceOperationValidation, ArtifactsOperations artifactToscaOperation) {
104         super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation,
105             interfaceOperation, interfaceLifecycleTypeOperation, artifactToscaOperation);
106         this.artifactCassandraDao = artifactCassandraDao;
107         this.interfaceOperationValidation = interfaceOperationValidation;
108     }
109
110     public Either<List<InterfaceDefinition>, ResponseFormat> deleteInterfaceOperation(String componentId,
111             String interfaceId, List<String> operationsToDelete, User user, boolean lock) {
112         validateUserExists(user.getUserId());
113
114         Either<org.openecomp.sdc.be.model.Component, ResponseFormat> componentEither = getComponentDetails(componentId);
115         if (componentEither.isRight()) {
116             return Either.right(componentEither.right().value());
117         }
118         org.openecomp.sdc.be.model.Component storedComponent = componentEither.left().value();
119
120         lockComponentResult(lock, storedComponent, DELETE_INTERFACE_OPERATION);
121
122
123         try {
124             Optional<InterfaceDefinition> optionalInterface = getInterfaceDefinitionFromComponentByInterfaceId(
125                     storedComponent, interfaceId);
126             if (!optionalInterface.isPresent()) {
127                 return Either.right(
128                         componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceId));
129             }
130             InterfaceDefinition interfaceDefinition = optionalInterface.get();
131
132             Map<String, Operation> operationsCollection = new HashMap<>();
133             for (String operationId : operationsToDelete) {
134                 Optional<Map.Entry<String, Operation>> optionalOperation =
135                         getOperationFromInterfaceDefinition(interfaceDefinition, operationId);
136                 if (!optionalOperation.isPresent()) {
137                     return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND,
138                             storedComponent.getUniqueId()));
139                 }
140
141                 Operation storedOperation = optionalOperation.get().getValue();
142                 Either<Boolean, ResponseFormat> validateDeleteOperationContainsNoMappedOutputResponse =
143                         interfaceOperationValidation.validateDeleteOperationContainsNoMappedOutput(storedOperation,
144                                 storedComponent, interfaceDefinition);
145                 if (validateDeleteOperationContainsNoMappedOutputResponse.isRight()) {
146                     return Either.right(validateDeleteOperationContainsNoMappedOutputResponse.right().value());
147                 }
148
149                 String artifactUniqueId = storedOperation.getImplementation().getUniqueId();
150                 if(!InterfaceOperationUtils.isArtifactInUse(storedComponent, operationId, artifactUniqueId)){
151                     Either<ArtifactDefinition, StorageOperationStatus> getArtifactEither =
152                             artifactToscaOperation.getArtifactById(storedComponent.getUniqueId(), artifactUniqueId);
153                     if(getArtifactEither.isLeft()){
154                         Either<ArtifactDefinition, StorageOperationStatus> removeArifactFromComponent =
155                                 artifactToscaOperation.removeArifactFromResource(componentId, artifactUniqueId,
156                                         NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue()),
157                                         true);
158                         if(removeArifactFromComponent.isRight()){
159                             janusGraphDao.rollback();
160                             ResponseFormat responseFormatByArtifactId = componentsUtils.getResponseFormatByArtifactId(
161                                     componentsUtils.convertFromStorageResponse(removeArifactFromComponent.right().value()),
162                                     storedOperation.getImplementation().getArtifactDisplayName());
163                             return Either.right(responseFormatByArtifactId);
164                         }
165
166                         CassandraOperationStatus cassandraStatus = artifactCassandraDao.deleteArtifact(artifactUniqueId);
167                         if (cassandraStatus != CassandraOperationStatus.OK) {
168                             janusGraphDao.rollback();
169                             ResponseFormat responseFormatByArtifactId = componentsUtils.getResponseFormatByArtifactId(
170                                     componentsUtils.convertFromStorageResponse(
171                                             componentsUtils.convertToStorageOperationStatus(cassandraStatus)),
172                                     storedOperation.getImplementation().getArtifactDisplayName());
173                             return Either.right(responseFormatByArtifactId);
174                         }
175                     }
176                 }
177
178                 operationsCollection.put(operationId, interfaceDefinition.getOperationsMap().get(operationId));
179                 interfaceDefinition.getOperations().remove(operationId);
180             }
181
182             Either<List<InterfaceDefinition>, StorageOperationStatus> deleteOperationEither =
183                     interfaceOperation.updateInterfaces(storedComponent.getUniqueId(),
184                             Collections.singletonList(interfaceDefinition));
185             if (deleteOperationEither.isRight()) {
186                 janusGraphDao.rollback();
187                 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(
188                         deleteOperationEither.right().value(), storedComponent.getComponentType())));
189             }
190
191             if (interfaceDefinition.getOperations().isEmpty()) {
192                 Either<String, StorageOperationStatus> deleteInterfaceEither = interfaceOperation.deleteInterface(
193                         storedComponent.getUniqueId(), interfaceDefinition.getUniqueId());
194                 if (deleteInterfaceEither.isRight()) {
195                     janusGraphDao.rollback();
196                     return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(
197                             deleteInterfaceEither.right().value(), storedComponent.getComponentType())));
198                 }
199             }
200
201             janusGraphDao.commit();
202             interfaceDefinition.getOperations().putAll(operationsCollection);
203             interfaceDefinition.getOperations().keySet().removeIf(key -> !(operationsToDelete.contains(key)));
204             return Either.left(Collections.singletonList(interfaceDefinition));
205         } catch (Exception e) {
206             LOGGER.error(EXCEPTION_OCCURRED_DURING_INTERFACE_OPERATION, "delete", e);
207             janusGraphDao.rollback();
208             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_DELETED));
209         } finally {
210             graphLockOperation.unlockComponent(storedComponent.getUniqueId(),
211                     NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue()));
212         }
213     }
214
215     private Either<org.openecomp.sdc.be.model.Component, ResponseFormat> getComponentDetails(String componentId) {
216         Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> componentStorageOperationStatusEither =
217                 toscaOperationFacade.getToscaElement(componentId);
218         if (componentStorageOperationStatusEither.isRight()) {
219             return Either.right(componentsUtils.getResponseFormat(
220                     componentsUtils.convertFromStorageResponse(componentStorageOperationStatusEither.right().value())));
221         }
222         return Either.left(componentStorageOperationStatusEither.left().value());
223     }
224
225     private Either<Boolean, ResponseFormat> lockComponentResult(boolean lock,
226             org.openecomp.sdc.be.model.Component component, String action) {
227         if (lock) {
228             try {
229                 lockComponent(component.getUniqueId(), component, action);
230             } catch (ComponentException e) {
231             janusGraphDao.rollback();
232             throw e;
233         }
234     }
235         return Either.left(true);
236     }
237
238     public Either<List<InterfaceDefinition>, ResponseFormat> getInterfaceOperation(String componentId,
239             String interfaceId, List<String> operationsToGet, User user, boolean lock) {
240         validateUserExists(user);
241
242         Either<org.openecomp.sdc.be.model.Component, ResponseFormat> componentEither = getComponentDetails(componentId);
243         if (componentEither.isRight()) {
244             return Either.right(componentEither.right().value());
245         }
246         org.openecomp.sdc.be.model.Component storedComponent = componentEither.left().value();
247
248         lockComponentResult(lock, storedComponent, GET_INTERFACE_OPERATION);
249
250         try {
251             Optional<InterfaceDefinition> optionalInterface = getInterfaceDefinitionFromComponentByInterfaceId(
252                     storedComponent, interfaceId);
253             if (!optionalInterface.isPresent()) {
254                 return Either.right(
255                         componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceId));
256             }
257             InterfaceDefinition interfaceDefinition = optionalInterface.get();
258
259             for (String operationId : operationsToGet) {
260                 Optional<Map.Entry<String, Operation>> optionalOperation =
261                         getOperationFromInterfaceDefinition(interfaceDefinition, operationId);
262                 if (!optionalOperation.isPresent()) {
263                     return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND,
264                             storedComponent.getUniqueId()));
265                 }
266             }
267
268             janusGraphDao.commit();
269             interfaceDefinition.getOperations().keySet().removeIf(key -> !(operationsToGet.contains(key)));
270             return Either.left(Collections.singletonList(interfaceDefinition));
271         } catch (Exception e) {
272             LOGGER.error(EXCEPTION_OCCURRED_DURING_INTERFACE_OPERATION, "get", e);
273             janusGraphDao.rollback();
274             return Either.right(
275                     componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, componentId));
276         } finally {
277             graphLockOperation.unlockComponent(storedComponent.getUniqueId(),
278                     NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue()));
279         }
280     }
281
282     public Either<List<InterfaceDefinition>, ResponseFormat> createInterfaceOperation(String componentId,
283             List<InterfaceDefinition> interfaceDefinitions, User user, boolean lock) {
284         return createOrUpdateInterfaceOperation(componentId, interfaceDefinitions, user, false,
285                 CREATE_INTERFACE_OPERATION, lock);
286     }
287
288     private Either<List<InterfaceDefinition>, ResponseFormat> createOrUpdateInterfaceOperation(String componentId,
289             List<InterfaceDefinition> interfaceDefinitions, User user, boolean isUpdate, String errorContext,
290             boolean lock) {
291         validateUserExists(user);
292
293         Either<org.openecomp.sdc.be.model.Component, ResponseFormat> componentEither = getComponentDetails(componentId);
294         if (componentEither.isRight()) {
295             return Either.right(componentEither.right().value());
296         }
297         org.openecomp.sdc.be.model.Component storedComponent = componentEither.left().value();
298
299         lockComponentResult(lock, storedComponent, errorContext);
300
301
302         Either<Map<String, InterfaceDefinition>, ResponseFormat> interfaceLifecycleTypes =
303                 getAllInterfaceLifecycleTypes();
304         if (interfaceLifecycleTypes.isRight()) {
305             return Either.right(interfaceLifecycleTypes.right().value());
306         }
307
308         try {
309             List<InterfaceDefinition> interfacesCollection = new ArrayList<>();
310             Map<String, Operation> operationsCollection = new HashMap<>();
311             for (InterfaceDefinition inputInterfaceDefinition : interfaceDefinitions) {
312                 Optional<InterfaceDefinition> optionalInterface =
313                         getInterfaceDefinitionFromComponentByInterfaceType(
314                                 storedComponent, inputInterfaceDefinition.getType());
315                 Either<Boolean, ResponseFormat> interfaceOperationValidationResponseEither =
316                         interfaceOperationValidation
317                                 .validateInterfaceOperations(inputInterfaceDefinition, storedComponent,
318                                         optionalInterface.orElse(null), interfaceLifecycleTypes.left().value(),
319                                         isUpdate);
320                 if (interfaceOperationValidationResponseEither.isRight()) {
321                     return Either.right(interfaceOperationValidationResponseEither.right().value());
322                 }
323
324                 Map<String, Operation> operationsToAddOrUpdate = inputInterfaceDefinition.getOperationsMap();
325                 operationsCollection.putAll(operationsToAddOrUpdate);
326                 inputInterfaceDefinition.getOperations().clear();
327
328                 Either<InterfaceDefinition, ResponseFormat> getInterfaceEither =
329                         getOrCreateInterfaceDefinition(storedComponent, inputInterfaceDefinition,
330                                 optionalInterface.orElse(null));
331                 if (getInterfaceEither.isRight()) {
332                     return Either.right(getInterfaceEither.right().value());
333                 }
334                 InterfaceDefinition interfaceDef = getInterfaceEither.left().value();
335
336                 updateOperationInputDefs(storedComponent, operationsToAddOrUpdate.values());
337
338                 for (Operation operation : operationsToAddOrUpdate.values()) {
339                     if (!isUpdate) {
340                         addOperationToInterface(interfaceDef, operation);
341                     } else {
342                         Optional<Map.Entry<String, Operation>> optionalOperation =
343                                 getOperationFromInterfaceDefinition(interfaceDef,
344                                         operation.getUniqueId());
345                         if (!optionalOperation.isPresent()) {
346                             janusGraphDao.rollback();
347                             return Either.right(componentsUtils
348                                                         .getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND,
349                                                                 storedComponent.getUniqueId()));
350                         }
351
352                         Operation storedOperation = optionalOperation.get().getValue();
353                         String artifactUuId = storedOperation.getImplementation().getArtifactUUID();
354                         String artifactUniqueId = storedOperation.getImplementation().getUniqueId();
355
356                         if(!InterfaceOperationUtils.isArtifactInUse(storedComponent, storedOperation.getUniqueId(), artifactUniqueId)){
357                             Either<ArtifactDefinition, StorageOperationStatus> getArtifactEither =
358                                     artifactToscaOperation.getArtifactById(storedComponent.getUniqueId(), artifactUniqueId);
359                             if(getArtifactEither.isLeft()){
360                                 Either<ArtifactDefinition, StorageOperationStatus> removeArifactFromComponent =
361                                         artifactToscaOperation.removeArifactFromResource(componentId, artifactUniqueId,
362                                                 NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue()),
363                                                 true);
364                                 if(removeArifactFromComponent.isRight()){
365                                     janusGraphDao.rollback();
366                                     ResponseFormat responseFormatByArtifactId = componentsUtils.getResponseFormatByArtifactId(
367                                             componentsUtils.convertFromStorageResponse(removeArifactFromComponent.right().value()),
368                                             storedOperation.getImplementation().getArtifactDisplayName());
369                                     return Either.right(responseFormatByArtifactId);
370                                 }
371
372                                 CassandraOperationStatus cassandraStatus = artifactCassandraDao.deleteArtifact(artifactUniqueId);
373                                 if (cassandraStatus != CassandraOperationStatus.OK) {
374                                     janusGraphDao.rollback();
375                                     ResponseFormat responseFormatByArtifactId =
376                                             componentsUtils.getResponseFormatByArtifactId(
377                                                     componentsUtils.convertFromStorageResponse(
378                                                             componentsUtils.convertToStorageOperationStatus(
379                                                                     cassandraStatus)),
380                                                     storedOperation.getImplementation().getArtifactDisplayName());
381                                     return Either.right(responseFormatByArtifactId);
382                                 }
383                             }
384                         }
385                         updateOperationOnInterface(interfaceDef, operation, artifactUuId);
386                     }
387                 }
388                 interfacesCollection.add(interfaceDef);
389             }
390
391             Either<List<InterfaceDefinition>, StorageOperationStatus> addCreateOperationEither =
392                     interfaceOperation.updateInterfaces(storedComponent.getUniqueId(), interfacesCollection);
393             if (addCreateOperationEither.isRight()) {
394                 janusGraphDao.rollback();
395                 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(
396                         addCreateOperationEither.right().value(), storedComponent.getComponentType())));
397             }
398
399             janusGraphDao.commit();
400             interfacesCollection.forEach(interfaceDefinition -> interfaceDefinition.getOperations().entrySet().removeIf(
401                     entry -> !operationsCollection.values().stream().map(OperationDataDefinition::getName)
402                                       .collect(Collectors.toList()).contains(entry.getValue().getName())));
403             return Either.left(interfacesCollection);
404         } catch (Exception e) {
405             janusGraphDao.rollback();
406             LOGGER.error(EXCEPTION_OCCURRED_DURING_INTERFACE_OPERATION, "addOrUpdate", e);
407             return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
408         } finally {
409             graphLockOperation.unlockComponent(storedComponent.getUniqueId(),
410                     NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue()));
411         }
412     }
413
414     public Either<Map<String, InterfaceDefinition>, ResponseFormat> getAllInterfaceLifecycleTypes() {
415
416         Either<Map<String, InterfaceDefinition>, StorageOperationStatus> interfaceLifecycleTypes =
417                 interfaceLifecycleTypeOperation.getAllInterfaceLifecycleTypes();
418         if (interfaceLifecycleTypes.isRight()) {
419             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_LIFECYCLE_TYPES_NOT_FOUND));
420         }
421         interfaceLifecycleTypes.left().value().values().forEach(id -> id.setOperations(
422                 id.getOperations().keySet().stream().collect(Collectors.toMap(key -> key.replaceFirst(
423                         id.getUniqueId() + ".", ""), i -> id.getOperations().get(i)))));
424
425         return Either.left(interfaceLifecycleTypes.left().value());
426     }
427
428     private Either<InterfaceDefinition, ResponseFormat> getOrCreateInterfaceDefinition(
429             org.openecomp.sdc.be.model.Component component, InterfaceDefinition interfaceDefinition,
430             InterfaceDefinition storedInterfaceDef) {
431         if (storedInterfaceDef != null) {
432             return Either.left(storedInterfaceDef);
433         }
434         interfaceDefinition.setUniqueId(UUID.randomUUID().toString());
435         interfaceDefinition.setToscaResourceName(interfaceDefinition.getType());
436         Either<List<InterfaceDefinition>, StorageOperationStatus> interfaceCreateEither =
437                 interfaceOperation.addInterfaces(component.getUniqueId(),
438                         Collections.singletonList(interfaceDefinition));
439         if (interfaceCreateEither.isRight()) {
440             janusGraphDao.rollback();
441             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(
442                     interfaceCreateEither.right().value(), component.getComponentType())));
443         }
444         return Either.left(interfaceCreateEither.left().value().get(0));
445     }
446
447     private void updateOperationInputDefs(org.openecomp.sdc.be.model.Component component,
448                                           Collection<Operation> interfaceOperations) {
449         interfaceOperations.stream().filter(operation -> Objects.nonNull(operation.getInputs())).forEach(
450                 operation -> operation.getInputs().getListToscaDataDefinition().forEach(
451                         inp -> component.getInputs()
452                                 .forEach(in -> updateOperationInputDefinition(component, inp, in))));
453     }
454
455     private void updateOperationInputDefinition(org.openecomp.sdc.be.model.Component component,
456                                                 OperationInputDefinition operationInput,
457                                                 InputDefinition componentInput) {
458         if (operationInput.getInputId().equals(componentInput.getUniqueId())) {
459             //Set the default value, value and schema only for inputs mapped to component inputs
460             operationInput.setDefaultValue(componentInput.getDefaultValue());
461             operationInput.setToscaDefaultValue(getInputToscaDefaultValue(operationInput, component));
462             operationInput.setValue(componentInput.getValue());
463             operationInput.setSchema(componentInput.getSchema());
464                         operationInput.setParentPropertyType(componentInput.getParentPropertyType());
465                         operationInput.setSubPropertyInputPath(componentInput.getSubPropertyInputPath());
466         }
467         //Set the tosca default value for inputs mapped to component inputs as well as other outputs
468         operationInput.setToscaDefaultValue(getInputToscaDefaultValue(operationInput, component));
469     }
470
471     private String getInputToscaDefaultValue(OperationInputDefinition input,
472                                              org.openecomp.sdc.be.model.Component component) {
473         Map<String, List<String>> defaultInputValue = null;
474         if (isOperationInputMappedToComponentInput(input, component.getInputs())) {
475             String propertyName = input.getInputId().substring(input.getInputId().indexOf('.') + 1);
476                         setParentPropertyTypeAndInputPath(input, component);
477             defaultInputValue = createMappedInputPropertyDefaultValue(propertyName);
478         } else if (isCapabilityProperty(input.getInputId(), component).isPresent()) {
479             Optional<ComponentInstanceProperty> instancePropertyOpt = isCapabilityProperty(input.getInputId(),
480                 component);
481             Optional<String> parentPropertyIdOpt = instancePropertyOpt.map(PropertyDataDefinition::getParentUniqueId);
482             Map<String, List<CapabilityDefinition>> componentCapabilities = component.getCapabilities();
483             if(MapUtils.isNotEmpty(componentCapabilities)) {
484                 List<CapabilityDefinition> capabilityDefinitionList = componentCapabilities.values().stream()
485                     .flatMap(Collection::stream)
486                     .filter(capabilityDefinition -> capabilityDefinition.getOwnerId().equals(component.getUniqueId()))
487                     .collect(Collectors.toList());
488
489                 defaultInputValue = parentPropertyIdOpt
490                     .flatMap(parentPropertyId ->
491                         getPropertyCapabilityFromAllCapProps(parentPropertyId, capabilityDefinitionList))
492                     .flatMap(capability ->
493                         instancePropertyOpt.map(instanceProperty ->
494                             new ImmutablePair<>(capability.getName(), instanceProperty.getName())))
495                     .map(tuple -> {
496                         String propertyName = tuple.right;
497                         String capabilityName = tuple.left;
498
499                         return createMappedCapabilityPropertyDefaultValue(capabilityName, propertyName);
500                     }).orElse(null);
501             }
502         } else {
503             //Currently inputs can only be mapped to a declared input or an other operation outputs
504             defaultInputValue = createMappedOutputDefaultValue(SELF, input.getInputId());
505         }
506         return new Gson().toJson(defaultInputValue);
507     }
508
509         private void setParentPropertyTypeAndInputPath(OperationInputDefinition input,
510                                                                                                    org.openecomp.sdc.be.model.Component component) {
511                 if (CollectionUtils.isEmpty(component.getInputs())) {
512                         return;
513                 }
514
515                 component.getInputs()
516                                 .stream()
517                                 .filter(inp -> inp.getUniqueId().equals(
518                                                 input.getInputId().substring(0, input.getInputId().lastIndexOf('.'))))
519                                 .forEach(inp -> {
520                                         input.setParentPropertyType(inp.getParentPropertyType());
521                                         if (Objects.nonNull(input.getName())) {
522                                                 input.setSubPropertyInputPath(input.getName().replaceAll("\\.", "#"));
523                                         }
524                                 });
525         }
526
527     private void addOperationToInterface(InterfaceDefinition interfaceDefinition, Operation interfaceOperation) {
528         interfaceOperation.setUniqueId(UUID.randomUUID().toString());
529         interfaceOperation.setImplementation(createArtifactDefinition(UUID.randomUUID().toString(), interfaceOperation.getName()));
530         interfaceDefinition.getOperations()
531                 .put(interfaceOperation.getUniqueId(), new OperationDataDefinition(interfaceOperation));
532     }
533
534     private void updateOperationOnInterface(InterfaceDefinition interfaceDefinition, Operation interfaceOperation,
535             String artifactUuId) {
536         interfaceOperation.setImplementation(createArtifactDefinition(artifactUuId, interfaceOperation.getName()));
537         interfaceDefinition.getOperations()
538                 .put(interfaceOperation.getUniqueId(), new OperationDataDefinition(interfaceOperation));
539     }
540
541     private ArtifactDefinition createArtifactDefinition(String artifactUuId, String operationName) {
542         ArtifactDefinition artifactDefinition = new ArtifactDefinition();
543         artifactDefinition.setArtifactUUID(artifactUuId);
544         artifactDefinition.setUniqueId(artifactUuId);
545         artifactDefinition.setArtifactType(ArtifactTypeEnum.WORKFLOW.getType());
546         artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT);
547         artifactDefinition.setArtifactLabel(operationName + ".workflowArtifact");
548         return artifactDefinition;
549     }
550
551     public Either<List<InterfaceDefinition>, ResponseFormat> updateInterfaceOperation(String componentId,
552             List<InterfaceDefinition> interfaceDefinitions, User user, boolean lock) {
553         return createOrUpdateInterfaceOperation(componentId, interfaceDefinitions, user, true,
554                 UPDATE_INTERFACE_OPERATION, lock);
555     }
556
557     public Either<List<OperationInputDefinition>, ResponseFormat> getInputsListForOperation(String componentId,
558                                                                                             String componentInstanceId, String interfaceId, String operationId, User user) {
559         Either<org.openecomp.sdc.be.model.Component, ResponseFormat> componentEither = getComponentDetails(componentId);
560         if (componentEither.isRight()){
561             return Either.right(componentEither.right().value());
562         }
563
564         org.openecomp.sdc.be.model.Component storedComponent = componentEither.left().value();
565         validateUserExists(user.getUserId());
566
567         Either<Boolean, ResponseFormat> lockResult = lockComponentResult(true, storedComponent, GET_INTERFACE_OPERATION);
568         if (lockResult.isRight()) {
569             return Either.right(lockResult.right().value());
570         }
571
572         try{
573             org.openecomp.sdc.be.model.Component parentComponent = componentEither.left().value();
574             Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces =
575                     parentComponent.getComponentInstancesInterfaces();
576             if(MapUtils.isEmpty(componentInstanceInterfaces)) {
577                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND,
578                         componentInstanceId));
579             }
580
581             List<ComponentInstanceInterface> componentInstanceInterfaceList =
582                     componentInstanceInterfaces.get(componentInstanceId);
583             for(ComponentInstanceInterface componentInstanceInterface : componentInstanceInterfaceList) {
584                 if(componentInstanceInterface.getInterfaceId().equals(interfaceId)){
585                     Map<String, OperationDataDefinition> operations = componentInstanceInterface.getOperations();
586                     if(MapUtils.isNotEmpty(operations) && operations.containsKey(operationId)) {
587                         ListDataDefinition<OperationInputDefinition> inputs = operations.get(operationId).getInputs();
588                         return Either.left(CollectionUtils.isEmpty(inputs.getListToscaDataDefinition())
589                                 ? new ArrayList<>() : inputs.getListToscaDataDefinition());
590                     }
591                 }
592             }
593             return Either.left(new ArrayList<>());
594         }
595         catch (Exception e) {
596             LOGGER.error(EXCEPTION_OCCURRED_DURING_INTERFACE_OPERATION, "get", e);
597             janusGraphDao.rollback();
598             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND));
599         }
600         finally {
601             if (lockResult.isLeft() && lockResult.left().value()) {
602                 graphLockOperation.unlockComponent(storedComponent.getUniqueId(),
603                         NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue()));
604             }
605         }
606     }
607
608 }