Catalog alignment
[sdc.git] / catalog-model / src / main / java / org / openecomp / sdc / be / model / jsonjanusgraph / operations / ArtifactsOperations.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.sdc.be.model.jsonjanusgraph.operations;
22
23 import fj.data.Either;
24 import org.apache.commons.collections.MapUtils;
25 import org.apache.commons.lang.text.StrBuilder;
26 import org.apache.commons.lang3.tuple.ImmutableTriple;
27 import org.apache.commons.lang3.tuple.Triple;
28 import org.apache.tinkerpop.gremlin.structure.Direction;
29 import org.openecomp.sdc.be.config.BeEcompErrorManager;
30 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
31 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
32 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
33 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
34 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
35 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
36 import org.openecomp.sdc.be.datatypes.elements.HeatParameterDataDefinition;
37 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
38 import org.openecomp.sdc.be.datatypes.elements.MapArtifactDataDefinition;
39 import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
40 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
41 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
42 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
43 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
44 import org.openecomp.sdc.be.model.ArtifactDefinition;
45 import org.openecomp.sdc.be.model.Component;
46 import org.openecomp.sdc.be.model.HeatParameterDefinition;
47 import org.openecomp.sdc.be.model.InterfaceDefinition;
48 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
49 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
50 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
51 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
52 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
53 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
54 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
55 import org.openecomp.sdc.common.log.api.ILogConfiguration;
56 import org.openecomp.sdc.common.log.wrappers.Logger;
57 import org.openecomp.sdc.common.util.GeneralUtility;
58 import org.slf4j.MDC;
59
60 import java.util.*;
61 import java.util.Map.Entry;
62 import java.util.stream.Collectors;
63
64 @org.springframework.stereotype.Component("artifacts-operations")
65 public class ArtifactsOperations extends BaseOperation {
66     private static final String FAILED_TO_FETCH_FOR_TOSCA_ELEMENT_WITH_ID_ERROR = "failed to fetch {} for tosca element with id {}, error {}";
67         private static final Logger log = Logger.getLogger(ArtifactsOperations.class.getName());
68
69     public Either<ArtifactDefinition, StorageOperationStatus> addArtifactToComponent(ArtifactDefinition artifactInfo,
70            Component component, NodeTypeEnum type, boolean failIfExist, String instanceId) {
71
72         String parentId = component.getUniqueId();
73         String artifactId = artifactInfo.getUniqueId();
74         if (artifactId == null && artifactInfo.getEsId() != null) {
75             artifactId = artifactInfo.getEsId();
76         }
77         Either<ArtifactDataDefinition, StorageOperationStatus> status = updateArtifactOnGraph(component, artifactInfo, type, artifactId, instanceId, false, false);
78         if (status.isRight()) {
79
80             log.debug("Failed to update artifact {} of {} {}. status is {}", artifactInfo.getArtifactName(), type.getName(), parentId, status.right().value());
81             BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("Update Artifact", artifactInfo.getArtifactName(), String.valueOf(status.right().value()));
82             return Either.right(status.right().value());
83         } else {
84
85             ArtifactDataDefinition artifactData = status.left().value();
86
87             ArtifactDefinition artifactDefResult = convertArtifactDataToArtifactDefinition(artifactInfo, artifactData);
88             log.debug("The returned ArtifactDefintion is {}", artifactDefResult);
89             return Either.left(artifactDefResult);
90         }
91
92     }
93
94     public Either<ArtifactDefinition, StorageOperationStatus> updateArtifactOnResource(ArtifactDefinition artifactInfo,
95            Component component, String artifactId, NodeTypeEnum type, String instanceId, boolean isUpdate) {
96
97         String id = component.getUniqueId();
98         Either<ArtifactDataDefinition, StorageOperationStatus> status = updateArtifactOnGraph(component, artifactInfo, type, artifactId, instanceId, isUpdate, false);
99         if (status.isRight()) {
100
101             log.debug("Failed to update artifact {} of {} {}. status is {}", artifactInfo.getArtifactName(), type.getName(), id, status.right().value());
102             BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("Update Artifact", artifactInfo.getArtifactName(), String.valueOf(status.right().value()));
103             return Either.right(status.right().value());
104         } else {
105
106             ArtifactDataDefinition artifactData = status.left().value();
107
108             ArtifactDefinition artifactDefResult = convertArtifactDataToArtifactDefinition(artifactInfo, artifactData);
109             log.debug("The returned ArtifactDefinition is {}", artifactDefResult);
110             return Either.left(artifactDefResult);
111         }
112     }
113
114     public Either<Boolean, StorageOperationStatus> isCloneNeeded(String parentId, ArtifactDefinition artifactInfo, NodeTypeEnum type) {
115         ArtifactGroupTypeEnum groupType = artifactInfo.getArtifactGroupType();
116
117         Triple<EdgeLabelEnum, Boolean, VertexTypeEnum> triple = getEdgeLabelEnumFromArtifactGroupType(groupType, type);
118         EdgeLabelEnum edgeLabelEnum = triple.getLeft();
119         return super.isCloneNeeded(parentId, edgeLabelEnum);
120     }
121
122     public Either<ArtifactDefinition, StorageOperationStatus> getArtifactById(String parentId, String id) {
123         return getArtifactById(parentId, id, null, null);
124     }
125
126     public Either<ArtifactDefinition, StorageOperationStatus> getArtifactById(String parentId, String id, ComponentTypeEnum componentType, String containerId) {
127         Either<ArtifactDefinition, StorageOperationStatus> result = null;
128         ArtifactDataDefinition foundArtifact = null;
129         if (componentType != null && componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
130             foundArtifact = getInstanceArtifactByLabelAndId(parentId, id, containerId, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS);
131             if (foundArtifact == null) {
132                 foundArtifact = getInstanceArtifactByLabelAndId(parentId, id, containerId, EdgeLabelEnum.INSTANCE_ARTIFACTS);
133             }
134         }
135         if (foundArtifact == null) {
136             foundArtifact = getArtifactByLabelAndId(parentId, id, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS);
137         }
138         if (foundArtifact == null) {
139             foundArtifact = getArtifactByLabelAndId(parentId, id, EdgeLabelEnum.TOSCA_ARTIFACTS);
140         }
141
142         if (foundArtifact == null) {
143             foundArtifact = getArtifactByLabelAndId(parentId, id, EdgeLabelEnum.ARTIFACTS);
144         }
145
146         if (foundArtifact == null) {
147             foundArtifact = getArtifactByLabelAndId(parentId, id, EdgeLabelEnum.SERVICE_API_ARTIFACTS);
148         }
149                 if (foundArtifact == null) {
150                         foundArtifact = findInterfaceArtifact(parentId, id);
151
152                 }
153
154         if (foundArtifact == null) {
155             result = Either.right(StorageOperationStatus.NOT_FOUND);
156             return result;
157         }
158
159         ArtifactDefinition artifactDefResult = convertArtifactDataToArtifactDefinition(null, foundArtifact);
160         return Either.left(artifactDefResult);
161
162     }
163         private ArtifactDataDefinition findInterfaceArtifact(String parentId, String id) {
164                 Either<Map<String, InterfaceDefinition>, JanusGraphOperationStatus> dataFromGraph = getDataFromGraph(parentId, EdgeLabelEnum.INTERFACE);
165                 if (dataFromGraph.isRight()){
166                         log.debug("failed to fetch interfaces {} for tosca element with id {}, error {}", id, parentId ,dataFromGraph.right().value());
167                         return null;
168                 }
169
170                 Map<String, InterfaceDefinition> interfaceDefinitionMap = dataFromGraph.left().value();
171                 if(interfaceDefinitionMap == null) {
172                         return null;
173                 }
174                 Collection<InterfaceDefinition> interfaces = interfaceDefinitionMap.values();
175                 if (interfaces == null){
176                         return null;
177                 }
178                 for (InterfaceDataDefinition interfaceDataDefinition : interfaces){
179                         Map<String, OperationDataDefinition> operationsMap = interfaceDataDefinition.getOperations();
180                         if (operationsMap == null) {
181                                 return null;
182                         }
183                         ArtifactDataDefinition implementationArtifact = getArtifactDataDefinition(id, operationsMap);
184                         if (implementationArtifact != null)
185                                 return implementationArtifact;
186                 }
187                 return null;
188         }
189
190         private ArtifactDataDefinition getArtifactDataDefinition(String id,
191                         Map<String, OperationDataDefinition> operationsMap) {
192                 for(OperationDataDefinition operationDataDefinition : operationsMap.values()){
193                         ArtifactDataDefinition implementationArtifact = operationDataDefinition.getImplementation();
194                         if(implementationArtifact != null){
195                                 String uniqueId = implementationArtifact.getUniqueId();
196                                 if (id.equals(uniqueId)) {
197                                         return  implementationArtifact;
198                                 }
199                         }
200                 }
201                 return null;
202         }
203
204
205     public Either<ArtifactDefinition, StorageOperationStatus> removeArifactFromResource(String id, String artifactId, NodeTypeEnum type, boolean deleteMandatoryArtifact) {
206         Either<ArtifactDefinition, StorageOperationStatus> status = removeArtifactOnGraph(id, artifactId, type, deleteMandatoryArtifact);
207
208         if (status.isRight()) {
209
210             log.debug("Failed to delete artifact {} of resource {}", artifactId, id);
211
212             BeEcompErrorManager.getInstance().logBeFailedDeleteNodeError("Delete Artifact", artifactId, String.valueOf(status.right().value()));
213             return Either.right(status.right().value());
214         } else {
215
216             return Either.left(status.left().value());
217         }
218     }
219
220     public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType, ArtifactGroupTypeEnum groupType, String instanceId) {
221
222         Triple<EdgeLabelEnum, Boolean, VertexTypeEnum> triple = getEdgeLabelEnumFromArtifactGroupType(groupType, parentType);
223         EdgeLabelEnum edgeLabelEnum = triple.getLeft();
224
225         Either<Map<String, ArtifactDefinition>, JanusGraphOperationStatus> foundArtifact = null;
226         Map<String, ArtifactDefinition> resMap = new HashMap<>();
227         foundArtifact = getArtifactByLabel(parentId, instanceId, edgeLabelEnum);
228         if (foundArtifact.isRight()) {
229             log.debug("Failed to find artifact in component {} with label {} ", parentId, edgeLabelEnum);
230             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(foundArtifact.right().value()));
231         }
232
233         resMap.putAll(foundArtifact.left().value());
234
235         return Either.left(resMap);
236     }
237
238     /**
239      * @param parentId   the id of the instance container
240      * @param instanceId the id of the instance of which to return its artifacts
241      * @return instance and instance deployment artifacts mapped by artifact label name
242      */
243     public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getAllInstanceArtifacts(String parentId, String instanceId) {
244         Map<String, ArtifactDataDefinition> resMap = new HashMap<>();
245         Either<Map<String, ArtifactDataDefinition>, JanusGraphOperationStatus> instArtifacts = getInstanceArtifactsByLabel(parentId, instanceId, EdgeLabelEnum.INSTANCE_ARTIFACTS);
246         if (instArtifacts.isRight()) {
247             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(instArtifacts.right().value()));
248         }
249         Either<Map<String, ArtifactDataDefinition>, JanusGraphOperationStatus> deployInstArtifacts = getInstanceArtifactsByLabel(parentId, instanceId, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS);
250         if (deployInstArtifacts.isRight()) {
251             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(deployInstArtifacts.right().value()));
252         }
253         resMap.putAll(instArtifacts.left().value());
254         resMap.putAll(deployInstArtifacts.left().value());
255         return Either.left(convertArtifactMapToArtifactDefinitionMap(resMap));
256     }
257
258     public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(String parentId) {
259
260         Either<Map<String, ArtifactDefinition>, JanusGraphOperationStatus> foundArtifact = null;
261         Map<String, ArtifactDefinition> resMap = new HashMap<>();
262         foundArtifact = getArtifactByLabel(parentId, null, EdgeLabelEnum.ARTIFACTS);
263         if (foundArtifact.isLeft()) {
264             resMap.putAll(foundArtifact.left().value());
265
266         }
267         foundArtifact = getArtifactByLabel(parentId, null, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS);
268         if (foundArtifact.isLeft()) {
269             resMap.putAll(foundArtifact.left().value());
270
271         }
272         foundArtifact = getArtifactByLabel(parentId, null, EdgeLabelEnum.TOSCA_ARTIFACTS);
273         if (foundArtifact.isLeft()) {
274             resMap.putAll(foundArtifact.left().value());
275         }
276         return Either.left(resMap);
277
278     }
279
280     public Either<ArtifactDefinition, StorageOperationStatus> removeArtifactOnGraph(String id, String artifactId, NodeTypeEnum type, boolean deleteMandatoryArtifact) {
281
282         Either<ArtifactDefinition, StorageOperationStatus> artifactData = this.getArtifactById(id, artifactId);
283         if (artifactData.isRight()) {
284             log.debug("Failed to find artifact in component {} with id {} ", id, artifactId);
285             return Either.right(artifactData.right().value());
286         }
287         ArtifactDataDefinition artifactDefinition = artifactData.left().value();
288         boolean isMandatory = false;
289         if ((artifactDefinition.getMandatory() || artifactDefinition.getServiceApi()) && !deleteMandatoryArtifact) {
290             // return Either.left(artifactData.left().value());
291             isMandatory = true;
292         }
293
294         Triple<EdgeLabelEnum, Boolean, VertexTypeEnum> triple = getEdgeLabelEnumFromArtifactGroupType(artifactDefinition.getArtifactGroupType(), type);
295         EdgeLabelEnum edgeLabelEnum = triple.getLeft();
296         VertexTypeEnum vertexTypeEnum = triple.getRight();
297
298         if (!isMandatory) {
299             StorageOperationStatus status = deleteToscaDataElement(id, edgeLabelEnum, vertexTypeEnum, artifactDefinition.getArtifactLabel(), JsonPresentationFields.ARTIFACT_LABEL);
300             if (status != StorageOperationStatus.OK)
301                 return Either.right(status);
302         }
303
304         return Either.left(artifactData.left().value());
305
306     }
307
308     private void updateUUID(Map<String, ArtifactDefinition> deploymentArtifacts, ArtifactDefinition updateArtifactData, String oldChecksum, String oldVesrion, boolean isUpdate, EdgeLabelEnum edgeLabel, String prevArtUid) {
309         if (oldVesrion == null || oldVesrion.isEmpty()) {
310             oldVesrion = "0";
311         }
312         String currentChecksum = updateArtifactData.getArtifactChecksum();
313
314         if (isUpdate) {
315             ArtifactTypeEnum type = ArtifactTypeEnum.findType(updateArtifactData.getArtifactType());
316             switch (type) {
317                 case HEAT_ENV:
318                     if (edgeLabel == EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS) {
319                         generateUUID(updateArtifactData, oldVesrion);
320                     }
321                     break;
322                 case HEAT:
323                 case HEAT_NET:
324                 case HEAT_VOL:
325                     boolean changed = false;
326                     Optional<Entry<String, ArtifactDefinition>> any = deploymentArtifacts.entrySet()
327                             .stream()
328                             .filter(e -> e.getKey().equals(updateArtifactData.getArtifactLabel()))
329                             .findAny();
330                     if ( any.isPresent() ){
331                         if ( !any.get().getValue().getArtifactChecksum().equals(updateArtifactData.getArtifactChecksum()) ){
332                             changed = true;
333                         }
334                     }
335                     Optional<Entry<String, ArtifactDefinition>> anyEnv = deploymentArtifacts.entrySet()
336                             .stream()
337                             .filter(e -> prevArtUid.equals(e.getValue().getGeneratedFromId()))
338                             .findAny();
339                     if ( anyEnv.isPresent() && anyEnv.get().getValue().getHeatParamUpdated()){
340                         String newCheckSum = sortAndCalculateChecksumForHeatParameters(updateArtifactData.getHeatParameters());
341                         if ( !anyEnv.get().getValue().getArtifactChecksum().equals(newCheckSum) ){
342                             changed = true;
343                             anyEnv.get().getValue().setArtifactChecksum(newCheckSum);
344                             UUID uuid = UUID.randomUUID();
345                             anyEnv.get().getValue().setArtifactUUID(uuid.toString());
346                         }
347                     }
348                     if ( changed && anyEnv.isPresent() ){
349                             generateUUID(updateArtifactData, oldVesrion);
350                             anyEnv.get().getValue().setGeneratedFromId(updateArtifactData.getUniqueId());
351                             anyEnv.get().getValue().setDuplicated(false);
352                             anyEnv.get().getValue().setArtifactVersion(updateArtifactData.getArtifactVersion());
353                             anyEnv.get().getValue().setHeatParamUpdated(false);
354                     }
355                     break;
356                 default:
357                     generateUUIDForNonHeatArtifactType(updateArtifactData, oldChecksum, oldVesrion, currentChecksum);
358                     break;
359             }
360         } else {
361             generateUUIDForNonHeatArtifactType(updateArtifactData, oldChecksum, oldVesrion, currentChecksum);
362         }
363     }
364
365     private void generateUUIDForNonHeatArtifactType(ArtifactDataDefinition artifactData, String oldChecksum, String oldVesrion, String currentChecksum) {
366         if (oldChecksum == null || oldChecksum.isEmpty()) {
367             if (currentChecksum != null) {
368                 generateUUID(artifactData, oldVesrion);
369             }
370         } else if ((currentChecksum != null && !currentChecksum.isEmpty()) && !oldChecksum.equals(currentChecksum)) {
371             generateUUID(artifactData, oldVesrion);
372         }
373     }
374
375     // @TODO add implementation
376
377     public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType) {
378         return null;
379     }
380
381     public Either<ArtifactDefinition, StorageOperationStatus> addHeatEnvArtifact(ArtifactDefinition artifactHeatEnv,
382            ArtifactDefinition artifactHeat, Component component, NodeTypeEnum parentType, boolean failIfExist, String instanceId) {
383         artifactHeatEnv.setGeneratedFromId(artifactHeat.getUniqueId());
384         return addArtifactToComponent(artifactHeatEnv, component, parentType, failIfExist, instanceId);
385     }
386
387     public Either<ArtifactDefinition, StorageOperationStatus> getHeatArtifactByHeatEnvId(String parentId, ArtifactDefinition heatEnv, NodeTypeEnum parentType, String containerId, ComponentTypeEnum componentType) {
388         String id = heatEnv.getGeneratedFromId();
389         ComponentTypeEnum compType;
390         switch (parentType) {
391             case ResourceInstance:
392                 compType = ComponentTypeEnum.RESOURCE_INSTANCE;
393                 break;
394             default:
395                 compType = componentType;
396         }
397         return getArtifactById(parentId, id, compType, containerId);
398     }
399
400     public Either<ArtifactDefinition, StorageOperationStatus> updateHeatEnvArtifact(Component component, ArtifactDefinition artifactEnvInfo, String artifactId, String newArtifactId, NodeTypeEnum type, String instanceId) {
401
402         Either<Map<String, ArtifactDefinition>, JanusGraphOperationStatus> artifactsEither = getArtifactByLabel(component.getUniqueId(), instanceId, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS);
403         return updateHeatEnvArtifact(artifactsEither, component, artifactEnvInfo, artifactId, newArtifactId, type, instanceId);
404     }
405
406     private Either<ArtifactDefinition, StorageOperationStatus> updateHeatEnvArtifact(
407             Either<Map<String, ArtifactDefinition>, JanusGraphOperationStatus> artifactsEither, Component component,
408             ArtifactDefinition artifactEnvInfo, String artifactId, String newArtifactId, NodeTypeEnum type, String instanceId) {
409
410         String id = component.getUniqueId();
411         if (artifactsEither.isRight()) {
412             log.debug("Failed to find artifacts in component {} with id {} ", id, artifactsEither.right().value());
413             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(artifactsEither.right().value()));
414         }
415
416         Map<String, ArtifactDefinition> artifacts = artifactsEither.left().value();
417         List<ArtifactDefinition> envList = artifacts.values().stream()
418                 .filter(a -> a.getGeneratedFromId() != null && a.getGeneratedFromId().equals(artifactId))
419                 .collect(Collectors.toList());
420         if (envList != null && !envList.isEmpty()) {
421             envList.forEach(a -> {
422                 a.setGeneratedFromId(newArtifactId);
423                 updateArtifactOnResource(a, component, a.getUniqueId(), type, instanceId, true);
424
425             });
426
427         }
428         return Either.left(artifactEnvInfo);
429     }
430
431     public Either<ArtifactDefinition, StorageOperationStatus> updateHeatEnvArtifactOnInstance(
432             Component component, ArtifactDefinition artifactEnvInfo, String artifactId, String newArtifactId, NodeTypeEnum type, String instanceId) {
433
434         String id = component.getUniqueId();
435         Either<Map<String, ArtifactDefinition>, JanusGraphOperationStatus> artifactsEither = getArtifactByLabel(id, instanceId, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS);
436         return updateHeatEnvArtifact(artifactsEither, component, artifactEnvInfo, artifactId, newArtifactId, type, instanceId);
437     }
438
439     public Either<ArtifactDefinition, StorageOperationStatus> updateHeatEnvPlaceholder(ArtifactDefinition artifactInfo, Component parent, NodeTypeEnum type) {
440                 return updateArtifactOnResource(artifactInfo, parent, artifactInfo.getUniqueId(), type, null, true);
441     }
442
443
444     ///////////////////////////////////////////// private methods ////////////////////////////////////////////////////
445
446     protected ArtifactDefinition convertArtifactDataToArtifactDefinition(ArtifactDefinition artifactInfo, ArtifactDataDefinition artifactDefResult) {
447         log.debug("The object returned after create property is {}", artifactDefResult);
448
449         ArtifactDefinition propertyDefResult = new ArtifactDefinition(artifactDefResult);
450         if (artifactInfo != null)
451             propertyDefResult.setPayload(artifactInfo.getPayloadData());
452
453         List<HeatParameterDefinition> parameters = new ArrayList<>();
454         /*
455          * StorageOperationStatus heatParametersOfNode = heatParametersOperation.getHeatParametersOfNode(NodeTypeEnum.ArtifactRef, artifactDefResult.getUniqueId().toString(), parameters); if ((heatParametersOfNode.equals(StorageOperationStatus.OK))
456          * && !parameters.isEmpty()) { propertyDefResult.setHeatParameters(parameters); }
457          */
458         return propertyDefResult;
459     }
460
461     private ArtifactDataDefinition getInstanceArtifactByLabelAndId(String parentId, String id, String containerId, EdgeLabelEnum edgeLabelEnum) {
462         ArtifactDataDefinition foundArtifact = null;
463         Either<Map<String, MapArtifactDataDefinition>, JanusGraphOperationStatus> artifactsEither = getDataFromGraph(containerId, edgeLabelEnum);
464         if (artifactsEither.isRight()) {
465             log.debug(FAILED_TO_FETCH_FOR_TOSCA_ELEMENT_WITH_ID_ERROR, edgeLabelEnum, containerId, artifactsEither.right().value());
466             return null;
467         }
468
469         Map<String, MapArtifactDataDefinition> artifacts = artifactsEither.left().value();
470
471         MapArtifactDataDefinition artifactsPerInstance = artifacts.get(parentId);
472         if (artifactsPerInstance == null) {
473             log.debug("failed to fetch artifacts for instance {} in tosca element with id {}, error {}", parentId, containerId, artifactsEither.right().value());
474             return null;
475         }
476         Optional<ArtifactDataDefinition> op = artifactsPerInstance.getMapToscaDataDefinition().values().stream().filter(p -> p.getUniqueId().equals(id)).findAny();
477         if (op.isPresent()) {
478             foundArtifact = op.get();
479         }
480         return foundArtifact;
481     }
482
483     private ArtifactDataDefinition getArtifactByLabelAndId(String parentId, String id, EdgeLabelEnum edgeLabelEnum) {
484         ArtifactDataDefinition foundArtifact = null;
485         Either<Map<String, ArtifactDataDefinition>, JanusGraphOperationStatus> artifactsEither = getDataFromGraph(parentId, edgeLabelEnum);
486         if (artifactsEither.isRight()) {
487             log.debug(FAILED_TO_FETCH_FOR_TOSCA_ELEMENT_WITH_ID_ERROR, edgeLabelEnum, parentId, artifactsEither.right().value());
488             return null;
489         }
490
491         Map<String, ArtifactDataDefinition> artifacts = artifactsEither.left().value();
492         Optional<ArtifactDataDefinition> op = artifacts.values().stream().filter(p -> p.getUniqueId().equals(id)).findAny();
493         if (op.isPresent()) {
494             foundArtifact = op.get();
495         }
496         return foundArtifact;
497     }
498
499     private Either<Map<String, ArtifactDefinition>, JanusGraphOperationStatus> getArtifactByLabel(String parentId, String instanceId, EdgeLabelEnum edgeLabelEnum) {
500         Either<Map<String, ArtifactDataDefinition>, JanusGraphOperationStatus> artifactsEither = getArtifactsDataByLabel(parentId, instanceId, edgeLabelEnum);
501         if (artifactsEither.isRight()) {
502             log.debug(FAILED_TO_FETCH_FOR_TOSCA_ELEMENT_WITH_ID_ERROR, edgeLabelEnum, parentId, artifactsEither.right().value());
503             return Either.right(artifactsEither.right().value());
504         }
505         Map<String, ArtifactDataDefinition> artifactDataMap = artifactsEither.left().value();
506         return Either.left(convertArtifactMapToArtifactDefinitionMap(artifactDataMap));
507     }
508
509     private Either<Map<String, ArtifactDataDefinition>, JanusGraphOperationStatus> getArtifactsDataByLabel(String parentId, String instanceId, EdgeLabelEnum edgeLabelEnum) {
510         return edgeLabelEnum.isInstanceArtifactsLabel() ? getInstanceArtifactsByLabel(parentId, instanceId, edgeLabelEnum) : getDataFromGraph(parentId, edgeLabelEnum);
511     }
512
513     private Map<String, ArtifactDefinition> convertArtifactMapToArtifactDefinitionMap(Map<String, ArtifactDataDefinition> artifactDataMap) {
514         Map<String, ArtifactDefinition> artMap = new HashMap<>();
515         if (artifactDataMap != null && !artifactDataMap.isEmpty()) {
516             artMap = artifactDataMap.entrySet().stream().collect(Collectors.toMap(Entry::getKey, e -> convertArtifactDataToArtifactDefinition(null, e.getValue())));
517         }
518         return artMap;
519     }
520
521     private Either<Map<String, ArtifactDataDefinition>, JanusGraphOperationStatus> getInstanceArtifactsByLabel(String parentId, String instanceId, EdgeLabelEnum edgeLabelEnum) {
522         Either<Map<String, MapArtifactDataDefinition>, JanusGraphOperationStatus> resultEither = getDataFromGraph(parentId, edgeLabelEnum);
523         if (resultEither.isRight()) {
524             log.debug(FAILED_TO_FETCH_FOR_TOSCA_ELEMENT_WITH_ID_ERROR, edgeLabelEnum, parentId, resultEither.right().value());
525             return Either.right(resultEither.right().value());
526         }
527         Map<String, MapArtifactDataDefinition> mapArtifacts = resultEither.left().value();
528         MapArtifactDataDefinition artifactPerInstance = mapArtifacts.get(instanceId);
529         return artifactPerInstance != null ? Either.left(artifactPerInstance.getMapToscaDataDefinition()) : Either.left(new HashMap<>());
530     }
531
532     private Triple<EdgeLabelEnum, Boolean, VertexTypeEnum> getEdgeLabelEnumFromArtifactGroupType(ArtifactGroupTypeEnum groupType, NodeTypeEnum nodeType) {
533         EdgeLabelEnum edgeLabelEnum;
534         VertexTypeEnum vertexTypeEnum;
535         Boolean isDeepElement = false;
536         /*
537          * if (nodeType == NodeTypeEnum.ResourceInstance) { edgeLabelEnum = EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS; vertexTypeEnum = VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS; isDeepElement = true; } else {
538          */
539         switch (groupType) {
540             case TOSCA:
541                 edgeLabelEnum = EdgeLabelEnum.TOSCA_ARTIFACTS;
542                 vertexTypeEnum = VertexTypeEnum.TOSCA_ARTIFACTS;
543                 break;
544             case DEPLOYMENT:
545                 if (nodeType == NodeTypeEnum.ResourceInstance) {
546                     edgeLabelEnum = EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS;
547                     vertexTypeEnum = VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS;
548                     isDeepElement = true;
549                 } else {
550                     edgeLabelEnum = EdgeLabelEnum.DEPLOYMENT_ARTIFACTS;
551                     vertexTypeEnum = VertexTypeEnum.DEPLOYMENT_ARTIFACTS;
552                 }
553                 break;
554             case SERVICE_API:
555                 edgeLabelEnum = EdgeLabelEnum.SERVICE_API_ARTIFACTS;
556                 vertexTypeEnum = VertexTypeEnum.SERVICE_API_ARTIFACTS;
557                 break;
558             default:
559                 if (nodeType == NodeTypeEnum.ResourceInstance) {
560                     edgeLabelEnum = EdgeLabelEnum.INSTANCE_ARTIFACTS;
561                     vertexTypeEnum = VertexTypeEnum.INSTANCE_ARTIFACTS;
562                     isDeepElement = true;
563                 } else {
564                     edgeLabelEnum = EdgeLabelEnum.ARTIFACTS;
565                     vertexTypeEnum = VertexTypeEnum.ARTIFACTS;
566                 }
567                 break;
568         }
569         // }
570         return new ImmutableTriple<>(edgeLabelEnum, isDeepElement, vertexTypeEnum);
571
572     }
573
574     public Either<ArtifactDataDefinition, StorageOperationStatus> updateArtifactOnGraph(Component component, ArtifactDefinition artifactInfo, NodeTypeEnum type, String artifactId, String instanceId, boolean isUpdate, boolean isDeletePlaceholder) {
575         String componentId = component.getUniqueId();
576         Either<ArtifactDataDefinition, StorageOperationStatus> res = null;
577         ArtifactDefinition artifactToUpdate = new ArtifactDefinition(artifactInfo);
578         ArtifactGroupTypeEnum groupType = artifactInfo.getArtifactGroupType();
579
580         Triple<EdgeLabelEnum, Boolean, VertexTypeEnum> triple = getEdgeLabelEnumFromArtifactGroupType(groupType, type);
581         EdgeLabelEnum edgeLabelEnum = triple.getLeft();
582         VertexTypeEnum vertexTypeEnum = triple.getRight();
583
584         Either<Boolean, StorageOperationStatus> isNeedToCloneEither = isCloneNeeded(componentId, edgeLabelEnum);
585         if (isNeedToCloneEither.isRight()) {
586             log.debug("Failed check is clone needed {}", componentId);
587             return Either.right(isNeedToCloneEither.right().value());
588
589         }
590         boolean isNeedToClone = isNeedToCloneEither.left().value();
591
592         String prevArtUid = artifactToUpdate.getUniqueId();
593         if (artifactId == null || isNeedToClone) {
594             String uniqueId;
595             if (edgeLabelEnum != EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS && edgeLabelEnum != EdgeLabelEnum.INSTANCE_ARTIFACTS) {
596                 uniqueId = UniqueIdBuilder.buildPropertyUniqueId(componentId, artifactToUpdate.getArtifactLabel());
597             } else {
598                 uniqueId = UniqueIdBuilder.buildInstanceArtifactUniqueId(componentId, instanceId, artifactToUpdate.getArtifactLabel());
599             }
600             prevArtUid = artifactToUpdate.getUniqueId();
601             artifactToUpdate.setUniqueId(uniqueId);
602             if (!isDeletePlaceholder)
603                 artifactToUpdate.setEsId(uniqueId);
604         } else
605             artifactToUpdate.setUniqueId(artifactId);
606
607         Map<String, ArtifactDefinition> artifacts = new HashMap<>();
608         Map<String, MapArtifactDataDefinition> artifactInst = null;
609         if (edgeLabelEnum != EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS && edgeLabelEnum != EdgeLabelEnum.INSTANCE_ARTIFACTS) {
610
611             Either<Map<String, ArtifactDataDefinition>, JanusGraphOperationStatus> artifactsEither = this.getDataFromGraph(componentId, edgeLabelEnum);
612
613             if (artifactsEither.isLeft() && artifactsEither.left().value() != null && !artifactsEither.left().value().isEmpty()) {
614                 artifacts = convertArtifactMapToArtifactDefinitionMap(artifactsEither.left().value());
615                 if (isNeedToClone && artifacts != null) {
616                     artifacts.values().stream().forEach(a -> a.setDuplicated(Boolean.TRUE));
617                 }
618             }
619         } else {
620
621             Either<Map<String, MapArtifactDataDefinition>, JanusGraphOperationStatus> artifactsEither = this.getDataFromGraph(componentId, edgeLabelEnum);
622             if (artifactsEither.isLeft()) {
623                 artifactInst = artifactsEither.left().value();
624                 if (isNeedToClone && artifactInst != null) {
625                     artifactInst.values().forEach(ma -> ma.getMapToscaDataDefinition().values().forEach(a -> a.setDuplicated(Boolean.TRUE)));
626                 }
627                 MapArtifactDataDefinition artifatcsOnInstance = artifactInst.get(instanceId);
628                 if (artifatcsOnInstance != null) {
629                     artifacts = convertArtifactMapToArtifactDefinitionMap(artifatcsOnInstance.getMapToscaDataDefinition());
630                 }
631             }
632         }
633         String oldChecksum = null;
634         String oldVersion = null;
635         if (artifacts != null && artifacts.containsKey(artifactInfo.getArtifactLabel())) {
636             ArtifactDataDefinition oldArtifactData = artifacts.get(artifactInfo.getArtifactLabel());
637             oldChecksum = oldArtifactData.getArtifactChecksum();
638             oldVersion = oldArtifactData.getArtifactVersion();
639             //duplicated flag didn't receive from UI, take from DB
640             artifactToUpdate.setDuplicated(oldArtifactData.getDuplicated());
641
642             if (isNeedToClone)
643                 artifactToUpdate.setDuplicated(Boolean.FALSE);
644             else {
645                 if (artifactToUpdate.getDuplicated()) {
646                     String uniqueId = "";
647                     if(type != NodeTypeEnum.ResourceInstance)
648                         uniqueId = UniqueIdBuilder.buildPropertyUniqueId(componentId, artifactToUpdate.getArtifactLabel());
649                     else
650                         uniqueId = UniqueIdBuilder.buildInstanceArtifactUniqueId(componentId, instanceId, artifactToUpdate.getArtifactLabel());
651
652                     artifactToUpdate.setUniqueId(uniqueId);
653                     if (!isDeletePlaceholder)
654                         artifactToUpdate.setEsId(uniqueId);
655                     artifactToUpdate.setDuplicated(Boolean.FALSE);
656                 }
657             }
658         }
659
660         updateUUID(artifacts, artifactToUpdate, oldChecksum, oldVersion, isUpdate, edgeLabelEnum, prevArtUid);
661
662         if (artifactInfo.getPayloadData() == null) {
663             if (!artifactToUpdate.getMandatory() || artifactToUpdate.getEsId() != null) {
664                 artifactToUpdate.setEsId(artifactToUpdate.getUniqueId());
665             }
666         } else {
667             if (artifactToUpdate.getEsId() == null) {
668                 artifactToUpdate.setEsId(artifactToUpdate.getUniqueId());
669             }
670         }
671
672         StorageOperationStatus status = StorageOperationStatus.OK;
673         if (edgeLabelEnum != EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS && edgeLabelEnum != EdgeLabelEnum.INSTANCE_ARTIFACTS) {
674             List<ArtifactDefinition> toscaDataList = new ArrayList<>();
675             toscaDataList.add(artifactToUpdate);
676
677             if (isNeedToClone && artifacts != null) {
678                 artifacts.values().stream().filter(a -> !a.getArtifactLabel().equals(artifactToUpdate.getArtifactLabel())).forEach(toscaDataList::add);
679             }else{
680                 if ( artifacts != null ) {
681                     artifacts.values().stream().filter(a -> artifactToUpdate.getUniqueId().equals(a.getGeneratedFromId())).forEach(toscaDataList::add);
682                 }
683             }
684             status = updateToscaDataOfToscaElement(componentId, edgeLabelEnum, vertexTypeEnum, toscaDataList, JsonPresentationFields.ARTIFACT_LABEL);
685         } else {
686             List<ArtifactDataDefinition> toscaDataList = new ArrayList<>();
687             toscaDataList.add(artifactToUpdate);
688             List<String> pathKeys = new ArrayList<>();
689             pathKeys.add(instanceId);
690             if (isNeedToClone) {
691                 MapArtifactDataDefinition artifatcsOnInstance = artifactInst.get(instanceId);
692                 if (artifatcsOnInstance != null) {
693                     Map<String, ArtifactDataDefinition> mapToscaDataDefinition = artifatcsOnInstance.getMapToscaDataDefinition();
694                     ArtifactDataDefinition artifactDataDefinitionToUpdate = new ArtifactDataDefinition(artifactToUpdate);
695                     mapToscaDataDefinition.put(artifactToUpdate.getArtifactLabel(), artifactDataDefinitionToUpdate);
696                 }
697
698                 for (Entry<String, MapArtifactDataDefinition> e : artifactInst.entrySet()) {
699                     List<ArtifactDataDefinition> toscaDataListPerInst = e.getValue().getMapToscaDataDefinition().values().stream().collect(Collectors.toList());
700                     List<String> pathKeysPerInst = new ArrayList<>();
701                     pathKeysPerInst.add(e.getKey());
702                     status = updateToscaDataDeepElementsOfToscaElement(componentId, edgeLabelEnum, vertexTypeEnum, toscaDataListPerInst, pathKeysPerInst, JsonPresentationFields.ARTIFACT_LABEL);
703                     if (status != StorageOperationStatus.OK) {
704                         log.debug("Failed to update atifacts group for instance {} in component {} edge type {} error {}", instanceId, componentId, edgeLabelEnum, status);
705                         res = Either.right(status);
706                         break;
707                     }
708                 }
709             } else {
710                 status = updateToscaDataDeepElementsOfToscaElement(componentId, edgeLabelEnum, vertexTypeEnum, toscaDataList, pathKeys, JsonPresentationFields.ARTIFACT_LABEL);
711             }
712         }
713         if (status == StorageOperationStatus.OK)
714             res = Either.left(artifactToUpdate);
715         else
716             res = Either.right(status);
717         return res;
718     }
719
720     public void generateUUID(ArtifactDataDefinition artifactData, String oldVesrion) {
721
722         UUID uuid = UUID.randomUUID();
723         artifactData.setArtifactUUID(uuid.toString());
724         MDC.put(ILogConfiguration.MDC_SERVICE_INSTANCE_ID, uuid.toString());
725         updateVersionAndDate(artifactData, oldVesrion);
726     }
727
728     private void updateVersionAndDate(ArtifactDataDefinition artifactData, String oldVesrion) {
729         if (artifactData.getArtifactChecksum() != null) {
730             long time = System.currentTimeMillis();
731             artifactData.setPayloadUpdateDate(time);
732         }
733         int newVersion = new Integer(oldVesrion).intValue();
734         newVersion++;
735         artifactData.setArtifactVersion(String.valueOf(newVersion));
736     }
737
738     public Either<ArtifactDataDefinition, StorageOperationStatus> removeArtifactOnGraph(ArtifactDefinition artifactFromGraph, String componentId, String instanceId, NodeTypeEnum type, boolean deleteMandatoryArtifact) {
739
740         Triple<EdgeLabelEnum, Boolean, VertexTypeEnum> triple = getEdgeLabelEnumFromArtifactGroupType(artifactFromGraph.getArtifactGroupType(), type);
741         EdgeLabelEnum edgeLabelEnum = triple.getLeft();
742         VertexTypeEnum vertexTypeEnum = triple.getRight();
743
744         if (deleteMandatoryArtifact || !(artifactFromGraph.getMandatory() || artifactFromGraph.getServiceApi())) {
745             StorageOperationStatus status;
746             if (triple.getMiddle()) {
747                 List<String> pathKeys = new ArrayList<>();
748                 pathKeys.add(instanceId);
749                 status = deleteToscaDataDeepElement(componentId, edgeLabelEnum, vertexTypeEnum, artifactFromGraph.getArtifactLabel(), pathKeys, JsonPresentationFields.ARTIFACT_LABEL);
750             } else {
751                 status = deleteToscaDataElement(componentId, edgeLabelEnum, vertexTypeEnum, artifactFromGraph.getArtifactLabel(), JsonPresentationFields.ARTIFACT_LABEL);
752             }
753             if (status != StorageOperationStatus.OK)
754                 return Either.right(status);
755         }
756         return Either.left(artifactFromGraph);
757
758     }
759
760     public Either<ArtifactDataDefinition, StorageOperationStatus> deleteArtifactWithCloningOnGraph(String componentId, ArtifactDefinition artifactToDelete, NodeTypeEnum type, String instanceId, boolean deleteMandatoryArtifact) {
761
762         Either<ArtifactDataDefinition, StorageOperationStatus> result = null;
763         Triple<EdgeLabelEnum, Boolean, VertexTypeEnum> triple = getEdgeLabelEnumFromArtifactGroupType(artifactToDelete.getArtifactGroupType(), type);
764         EdgeLabelEnum edgeLabel = triple.getLeft();
765         VertexTypeEnum vertexLabel = triple.getRight();
766
767         Boolean deleteElement = deleteMandatoryArtifact || !(artifactToDelete.getMandatory() || artifactToDelete.getServiceApi());
768         Map<String, ToscaDataDefinition> artifacts = null;
769         GraphVertex parentVertex = null;
770         Either<Map<String, ToscaDataDefinition>, JanusGraphOperationStatus> getArtifactsRes = null;
771
772         Either<GraphVertex, JanusGraphOperationStatus> getToscaElementRes = janusGraphDao
773             .getVertexById(componentId, JsonParseFlagEnum.NoParse);
774         if (getToscaElementRes.isRight()) {
775             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to get tosca element {} upon getting tosca data from graph. Status is {}. ", componentId, getToscaElementRes.right().value());
776             result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getToscaElementRes.right().value()));
777         }
778         if (result == null) {
779             parentVertex = getToscaElementRes.left().value();
780             getArtifactsRes = this.getDataFromGraph(parentVertex, edgeLabel);
781             if (getArtifactsRes.isRight()) {
782                 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getArtifactsRes.right().value()));
783             }
784         }
785         if (result == null) {
786             artifacts = getArtifactsRes.left().value();
787             if (triple.getMiddle()) {
788                 artifacts.values().forEach(ma -> ((MapArtifactDataDefinition) ma).getMapToscaDataDefinition().values().forEach(a -> a.setDuplicated(Boolean.TRUE)));
789                 MapArtifactDataDefinition artifatcsOnInstance = (MapArtifactDataDefinition) artifacts.get(instanceId);
790                 if (artifatcsOnInstance != null && deleteElement) {
791                     artifatcsOnInstance.getMapToscaDataDefinition().remove(artifactToDelete.getArtifactLabel());
792                 }
793             } else {
794                 if (deleteElement) {
795                     artifacts.remove(artifactToDelete.getArtifactLabel());
796                 }
797                 artifacts.values().stream().forEach(a -> ((ArtifactDataDefinition) a).setDuplicated(Boolean.TRUE));
798             }
799             artifactToDelete.setDuplicated(Boolean.TRUE);
800         }
801         if (artifacts != null) {
802             JanusGraphOperationStatus
803                 status = janusGraphDao.deleteEdgeByDirection(parentVertex, Direction.OUT, edgeLabel);
804             if (status != JanusGraphOperationStatus.OK) {
805                 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
806             } else if (MapUtils.isNotEmpty(artifacts)) {
807                 Either<GraphVertex, StorageOperationStatus> associateResult = associateElementToData(parentVertex, vertexLabel, edgeLabel, artifacts);
808                 if (associateResult.isRight()) {
809                     result = Either.right(associateResult.right().value());
810                 }
811             }
812         }
813         if (result == null) {
814             result = Either.left(artifactToDelete);
815         }
816         return result;
817     }
818
819     public String sortAndCalculateChecksumForHeatParameters(List<HeatParameterDataDefinition> heatParameters) {
820         StrBuilder sb = new StrBuilder();
821         heatParameters.stream()
822                 .sorted(Comparator.comparingInt(HeatParameterDataDefinition::hashCode))
823                 .map(HeatParameterDataDefinition::hashCode)
824                 .collect(Collectors.toSet())
825                 .forEach(sb::append);
826         return GeneralUtility.calculateMD5Base64EncodedByString(sb.toString());
827     }
828 }