1946db8b5dda116033779dd44f8d31d9e21bfcf6
[sdc.git] /
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 package org.openecomp.sdc.vendorsoftwareproduct.impl;
18
19 import org.apache.commons.collections4.CollectionUtils;
20 import org.apache.commons.collections4.MapUtils;
21 import org.openecomp.core.utilities.CommonMethods;
22 import org.openecomp.core.utilities.json.JsonSchemaDataGenerator;
23 import org.openecomp.core.utilities.json.JsonUtil;
24 import org.openecomp.sdc.common.errors.CoreException;
25 import org.openecomp.sdc.common.errors.ErrorCategory;
26 import org.openecomp.sdc.common.errors.ErrorCode;
27 import org.openecomp.sdc.logging.api.Logger;
28 import org.openecomp.sdc.logging.api.LoggerFactory;
29 import org.openecomp.sdc.vendorsoftwareproduct.CompositionEntityDataManager;
30 import org.openecomp.sdc.vendorsoftwareproduct.dao.ComponentDao;
31 import org.openecomp.sdc.vendorsoftwareproduct.dao.ComputeDao;
32 import org.openecomp.sdc.vendorsoftwareproduct.dao.DeploymentFlavorDao;
33 import org.openecomp.sdc.vendorsoftwareproduct.dao.ImageDao;
34 import org.openecomp.sdc.vendorsoftwareproduct.dao.NetworkDao;
35 import org.openecomp.sdc.vendorsoftwareproduct.dao.NicDao;
36 import org.openecomp.sdc.vendorsoftwareproduct.dao.VendorSoftwareProductInfoDao;
37 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.*;
38 import org.openecomp.sdc.vendorsoftwareproduct.services.schemagenerator.SchemaGenerator;
39 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.Component;
40 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.ComponentData;
41 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.CompositionData;
42 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.CompositionEntityId;
43 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.CompositionEntityType;
44 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.CompositionEntityValidationData;
45 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.ComputeData;
46 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.Image;
47 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.Network;
48 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.NetworkType;
49 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.Nic;
50 import org.openecomp.sdc.vendorsoftwareproduct.types.schemagenerator.ComponentQuestionnaireSchemaInput;
51 import org.openecomp.sdc.vendorsoftwareproduct.types.schemagenerator.SchemaTemplateContext;
52 import org.openecomp.sdc.vendorsoftwareproduct.types.schemagenerator.SchemaTemplateInput;
53 import org.openecomp.sdc.versioning.dao.types.Version;
54
55 import java.util.ArrayList;
56 import java.util.Collection;
57 import java.util.Collections;
58 import java.util.EnumMap;
59 import java.util.HashMap;
60 import java.util.HashSet;
61 import java.util.List;
62 import java.util.Map;
63 import java.util.Objects;
64 import java.util.Set;
65
66 public class CompositionEntityDataManagerImpl implements CompositionEntityDataManager {
67
68   private static final String COMPOSITION_ENTITY_DATA_MANAGER_ERR =
69       "COMPOSITION_ENTITY_DATA_MANAGER_ERR";
70   private static final String COMPOSITION_ENTITY_DATA_MANAGER_ERR_MSG =
71       "Invalid input: %s may not be null";
72   private static final String MISSING_OR_INVALID_QUESTIONNAIRE_MSG =
73       "Data is missing/invalid for this %s. Please refill and resubmit.";
74
75   private static final Logger logger =
76       LoggerFactory.getLogger(CompositionEntityDataManagerImpl.class);
77   private Map<CompositionEntityId, CompositionEntityData> entities = new HashMap<>();
78   private Map<CompositionEntityType, String> nonDynamicSchemas =
79       new EnumMap<>(CompositionEntityType.class);
80   private List<CompositionEntityValidationData> roots = new ArrayList<>();
81
82   private VendorSoftwareProductInfoDao vspInfoDao;
83   private ComponentDao componentDao;
84   private NicDao nicDao;
85   private NetworkDao networkDao;
86   private ImageDao imageDao;
87   private ComputeDao computeDao;
88   private DeploymentFlavorDao deploymentFlavorDao;
89
90   public CompositionEntityDataManagerImpl(VendorSoftwareProductInfoDao vspInfoDao,
91                                           ComponentDao componentDao,
92                                           NicDao nicDao, NetworkDao networkDao,
93                                           ImageDao imageDao, ComputeDao computeDao,
94                                           DeploymentFlavorDao deploymentFlavorDao) {
95     this.vspInfoDao = vspInfoDao;
96     this.componentDao = componentDao;
97     this.nicDao = nicDao;
98     this.networkDao = networkDao;
99     this.imageDao = imageDao;
100     this.computeDao = computeDao;
101     this.deploymentFlavorDao = deploymentFlavorDao;
102   }
103
104   /**
105    * Validate entity composition entity validation data.
106    *
107    * @param entity                the entity
108    * @param schemaTemplateContext the schema template context
109    * @param schemaTemplateInput   the schema template input
110    * @return the composition entity validation data
111    */
112   @Override
113   public CompositionEntityValidationData validateEntity(CompositionEntity entity,
114                                                         SchemaTemplateContext schemaTemplateContext,
115                                                         SchemaTemplateInput schemaTemplateInput) {
116     if (entity == null) {
117       throw new CoreException(
118           new ErrorCode.ErrorCodeBuilder().withCategory(ErrorCategory.APPLICATION)
119               .withId(COMPOSITION_ENTITY_DATA_MANAGER_ERR).withMessage(
120               String.format(COMPOSITION_ENTITY_DATA_MANAGER_ERR_MSG, "composition entity"))
121               .build());
122     }
123     if (schemaTemplateContext == null) {
124       throw new CoreException(
125           new ErrorCode.ErrorCodeBuilder().withCategory(ErrorCategory.APPLICATION)
126               .withId(COMPOSITION_ENTITY_DATA_MANAGER_ERR).withMessage(
127               String.format(COMPOSITION_ENTITY_DATA_MANAGER_ERR_MSG, "schema template context"))
128               .build());
129     }
130
131     CompositionEntityValidationData validationData =
132         new CompositionEntityValidationData(entity.getType(), entity.getId());
133     String json =
134         schemaTemplateContext == SchemaTemplateContext.composition ? entity.getCompositionData()
135             : entity.getQuestionnaireData();
136     validationData.setErrors(JsonUtil.validate(
137         json == null ? JsonUtil.object2Json(new Object()) : json,
138         generateSchema(schemaTemplateContext, entity.getType(), schemaTemplateInput)));
139     return validationData;
140   }
141
142   /**
143    * Add entity.
144    *
145    * @param entity              the entity
146    * @param schemaTemplateInput the schema template input
147    */
148   @Override
149   public void addEntity(CompositionEntity entity, SchemaTemplateInput schemaTemplateInput) {
150     if (entity == null) {
151       throw new CoreException(
152           new ErrorCode.ErrorCodeBuilder().withCategory(ErrorCategory.APPLICATION)
153               .withId(COMPOSITION_ENTITY_DATA_MANAGER_ERR).withMessage(
154               String.format(COMPOSITION_ENTITY_DATA_MANAGER_ERR_MSG, "composition entity"))
155               .build());
156     }
157     entities.put(entity.getCompositionEntityId(),
158         new CompositionEntityData(entity, schemaTemplateInput));
159   }
160
161   /**
162    * Validate entities questionnaire map.
163    *
164    * @return the map
165    */
166   @Override
167   public Map<CompositionEntityId, Collection<String>> validateEntitiesQuestionnaire() {
168     Map<CompositionEntityId, Collection<String>> errorsByEntityId = new HashMap<>();
169     entities.forEach((key, value) -> {
170       Collection<String> errors = validateQuestionnaire(value);
171       if (errors != null) {
172         errorsByEntityId.put(key, errors);
173       }
174     });
175     return errorsByEntityId;
176   }
177
178   /**
179    * Build trees.
180    */
181   @Override
182   public void buildTrees() {
183     Map<CompositionEntityId, CompositionEntityValidationData> entitiesValidationData =
184         new HashMap<>();
185     entities.forEach((key, value) -> addValidationDataEntity(entitiesValidationData, key,
186         value.entity));
187   }
188
189   public Collection<CompositionEntityValidationData> getTrees() {
190     return roots;
191   }
192
193   @Override
194   public void saveCompositionData(String vspId, Version version, CompositionData compositionData) {
195     if (Objects.isNull(compositionData)) {
196       return;
197     }
198
199     Map<String, String> networkIdByName = saveNetworks(vspId, version, compositionData);
200     saveComponents(vspId, version, compositionData, networkIdByName);
201   }
202
203   @Override
204   public Set<CompositionEntityValidationData> getAllErrorsByVsp(String vspId) {
205     Set<CompositionEntityValidationData> entitiesWithErrors = new HashSet<>();
206     for (CompositionEntityValidationData root : roots) {
207       if (root.getEntityId().equals(vspId)) {
208         getEntityListWithErrors(root, entitiesWithErrors);
209         break;
210       }
211     }
212
213     if (CollectionUtils.isNotEmpty(entitiesWithErrors)) {
214       updateValidationCompositionEntityName(entitiesWithErrors);
215       return entitiesWithErrors;
216     }
217
218     return new HashSet<>();
219   }
220
221   private boolean isThereErrorsInSubTree(CompositionEntityValidationData entity) {
222     if (Objects.isNull(entity)) {
223       return false;
224     }
225
226     if (CollectionUtils.isNotEmpty(entity.getErrors())) {
227       return true;
228     }
229
230     Collection<CompositionEntityValidationData> subEntitiesValidationData =
231         entity.getSubEntitiesValidationData();
232     return !CollectionUtils.isEmpty(subEntitiesValidationData) &&
233         checkForErrorsInChildren(subEntitiesValidationData);
234
235   }
236
237   private boolean checkForErrorsInChildren(
238       Collection<CompositionEntityValidationData> subEntitiesValidationData) {
239     boolean result = false;
240     for (CompositionEntityValidationData subEntity : subEntitiesValidationData) {
241       if (CollectionUtils.isNotEmpty(subEntity.getErrors())) {
242         return true;
243       }
244
245       result = isThereErrorsInSubTree(subEntity) || result;
246       if (result) {
247         return true;
248       }
249     }
250     return false;
251   }
252
253   private void saveComponents(String vspId, Version version, CompositionData compositionData,
254                               Map<String, String> networkIdByName) {
255     if (CollectionUtils.isNotEmpty(compositionData.getComponents())) {
256       for (Component component : compositionData.getComponents()) {
257         ComponentEntity componentEntity = new ComponentEntity(vspId, version, null);
258         componentEntity.setComponentCompositionData(component.getData());
259
260         String componentId = createComponent(componentEntity, false).getId();
261
262         saveImagesByComponent(vspId, version, component, componentId);
263         saveComputesFlavorByComponent(vspId, version, component, componentId);
264
265         saveNicsByComponent(vspId, version, networkIdByName, component, componentId);
266       }
267     }
268   }
269
270   private void saveNicsByComponent(String vspId, Version version,
271                                    Map<String, String> networkIdByName, Component component,
272                                    String componentId) {
273     if (CollectionUtils.isNotEmpty(component.getNics())) {
274       for (Nic nic : component.getNics()) {
275         if (nic.getNetworkName() != null && MapUtils.isNotEmpty(networkIdByName)) {
276           nic.setNetworkId(networkIdByName.get(nic.getNetworkName()));
277         }
278         nic.setNetworkName(null);
279         //For heat flow set network type to be internal by default for NIC
280         nic.setNetworkType(NetworkType.Internal);
281
282         NicEntity nicEntity = new NicEntity(vspId, version, componentId, null);
283         nicEntity.setNicCompositionData(nic);
284         createNic(nicEntity);
285       }
286     }
287   }
288
289   private Map<String, String> saveNetworks(String vspId, Version version,
290                                            CompositionData compositionData) {
291     Map<String, String> networkIdByName = new HashMap<>();
292     if (CollectionUtils.isNotEmpty(compositionData.getNetworks())) {
293       for (Network network : compositionData.getNetworks()) {
294
295         NetworkEntity networkEntity = new NetworkEntity(vspId, version, null);
296         networkEntity.setNetworkCompositionData(network);
297
298         if (network.getName() != null) {
299           networkIdByName.put(network.getName(), createNetwork(networkEntity).getId());
300         }
301       }
302     }
303     return networkIdByName;
304   }
305
306   private NetworkEntity createNetwork(NetworkEntity network) {
307     //network.setId(CommonMethods.nextUuId()); will be set by the dao
308     networkDao.create(network);
309     return network;
310   }
311
312   @Override
313   public ComponentEntity createComponent(ComponentEntity component, boolean isManualVsp) {
314     //component.setId(CommonMethods.nextUuId()); will be set by the dao
315     ComponentQuestionnaireSchemaInput schemaInput = new ComponentQuestionnaireSchemaInput(null,
316         null, component.getComponentCompositionData().getDisplayName(), isManualVsp);
317     String questionnarieData = new JsonSchemaDataGenerator(generateSchema(SchemaTemplateContext.questionnaire,
318             CompositionEntityType.component, schemaInput)).generateData();
319     component.setQuestionnaireData(questionnarieData);
320
321     componentDao.create(component);
322     return component;
323   }
324
325   @Override
326   public NicEntity createNic(NicEntity nic) {
327     //nic.setId(CommonMethods.nextUuId()); will be set by the dao
328     nic.setQuestionnaireData(
329         new JsonSchemaDataGenerator(
330             generateSchema(SchemaTemplateContext.questionnaire, CompositionEntityType.nic, null))
331             .generateData());
332
333     nicDao.create(nic);
334     return nic;
335   }
336
337
338   public void addErrorsToTrees(Map<CompositionEntityId, Collection<String>> errors) {
339     roots.forEach(root -> addErrorsToTree(root, null, errors));
340   }
341
342   /* *
343    * get a flat list of all questionnaire entities that have validation errors
344    * */
345   public Set<CompositionEntityValidationData> getEntityListWithErrors() {
346     Set<CompositionEntityValidationData> treeAsList = new HashSet<>();
347
348     for (CompositionEntityValidationData entity : roots) {
349       if (CollectionUtils.isNotEmpty(entity.getErrors())) {
350         addNodeWithErrors(entity, treeAsList);
351       }
352       getEntityListWithErrors(entity, treeAsList);
353     }
354
355     updateValidationCompositionEntityName(treeAsList);
356     return treeAsList;
357   }
358
359   private void getEntityListWithErrors(CompositionEntityValidationData entity,
360                                        Set<CompositionEntityValidationData> compositionSet) {
361     if (CollectionUtils.isNotEmpty(entity.getErrors())) {
362       addNodeWithErrors(entity, compositionSet);
363     }
364
365     if (CollectionUtils.isEmpty(entity.getSubEntitiesValidationData())) {
366       return;
367     }
368
369     for (CompositionEntityValidationData child : entity.getSubEntitiesValidationData()) {
370       getEntityListWithErrors(child, compositionSet);
371     }
372   }
373
374
375   private void addNodeWithErrors(CompositionEntityValidationData node,
376                                  Set<CompositionEntityValidationData> entitiesWithErrors) {
377     CompositionEntityValidationData compositionNodeToAdd = new CompositionEntityValidationData(node
378         .getEntityType(), node.getEntityId());
379     compositionNodeToAdd.setErrors(node.getErrors());
380     compositionNodeToAdd.setSubEntitiesValidationData(null);
381
382     entitiesWithErrors.add(compositionNodeToAdd);
383   }
384
385   public void removeNodesWithoutErrors() {
386     roots.forEach(root -> removeNodesWithoutErrors(root, null));
387   }
388
389
390   private CompositionEntityData getCompositionEntityDataById(CompositionEntityValidationData
391                                                                  entity) {
392     for (Map.Entry<CompositionEntityId, CompositionEntityData> entityEntry : entities
393         .entrySet()) {
394       if (entityEntry.getKey().getId().equals(entity.getEntityId())) {
395         return entityEntry.getValue();
396       }
397     }
398     return null;
399   }
400
401
402   private void updateValidationCompositionEntityName(Set<CompositionEntityValidationData>
403                                                          compositionSet) {
404     for (CompositionEntityValidationData entity : compositionSet) {
405       String compositionData = getCompositionDataAsString(entity);
406       if (entity.getEntityType().equals(CompositionEntityType.vsp) ||
407           Objects.nonNull(compositionData)) {
408         entity.setEntityName(getEntityNameByEntityType(compositionData, entity));
409       }
410     }
411   }
412
413   private String getCompositionDataAsString(CompositionEntityValidationData entity) {
414     CompositionEntityData compositionEntityData = getCompositionEntityDataById(entity);
415     return compositionEntityData == null ? null : compositionEntityData.entity.getCompositionData();
416   }
417
418
419   private String getEntityNameByEntityType(String compositionData,
420                                            CompositionEntityValidationData entity) {
421     switch (entity.getEntityType()) {
422       case component:
423         ComponentData component = JsonUtil.json2Object(compositionData, ComponentData.class);
424         return component.getDisplayName();
425
426       case nic:
427         Nic nic = JsonUtil.json2Object(compositionData, Nic.class);
428         return nic.getName();
429
430       case network:
431         Network network = JsonUtil.json2Object(compositionData, Network.class);
432         return network.getName();
433
434       case image:
435         Image image = JsonUtil.json2Object(compositionData, Image.class);
436         return image.getFileName();
437
438       case compute:
439         ComputeData compute = JsonUtil.json2Object(compositionData, ComputeData.class);
440         return compute.getName();
441
442       case vsp:
443         CompositionEntityData vspEntity = getCompositionEntityDataById(entity);
444         if (Objects.isNull(vspEntity)) {
445           return null;
446         }
447         VspQuestionnaireEntity vspQuestionnaireEntity = (VspQuestionnaireEntity) vspEntity.entity;
448         VspDetails vspDetails =
449             vspInfoDao.get(new VspDetails(vspQuestionnaireEntity.getId(),
450                 vspQuestionnaireEntity.getVersion()));
451         return vspDetails.getName();
452       default:
453         return null;
454     }
455   }
456
457   private void removeNodesWithoutErrors(CompositionEntityValidationData node,
458                                         CompositionEntityValidationData parent) {
459
460     if (Objects.isNull(node)) {
461       return;
462     }
463
464     if (hasChildren(node)) {
465       Collection<CompositionEntityValidationData> subNodes =
466           new ArrayList<>(node.getSubEntitiesValidationData());
467       subNodes.forEach(subNode -> removeNodesWithoutErrors(subNode, node));
468       node.setSubEntitiesValidationData(subNodes);
469
470       if (canNodeGetRemovedFromValidationDataTree(node)) {
471         removeNodeFromChildren(parent, node);
472       }
473     } else if (canNodeGetRemovedFromValidationDataTree(node)) {
474       removeNodeFromChildren(parent, node);
475     }
476   }
477
478   private void removeNodeFromChildren(CompositionEntityValidationData parent,
479                                       CompositionEntityValidationData childToRemove) {
480     if (!Objects.isNull(parent)) {
481       parent.getSubEntitiesValidationData().remove(childToRemove);
482     }
483   }
484
485   private boolean hasChildren(CompositionEntityValidationData node) {
486     return !CollectionUtils.isEmpty(node.getSubEntitiesValidationData());
487   }
488
489   private boolean canNodeGetRemovedFromValidationDataTree(CompositionEntityValidationData node) {
490     return !hasChildren(node) && CollectionUtils.isEmpty(node.getErrors());
491   }
492
493
494   private void addValidationDataEntity(
495       Map<CompositionEntityId, CompositionEntityValidationData> entitiesValidationData,
496       CompositionEntityId entityId, CompositionEntity entity) {
497     if (entitiesValidationData.containsKey(entityId)) {
498       return;
499     }
500
501     CompositionEntityValidationData validationData =
502         new CompositionEntityValidationData(entity.getType(), entity.getId());
503     entitiesValidationData.put(entityId, validationData);
504
505     CompositionEntityId parentEntityId = entityId.getParentId();
506     if (parentEntityId == null) {
507       roots.add(validationData);
508     } else {
509       CompositionEntityData parentEntity = entities.get(parentEntityId);
510       if (parentEntity == null) {
511         roots.add(validationData);
512       } else {
513         addValidationDataEntity(entitiesValidationData, parentEntityId, parentEntity.entity);
514         entitiesValidationData.get(parentEntityId).addSubEntityValidationData(validationData);
515       }
516     }
517   }
518
519   private void addErrorsToTree(CompositionEntityValidationData node,
520                                CompositionEntityId parentNodeId,
521                                Map<CompositionEntityId, Collection<String>> errors) {
522     if (node == null) {
523       return;
524     }
525     CompositionEntityId nodeId = new CompositionEntityId(node.getEntityId(), parentNodeId);
526     node.setErrors(errors.get(nodeId));
527
528     if (node.getSubEntitiesValidationData() != null) {
529       node.getSubEntitiesValidationData()
530           .forEach(subNode -> addErrorsToTree(subNode, nodeId, errors));
531     }
532   }
533
534   private Collection<String> validateQuestionnaire(CompositionEntityData compositionEntityData) {
535     logger.debug(String.format("validateQuestionnaire start:  " +
536             "[entity.type]=%s, [entity.id]=%s, [entity.questionnaireString]=%s",
537         compositionEntityData.entity.getType().name(),
538         compositionEntityData.entity.getCompositionEntityId().toString(),
539         compositionEntityData.entity.getQuestionnaireData()));
540
541     if (Objects.isNull(compositionEntityData.entity.getQuestionnaireData()) ||
542         !JsonUtil.isValidJson(compositionEntityData.entity.getQuestionnaireData())) {
543       return Collections.singletonList(String
544           .format(MISSING_OR_INVALID_QUESTIONNAIRE_MSG, compositionEntityData.entity.getType()));
545     }
546
547     return JsonUtil.validate(
548         compositionEntityData.entity.getQuestionnaireData() == null
549             ? JsonUtil.object2Json(new Object())
550             : compositionEntityData.entity.getQuestionnaireData(),
551         getSchema(compositionEntityData.entity.getType(), SchemaTemplateContext.questionnaire,
552             compositionEntityData.schemaTemplateInput));
553   }
554
555   private String getSchema(CompositionEntityType compositionEntityType,
556                            SchemaTemplateContext schemaTemplateContext,
557                            SchemaTemplateInput schemaTemplateInput) {
558     return schemaTemplateInput == null
559         ? nonDynamicSchemas.computeIfAbsent(compositionEntityType,
560         k -> generateSchema(schemaTemplateContext, compositionEntityType, null))
561         : generateSchema(schemaTemplateContext, compositionEntityType, schemaTemplateInput);
562   }
563
564   private static class CompositionEntityData {
565     private CompositionEntity entity;
566     private SchemaTemplateInput schemaTemplateInput;
567
568     CompositionEntityData(CompositionEntity entity, SchemaTemplateInput schemaTemplateInput) {
569       this.entity = entity;
570       this.schemaTemplateInput = schemaTemplateInput;
571     }
572
573   }
574
575   // todo - make SchemaGenerator non static and mock it in UT instead of mocking this method (and
576   // make the method private
577   protected String generateSchema(SchemaTemplateContext schemaTemplateContext,
578                                   CompositionEntityType compositionEntityType,
579                                   SchemaTemplateInput schemaTemplateInput) {
580     return SchemaGenerator
581         .generate(schemaTemplateContext, compositionEntityType, schemaTemplateInput);
582   }
583
584   @Override
585   public DeploymentFlavorEntity createDeploymentFlavor(DeploymentFlavorEntity deploymentFlavor) {
586     deploymentFlavor.setId(CommonMethods.nextUuId());
587     deploymentFlavorDao.create(deploymentFlavor);
588     return deploymentFlavor;
589   }
590
591   @Override
592   public ImageEntity createImage(ImageEntity image) {
593     image.setId(CommonMethods.nextUuId());
594
595     image.setQuestionnaireData(
596         new JsonSchemaDataGenerator(SchemaGenerator
597             .generate(SchemaTemplateContext.questionnaire, CompositionEntityType.image, null))
598             .generateData());
599
600     imageDao.create(image);
601     return image;
602   }
603
604   public void saveComputesFlavorByComponent(String vspId, Version version, Component component,
605                                             String componentId) {
606     if (CollectionUtils.isNotEmpty(component.getCompute())) {
607       for (ComputeData flavor : component.getCompute()) {
608         ComputeEntity computeEntity = new ComputeEntity(vspId, version, componentId, null);
609         computeEntity.setComputeCompositionData(flavor);
610         computeEntity.setQuestionnaireData(
611             new JsonSchemaDataGenerator(SchemaGenerator
612                 .generate(SchemaTemplateContext.questionnaire, CompositionEntityType.compute,
613                     null)).generateData());
614
615         computeDao.create(computeEntity);
616       }
617     }
618   }
619
620   public void saveImagesByComponent(String vspId, Version version, Component component, String
621       componentId) {
622     if (CollectionUtils.isNotEmpty(component.getImages())) {
623       for (Image img : component.getImages()) {
624         ImageEntity imageEntity = new ImageEntity(vspId, version, componentId, null);
625         imageEntity.setImageCompositionData(img);
626         createImage(imageEntity);
627       }
628     }
629   }
630
631 }