[SDC] Onboarding 1710 rebase.
[sdc.git] / openecomp-be / backend / openecomp-sdc-vendor-software-product-manager / src / main / java / org / openecomp / sdc / vendorsoftwareproduct / impl / ComponentManagerImpl.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.vendorsoftwareproduct.impl;
22
23 import static org.openecomp.sdc.tosca.datatypes.ToscaNodeType.VFC_NODE_TYPE_PREFIX;
24
25 import org.apache.commons.collections4.CollectionUtils;
26 import org.openecomp.core.utilities.json.JsonUtil;
27 import org.openecomp.sdc.common.errors.CoreException;
28 import org.openecomp.sdc.common.errors.ErrorCategory;
29 import org.openecomp.sdc.common.errors.ErrorCode;
30 import org.openecomp.sdc.datatypes.error.ErrorLevel;
31 import org.openecomp.sdc.logging.context.impl.MdcDataDebugMessage;
32 import org.openecomp.sdc.logging.context.impl.MdcDataErrorMessage;
33 import org.openecomp.sdc.logging.types.LoggerConstants;
34 import org.openecomp.sdc.logging.types.LoggerErrorCode;
35 import org.openecomp.sdc.logging.types.LoggerTragetServiceName;
36 import org.openecomp.sdc.vendorsoftwareproduct.ComponentManager;
37 import org.openecomp.sdc.vendorsoftwareproduct.NicManager;
38 import org.openecomp.sdc.vendorsoftwareproduct.dao.ComponentDao;
39 import org.openecomp.sdc.vendorsoftwareproduct.dao.VendorSoftwareProductInfoDao;
40 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.ComponentEntity;
41 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.VspDetails;
42 import org.openecomp.sdc.vendorsoftwareproduct.errors.CompositionEditNotAllowedErrorBuilder;
43 import org.openecomp.sdc.vendorsoftwareproduct.errors.VendorSoftwareProductErrorCodes;
44 import org.openecomp.sdc.vendorsoftwareproduct.services.composition.CompositionEntityDataManager;
45 import org.openecomp.sdc.vendorsoftwareproduct.services.schemagenerator.SchemaGenerator;
46 import org.openecomp.sdc.vendorsoftwareproduct.types.CompositionEntityResponse;
47 import org.openecomp.sdc.vendorsoftwareproduct.types.QuestionnaireResponse;
48 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.ComponentData;
49 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.CompositionEntityType;
50 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.CompositionEntityValidationData;
51 import org.openecomp.sdc.vendorsoftwareproduct.types.schemagenerator.ComponentCompositionSchemaInput;
52 import org.openecomp.sdc.vendorsoftwareproduct.types.schemagenerator.ComponentQuestionnaireSchemaInput;
53 import org.openecomp.sdc.vendorsoftwareproduct.types.schemagenerator.SchemaTemplateContext;
54 import org.openecomp.sdc.vendorsoftwareproduct.types.schemagenerator.SchemaTemplateInput;
55 import org.openecomp.sdc.vendorsoftwareproduct.utils.VendorSoftwareProductUtils;
56 import org.openecomp.sdc.versioning.VersioningUtil;
57 import org.openecomp.sdc.versioning.dao.types.Version;
58
59 import java.util.Collection;
60 import java.util.List;
61 import java.util.Map;
62 import java.util.stream.Collectors;
63
64 public class ComponentManagerImpl implements ComponentManager {
65   private static final MdcDataDebugMessage mdcDataDebugMessage = new MdcDataDebugMessage();
66   private ComponentDao componentDao;
67   private CompositionEntityDataManager compositionEntityDataManager;
68   private NicManager nicManager;
69   private VendorSoftwareProductInfoDao vspInfoDao;
70
71   public ComponentManagerImpl(
72       ComponentDao componentDao,
73       CompositionEntityDataManager compositionEntityDataManager,
74       NicManager nicManager, VendorSoftwareProductInfoDao vspInfoDao) {
75     this.componentDao = componentDao;
76     this.compositionEntityDataManager = compositionEntityDataManager;
77     this.nicManager = nicManager;
78     this.vspInfoDao = vspInfoDao;
79   }
80
81   @Override
82   public Collection<ComponentEntity> listComponents(String vspId, Version version, String user) {
83     mdcDataDebugMessage.debugEntryMessage("VSP id", vspId);
84     mdcDataDebugMessage.debugExitMessage("VSP id", vspId);
85     return componentDao.list(new ComponentEntity(vspId, version, null));
86   }
87
88   @Override
89   public void deleteComponents(String vspId, Version version, String user) {
90     mdcDataDebugMessage.debugEntryMessage("VSP id", vspId);
91     if (!vspInfoDao.isManual(vspId, version)) {
92       MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
93           LoggerTragetServiceName.DELETE_COMPONENT, ErrorLevel.ERROR.name(),
94           LoggerErrorCode.PERMISSION_ERROR.getErrorCode(), "Can't delete component");
95       throw new CoreException(
96           new CompositionEditNotAllowedErrorBuilder(vspId, version).build());
97     }
98
99     //componentDao.updateVspLatestModificationTime(vspId, version);
100     mdcDataDebugMessage.debugExitMessage("VSP id", vspId);
101   }
102
103   /*@Override
104   public ComponentEntity createComponent(ComponentEntity component, String user) {
105     mdcDataDebugMessage.debugEntryMessage("VSP id", component.getId());
106
107     if (!isManual(component.getVspId(), component.getVersion())) {
108       MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
109           LoggerTragetServiceName.CREATE_COMPONENT, ErrorLevel.ERROR.name(),
110           LoggerErrorCode.PERMISSION_ERROR.getErrorCode(), "Can't create component");
111       throw new CoreException(
112           new CompositionEditNotAllowedErrorBuilder(component.getVspId(), component.getVersion())
113               .build());
114
115     }
116     //componentDao.updateVspLatestModificationTime(component.getVspId(), component.getVersion());
117     mdcDataDebugMessage.debugExitMessage("VSP id", component.getId());
118     return null;
119   }*/
120
121   @Override
122   public ComponentEntity createComponent(ComponentEntity component, String user) {
123     mdcDataDebugMessage.debugEntryMessage("VSP id", component.getId());
124     /*Version activeVersion =
125         getVersionInfo(component.getVspId(), VersionableEntityAction.Write, user)
126             .getActiveVersion();
127     component.setVersion(activeVersion);*/
128
129     final String VFC_ADD_NOT_ALLOWED_IN_HEAT_ONBOARDING_MSG =
130         "VFCs cannot be added for VSPs onboarded with HEAT.";
131
132     ComponentEntity createdComponent = null;
133
134     if (!vspInfoDao.isManual(component.getVspId(), component.getVersion())) {
135       MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
136           LoggerTragetServiceName.CREATE_COMPONENT, ErrorLevel.ERROR.name(),
137           LoggerErrorCode.PERMISSION_ERROR.getErrorCode(), "Can't create component");
138       throw new CoreException(
139           new ErrorCode.ErrorCodeBuilder().withCategory(ErrorCategory.APPLICATION)
140               .withId(VendorSoftwareProductErrorCodes.VFC_ADD_NOT_ALLOWED_IN_HEAT_ONBOARDING)
141               .withMessage(VFC_ADD_NOT_ALLOWED_IN_HEAT_ONBOARDING_MSG).build());
142     } else {
143       validateComponentManual(component);
144       updateComponentName(component);
145       createdComponent = createComponent(component);
146     }
147
148     mdcDataDebugMessage.debugExitMessage("VSP id", component.getId());
149
150     return createdComponent;
151   }
152
153   private ComponentEntity createComponent(ComponentEntity component) {
154     return compositionEntityDataManager.createComponent(component);
155   }
156
157   private void updateComponentName(ComponentEntity component) {
158     final String NAME_PREFIX = VFC_NODE_TYPE_PREFIX + "heat.";
159     ComponentData data = component.getComponentCompositionData();
160     data.setName(NAME_PREFIX + data.getDisplayName());
161     component.setComponentCompositionData(data);
162   }
163
164   private void validateComponentManual(ComponentEntity component) {
165     final String VSP_VFC_COUNT_EXCEED_MSG = "Creation of only one VFC per "
166         + "VSP allowed.";
167
168     final String VSP_VFC_DUPLICATE_NAME_MSG = "VFC with specified name "
169         + "already present in given VSP.";
170
171     Collection<ComponentEntity> vspComponentList = listComponents(component.getVspId()
172         , component.getVersion(), null);
173     if (vspComponentList.size() >= 1) //1707 release only supports 1 VFC in VSP (manual creation)
174     {
175       MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
176           LoggerTragetServiceName.CREATE_COMPONENT, ErrorLevel.ERROR.name(),
177           LoggerErrorCode.PERMISSION_ERROR.getErrorCode(), "Can't create component: "
178               + "vsp component count exceed");
179       throw new CoreException(
180           new ErrorCode.ErrorCodeBuilder().withCategory(ErrorCategory.APPLICATION)
181               .withId(VendorSoftwareProductErrorCodes.VSP_VFC_COUNT_EXCEED)
182               .withMessage(VSP_VFC_COUNT_EXCEED_MSG).build());
183     }
184     if (!isVfcNameUnique(vspComponentList,
185         component.getComponentCompositionData().getDisplayName())) {
186       MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
187           LoggerTragetServiceName.CREATE_COMPONENT, ErrorLevel.ERROR.name(),
188           LoggerErrorCode.PERMISSION_ERROR.getErrorCode(), "Can't create component: "
189               + "vsp component duplicate name");
190       throw new CoreException(
191           new ErrorCode.ErrorCodeBuilder().withCategory(ErrorCategory.APPLICATION)
192               .withId(VendorSoftwareProductErrorCodes.VSP_VFC_DUPLICATE_NAME)
193               .withMessage(VSP_VFC_DUPLICATE_NAME_MSG).build());
194     }
195   }
196
197   private boolean isVfcNameUnique(Collection<ComponentEntity> component, String displayName) {
198     for (ComponentEntity comp : component) {
199       if (comp.getComponentCompositionData().getDisplayName().equalsIgnoreCase(displayName)) {
200         return false;
201       }
202     }
203     return true;
204   }
205
206   @Override
207   public CompositionEntityValidationData updateComponent(ComponentEntity component, String user) {
208     mdcDataDebugMessage.debugEntryMessage("VSP id, component id", component
209         .getVspId(), component.getId());
210     ComponentEntity retrieved =
211         getComponent(component.getVspId(), component.getVersion(), component.getId());
212
213     if (vspInfoDao.isManual(component.getVspId(), component.getVersion())) {
214       validateComponentUpdateManual(component, retrieved, user);
215     }
216
217
218     ComponentCompositionSchemaInput schemaInput = new ComponentCompositionSchemaInput();
219     schemaInput.setManual(vspInfoDao.isManual(component.getVspId(), component.getVersion()));
220     schemaInput.setComponent(retrieved.getComponentCompositionData());
221
222     CompositionEntityValidationData validationData = compositionEntityDataManager
223         .validateEntity(component, SchemaTemplateContext.composition, schemaInput);
224     if (CollectionUtils.isEmpty(validationData.getErrors())) {
225       updateComponentName(component);
226       componentDao.update(component);
227       //componentDao.updateVspLatestModificationTime(component.getVspId(), component.getVersion());
228     }
229     mdcDataDebugMessage.debugExitMessage("VSP id, component id", component.getVspId(),
230         component.getId());
231
232     return validationData;
233   }
234
235   private void validateComponentUpdateManual(ComponentEntity component, ComponentEntity
236       retrieved, String user) {
237     Collection<ComponentEntity> vspComponentList = listComponents(component.getVspId()
238         , component.getVersion(), user);
239     //Removing check from name as we will ignore passed value
240     // and re-genarate new name from displayName
241     //    List<String> invalidParameters = new LinkedList<>();
242     //    if (!component.getComponentCompositionData().getName().equals(retrieved
243     //        .getComponentCompositionData().getName())) {
244     //      invalidParameters.add(NAME);
245     //    }
246     //    if (!invalidParameters.isEmpty()) {
247     //      String msg = String.format(VFC_ATTRIBUTE_UPDATE_NOT_ALLOWED_MSG, StringUtils
248     //          .join(invalidParameters, ", "));
249     //      MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
250     //          LoggerTragetServiceName.UPDATE_COMPONENT, ErrorLevel.ERROR.name(),
251     //          LoggerErrorCode.DATA_ERROR.getErrorCode(), msg);
252     //
253     //      throw new CoreException(
254     //          new ErrorCode.ErrorCodeBuilder().withCategory(ErrorCategory.APPLICATION)
255     //              .withId(VendorSoftwareProductErrorCodes.VFC_ATTRIBUTE_UPDATE_NOT_ALLOWED)
256     //              .withMessage(msg).build());
257     //    }
258
259     //VFC name should be unique within VSP
260     //Removing VFC with same ID from list to avoid self compare
261     for(ComponentEntity ce : vspComponentList) {
262       if (ce.getId().equals(component.getId())) {
263         vspComponentList.remove(ce);
264         break;
265       }
266     }
267     if (!isVfcNameUnique(vspComponentList,  component.getComponentCompositionData()
268         .getDisplayName())) {
269        final String VSP_VFC_DUPLICATE_NAME_MSG = "VFC with specified name "
270           + "already present in given VSP.";
271       MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
272           LoggerTragetServiceName.UPDATE_COMPONENT, ErrorLevel.ERROR.name(),
273           LoggerErrorCode.PERMISSION_ERROR.getErrorCode(), "Component with same name already " +
274               "exists for specified VSP");
275       throw new CoreException(
276           new ErrorCode.ErrorCodeBuilder().withCategory(ErrorCategory.APPLICATION)
277               .withId(VendorSoftwareProductErrorCodes.VSP_VFC_DUPLICATE_NAME)
278               .withMessage(VSP_VFC_DUPLICATE_NAME_MSG).build());
279
280     }
281   }
282
283   public CompositionEntityResponse<ComponentData> getComponent(String vspId, Version version,
284                                                                String componentId, String user) {
285     mdcDataDebugMessage.debugEntryMessage("VSP id, component id", vspId, componentId);
286     ComponentEntity componentEntity = getComponent(vspId, version, componentId);
287     ComponentData component = componentEntity.getComponentCompositionData();
288
289     ComponentCompositionSchemaInput schemaInput = new ComponentCompositionSchemaInput();
290     schemaInput.setManual(vspInfoDao.isManual(vspId, version));
291     schemaInput.setComponent(component);
292
293     CompositionEntityResponse<ComponentData> response = new CompositionEntityResponse<>();
294     response.setId(componentId);
295     response.setData(component);
296     response.setSchema(getComponentCompositionSchema(schemaInput));
297     mdcDataDebugMessage.debugExitMessage("VSP id, component id", vspId, componentId);
298
299     return response;
300   }
301
302   @Override
303   public void deleteComponent(String vspId, Version version, String componentId, String user) {
304     mdcDataDebugMessage.debugEntryMessage("VSP id, component id", vspId, componentId);
305
306     if (!vspInfoDao.isManual(vspId, version)) {
307       MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
308           LoggerTragetServiceName.DELETE_COMPONENT, ErrorLevel.ERROR.name(),
309           LoggerErrorCode.PERMISSION_ERROR.getErrorCode(), "Can't delete component");
310       throw new CoreException(
311           new CompositionEditNotAllowedErrorBuilder(vspId, version).build());
312     }
313
314     //componentDao.updateVspLatestModificationTime(vspId, version);
315
316     mdcDataDebugMessage.debugExitMessage("VSP id, component id", vspId, componentId);
317   }
318
319   @Override
320   public QuestionnaireResponse getQuestionnaire(String vspId, Version version,
321                                                 String componentId, String user) {
322     mdcDataDebugMessage.debugEntryMessage("VSP id, component id", vspId, componentId);
323
324     QuestionnaireResponse questionnaireResponse = new QuestionnaireResponse();
325     ComponentEntity component = componentDao.getQuestionnaireData(vspId, version, componentId);
326     VersioningUtil
327         .validateEntityExistence(component, new ComponentEntity(vspId, version, componentId),
328             VspDetails.ENTITY_TYPE);
329
330     questionnaireResponse.setData(component.getQuestionnaireData());
331     List<String> nicNames = nicManager.listNics(vspId, version, componentId, user).stream()
332         .map(nic -> nic.getNicCompositionData().getName()).collect(Collectors.toList());
333     questionnaireResponse.setSchema(getComponentQuestionnaireSchema(
334         new ComponentQuestionnaireSchemaInput(nicNames, questionnaireResponse.getData() == null
335             ? null
336             : JsonUtil.json2Object(questionnaireResponse.getData(), Map.class))));
337
338     mdcDataDebugMessage.debugExitMessage("VSP id, component id", vspId, componentId);
339     return questionnaireResponse;
340   }
341
342   @Override
343   public void updateQuestionnaire(String vspId, Version version, String componentId,
344                                   String questionnaireData, String user) {
345     mdcDataDebugMessage.debugEntryMessage("VSP id, component id", vspId, componentId);
346     validateComponentExistence(vspId, version, componentId, user);
347
348     componentDao.updateQuestionnaireData(vspId, version, componentId, questionnaireData);
349
350     //componentDao.updateVspLatestModificationTime(vspId, version);
351     mdcDataDebugMessage.debugExitMessage("VSP id, component id", vspId, componentId);
352   }
353
354   @Override
355   public void validateComponentExistence(String vspId, Version version, String componentId,
356                                          String user) {
357     getComponent(vspId, version, componentId);
358   }
359
360   private ComponentEntity getComponent(String vspId, Version version, String componentId) {
361     ComponentEntity retrieved = componentDao.get(new ComponentEntity(vspId, version, componentId));
362     VersioningUtil
363         .validateEntityExistence(retrieved, new ComponentEntity(vspId, version, componentId),
364             VspDetails.ENTITY_TYPE);
365     return retrieved;
366   }
367
368   protected String getComponentCompositionSchema(ComponentCompositionSchemaInput schemaInput) {
369     return SchemaGenerator
370         .generate(SchemaTemplateContext.composition, CompositionEntityType.component, schemaInput);
371   }
372
373   protected String getComponentQuestionnaireSchema(SchemaTemplateInput schemaInput) {
374     return SchemaGenerator
375         .generate(SchemaTemplateContext.questionnaire, CompositionEntityType.component,
376             schemaInput);
377   }
378
379   /*private boolean isManual(String vspId, Version version) {
380     return false;
381   }*/
382 }