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