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