Add collaboration feature
[sdc.git] / openecomp-be / backend / openecomp-sdc-vendor-software-product-manager / src / main / java / org / openecomp / sdc / vendorsoftwareproduct / impl / ImageManagerImpl.java
1 package org.openecomp.sdc.vendorsoftwareproduct.impl;
2
3
4 import org.apache.commons.collections4.CollectionUtils;
5 import org.openecomp.core.utilities.json.JsonUtil;
6 import org.openecomp.sdc.common.errors.CoreException;
7 import org.openecomp.sdc.common.errors.ErrorCode;
8 import org.openecomp.sdc.datatypes.error.ErrorLevel;
9 import org.openecomp.sdc.logging.context.impl.MdcDataDebugMessage;
10 import org.openecomp.sdc.logging.context.impl.MdcDataErrorMessage;
11 import org.openecomp.sdc.logging.types.LoggerConstants;
12 import org.openecomp.sdc.logging.types.LoggerErrorCode;
13 import org.openecomp.sdc.logging.types.LoggerTragetServiceName;
14 import org.openecomp.sdc.vendorsoftwareproduct.ImageManager;
15 import org.openecomp.sdc.vendorsoftwareproduct.dao.ImageDao;
16 import org.openecomp.sdc.vendorsoftwareproduct.dao.VendorSoftwareProductInfoDao;
17 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.ComponentEntity;
18 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.ImageEntity;
19 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.VspDetails;
20 import org.openecomp.sdc.vendorsoftwareproduct.errors.ImageErrorBuilder;
21 import org.openecomp.sdc.vendorsoftwareproduct.errors.NotSupportedHeatOnboardMethodErrorBuilder;
22 import org.openecomp.sdc.vendorsoftwareproduct.services.composition.CompositionEntityDataManager;
23 import org.openecomp.sdc.vendorsoftwareproduct.services.schemagenerator.SchemaGenerator;
24 import org.openecomp.sdc.vendorsoftwareproduct.types.CompositionEntityResponse;
25 import org.openecomp.sdc.vendorsoftwareproduct.types.QuestionnaireResponse;
26 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.CompositionEntityType;
27 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.CompositionEntityValidationData;
28 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.Image;
29 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.ImageFormat;
30 import org.openecomp.sdc.vendorsoftwareproduct.types.questionnaire.component.image.ImageDetails;
31 import org.openecomp.sdc.vendorsoftwareproduct.types.schemagenerator.ImageCompositionSchemaInput;
32 import org.openecomp.sdc.vendorsoftwareproduct.types.schemagenerator.SchemaTemplateContext;
33 import org.openecomp.sdc.vendorsoftwareproduct.types.schemagenerator.SchemaTemplateInput;
34 import org.openecomp.sdc.versioning.VersioningUtil;
35 import org.openecomp.sdc.versioning.dao.types.Version;
36
37 import java.util.Collection;
38 import java.util.stream.Collectors;
39
40 public class ImageManagerImpl implements ImageManager {
41   private static MdcDataDebugMessage mdcDataDebugMessage = new MdcDataDebugMessage();
42   private VendorSoftwareProductInfoDao vspInfoDao;
43   private ImageDao imageDao;
44   private CompositionEntityDataManager compositionEntityDataManager;
45
46   public ImageManagerImpl(VendorSoftwareProductInfoDao vspInfoDao,
47                           ImageDao imageDao,
48                           CompositionEntityDataManager compositionEntityDataManager) {
49     this.vspInfoDao = vspInfoDao;
50     this.imageDao = imageDao;
51     this.compositionEntityDataManager = compositionEntityDataManager;
52   }
53
54   @Override
55   public ImageEntity createImage(ImageEntity imageEntity) {
56     boolean isManual = vspInfoDao.isManual(imageEntity.getVspId(), imageEntity.getVersion());
57     if (!isManual) {
58       ErrorCode errorCode = NotSupportedHeatOnboardMethodErrorBuilder
59           .getAddImageNotSupportedHeatOnboardMethodErrorBuilder();
60
61       MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
62           LoggerTragetServiceName.CREATE_IMAGE, ErrorLevel.ERROR.name(),
63           errorCode.id(), errorCode.message());
64
65       throw new CoreException(errorCode);
66     }
67     compositionEntityDataManager.createImage(imageEntity);
68     return imageEntity;
69   }
70
71   @Override
72   public Collection<ImageEntity> listImages(String vspId, Version version, String componentId) {
73     mdcDataDebugMessage.debugEntryMessage("VSP id", vspId);
74     Collection<ImageEntity> imageEntities =
75         imageDao.list(new ImageEntity(vspId, version, componentId, null));
76
77     mdcDataDebugMessage.debugExitMessage("VSP id", vspId);
78     return imageEntities;
79   }
80
81   @Override
82   public CompositionEntityResponse<Image> getImageSchema(String vspId) {
83     mdcDataDebugMessage.debugEntryMessage("VSP id, image id", vspId);
84
85     CompositionEntityResponse<Image> response = new CompositionEntityResponse<>();
86     ImageCompositionSchemaInput inputSchema = new ImageCompositionSchemaInput();
87     Image image = new Image();
88     //image.setFormat(ImageFormat.qcow2.name());
89     inputSchema.setImage(image);
90     response.setSchema(getImageCompositionSchema(inputSchema));
91
92     mdcDataDebugMessage.debugExitMessage("VSP id, image id", vspId);
93     return response;
94   }
95
96   @Override
97   public CompositionEntityResponse<Image> getImage(String vspId, Version version, String
98       componentId, String imageId) {
99
100     mdcDataDebugMessage.debugEntryMessage("VSP id, componentId, image id", vspId, componentId,
101         imageId);
102     ImageEntity imageEntity = getImageEntity(vspId, version, componentId, imageId);
103
104     Image image = imageEntity.getImageCompositionData();
105     //Set format to default value in order to handle FTL validation when image format is null
106     /*if(image.getFormat() == null)
107       image.setFormat(ImageFormat.qcow2.name());*/
108
109     ImageCompositionSchemaInput schemaInput = new ImageCompositionSchemaInput();
110     schemaInput.setImage(image);
111
112     CompositionEntityResponse<Image> response = new CompositionEntityResponse<>();
113     response.setId(imageId);
114     response.setData(image);
115     response.setSchema(getImageCompositionSchema(schemaInput));
116
117     mdcDataDebugMessage.debugExitMessage("VSP id, componentId, image id", vspId, componentId,
118         imageId);
119
120     return response;
121   }
122
123   @Override
124   public QuestionnaireResponse getImageQuestionnaire(String vspId, Version version, String
125       componentId, String imageId) {
126     mdcDataDebugMessage.debugEntryMessage("VSP id", vspId);
127     QuestionnaireResponse questionnaireResponse = new QuestionnaireResponse();
128     //validateComponentId(vspId,version,componentId);
129
130     ImageEntity retrieved = imageDao.getQuestionnaireData(vspId, version, componentId, imageId);
131     VersioningUtil.validateEntityExistence(retrieved, new ImageEntity(vspId, version, componentId,
132         imageId), ComponentEntity.ENTITY_TYPE);
133     questionnaireResponse.setData(retrieved.getQuestionnaireData());
134     questionnaireResponse.setSchema(getImageQuestionnaireSchema(null));
135
136     mdcDataDebugMessage.debugExitMessage("VSP id", vspId);
137
138     return questionnaireResponse;
139   }
140
141   @Override
142   public void deleteImage(String vspId, Version version, String componentId, String imageId) {
143     mdcDataDebugMessage
144         .debugEntryMessage("VSP id, component id", vspId, componentId, imageId);
145     ImageEntity imageEntity = getImageEntity(vspId, version, componentId, imageId);
146     if (!vspInfoDao.isManual(vspId, version)) {
147       final ErrorCode deleteImageErrorBuilder =
148           NotSupportedHeatOnboardMethodErrorBuilder
149               .getDelImageNotSupportedHeatOnboardMethodErrorBuilder();
150       MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
151           LoggerTragetServiceName.DELETE_IMAGE, ErrorLevel.ERROR.name(),
152           LoggerErrorCode.PERMISSION_ERROR.getErrorCode(),
153           deleteImageErrorBuilder.message());
154       throw new CoreException(deleteImageErrorBuilder);
155     }
156     if (imageEntity != null) {
157       imageDao.delete(new ImageEntity(vspId, version, componentId, imageId));
158     }
159     mdcDataDebugMessage
160         .debugExitMessage("VSP id, component id", vspId, componentId, imageId);
161   }
162
163   private void validateHeatVspImageUpdate(String name, String value, String retrivedValue) {
164     if (value != null && !value.equals(retrivedValue)) {
165       final ErrorCode updateHeatImageErrorBuilder =
166           ImageErrorBuilder.getImageHeatReadOnlyErrorBuilder(name);
167
168       MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
169           LoggerTragetServiceName.UPDATE_IMAGE, ErrorLevel.ERROR.name(),
170           LoggerErrorCode.PERMISSION_ERROR.getErrorCode(),
171           updateHeatImageErrorBuilder.message());
172       throw new CoreException(updateHeatImageErrorBuilder);
173     }
174   }
175
176   @Override
177   public CompositionEntityValidationData updateImage(ImageEntity image) {
178     mdcDataDebugMessage
179         .debugEntryMessage("VSP id, component id", image.getVspId(), image.getComponentId(),
180             image.getId());
181
182     boolean isManual = vspInfoDao.isManual(image.getVspId(), image.getVersion());
183     ImageEntity retrieved =
184         getImageEntity(image.getVspId(), image.getVersion(), image.getComponentId(),
185             image.getId());
186
187     if (!isManual) {
188       final Image imageCompositionData = image.getImageCompositionData();
189       final String fileName = imageCompositionData.getFileName();
190       //final String format = imageCompositionData.getFormat();
191       validateHeatVspImageUpdate("fileName", fileName, retrieved.getImageCompositionData()
192           .getFileName());
193       /*validateHeatVspImageUpdate("format", format, retrieved.getImageCompositionData()
194           .getFormat());*/
195     }
196
197     Collection<ImageEntity> vfcImageList = listImages(image.getVspId(),
198         image.getVersion(), image.getComponentId());
199
200     //Set to null so that retrieved object is equal to one in list and gets removed.
201     retrieved.setQuestionnaireData(null);
202     vfcImageList.remove(retrieved);
203
204     //Set format to default value in order to handle FTL validation when image format is null
205     /*if(image.getImageCompositionData().getFormat() == null)
206       image.getImageCompositionData().setFormat(ImageFormat.qcow2.name());*/
207
208     ImageCompositionSchemaInput schemaInput = new ImageCompositionSchemaInput();
209     schemaInput.setImage(image.getImageCompositionData());
210
211     CompositionEntityValidationData validationData = compositionEntityDataManager
212         .validateEntity(image, SchemaTemplateContext.composition, schemaInput);
213     if (CollectionUtils.isEmpty(validationData.getErrors())) {
214       imageDao.update(image);
215     }
216
217     mdcDataDebugMessage
218         .debugExitMessage("VSP id, component id", image.getVspId(), image.getComponentId(),
219             image.getId());
220
221     return validationData;
222   }
223
224   @Override
225   public void updateImageQuestionnaire(String vspId, Version version, String componentId, String
226       imageId, String questionnaireData) {
227     mdcDataDebugMessage.debugEntryMessage("VSP id, component id, imageId", vspId, componentId,
228         imageId);
229
230     getImageEntity(vspId, version, componentId, imageId);
231
232
233     final ImageDetails image = JsonUtil.json2Object(questionnaireData, ImageDetails.class);
234     final String format = image.getFormat();
235     try {
236       if (format != null) {
237         ImageFormat.valueOf(format);
238       }
239     } catch (IllegalArgumentException exception) {
240       ErrorCode errorCode = ImageErrorBuilder.getInvalidImageFormatErrorBuilder();
241       MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
242           LoggerTragetServiceName.UPDATE_IMAGE, ErrorLevel.ERROR.name(),
243           errorCode.id(), errorCode.message());
244       throw new CoreException(errorCode);
245     }
246
247     //Validate Format is read only for HEAT Onboarding
248     if (!vspInfoDao.isManual(vspId, version)) {
249       final QuestionnaireResponse imageQuestionnaire = getImageQuestionnaire(vspId, version,
250           componentId, imageId);
251       final String data = imageQuestionnaire.getData();
252       if (data != null) {
253         String retrivedFormat = JsonUtil.json2Object(data, ImageDetails.class).getFormat();
254         validateHeatVspImageUpdate("format", format, retrivedFormat);
255       }
256     }
257
258     if (!isImageVersionUnique(vspId, version, componentId, imageId, image)) {
259       ErrorCode errorCode = ImageErrorBuilder.getDuplicateImageVersionErrorBuilder(image
260           .getVersion(), componentId);
261
262       MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
263           LoggerTragetServiceName.UPDATE_IMAGE, ErrorLevel.ERROR.name(),
264           errorCode.id(), errorCode.message());
265
266       throw new CoreException(errorCode);
267     }
268
269     imageDao.updateQuestionnaireData(vspId, version, componentId, imageId, questionnaireData);
270     mdcDataDebugMessage.debugExitMessage("VSP id, component id, imageId", vspId, componentId,
271         imageId);
272   }
273
274   private boolean isImageVersionUnique(String vspId, Version version, String componentId,
275                                        String imageId,
276                                        ImageDetails image) {
277     boolean isPresent = true;
278     if (image != null && image.getVersion() != null) {
279       Collection<ImageEntity> imageEntities =
280           imageDao.list(new ImageEntity(vspId, version, componentId, null));
281       if (CollectionUtils.isNotEmpty(imageEntities)) {
282         imageEntities =
283             imageEntities.stream().filter(imageEntity -> image.getVersion().trim().equalsIgnoreCase(
284                 getImageVersion(vspId, version, componentId, imageEntity))
285                 && !imageEntity.getId().equals(imageId)).collect(Collectors.toList());
286
287         isPresent = CollectionUtils.isEmpty(imageEntities);
288       }
289     }
290
291     return isPresent;
292   }
293
294   private String getImageVersion(String vspId, Version version, String componentId,
295                                  ImageEntity imageEntity) {
296     QuestionnaireResponse imageQuestionnaire = getImageQuestionnaire(vspId, version,
297         componentId, imageEntity.getId());
298     ImageDetails imageDetails =
299         JsonUtil.json2Object(imageQuestionnaire.getData(), ImageDetails.class);
300
301     return imageDetails == null ? null
302         : imageDetails.getVersion() != null ? imageDetails.getVersion().trim() : null;
303   }
304
305   private ImageEntity getImageEntity(String vspId, Version version, String componentId,
306                                      String imageId) {
307     //validateComponentId(vspId,version,componentId);
308
309     ImageEntity imageEntity = imageDao.get(new ImageEntity(vspId, version, componentId, imageId));
310
311     VersioningUtil.validateEntityExistence(imageEntity, new ImageEntity(vspId, version, componentId,
312         imageId), VspDetails.ENTITY_TYPE);
313     return imageEntity;
314   }
315
316   protected String getImageCompositionSchema(SchemaTemplateInput schemaInput) {
317     mdcDataDebugMessage.debugEntryMessage(null);
318     mdcDataDebugMessage.debugExitMessage(null);
319     return SchemaGenerator
320         .generate(SchemaTemplateContext.composition, CompositionEntityType.image,
321             schemaInput);
322   }
323
324   protected String getImageQuestionnaireSchema(SchemaTemplateInput schemaInput) {
325     mdcDataDebugMessage.debugEntryMessage(null);
326
327     mdcDataDebugMessage.debugExitMessage(null);
328     return SchemaGenerator
329         .generate(SchemaTemplateContext.questionnaire, CompositionEntityType.image,
330             schemaInput);
331   }
332 }