get_input property value deprecated format
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / ComponentBusinessLogic.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  * Modifications copyright (c) 2019 Nokia
20  * ================================================================================
21  */
22 package org.openecomp.sdc.be.components.impl;
23
24 import fj.data.Either;
25 import java.util.ArrayList;
26 import java.util.HashMap;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Map.Entry;
30 import java.util.Optional;
31 import java.util.function.BiFunction;
32 import java.util.function.BooleanSupplier;
33 import java.util.stream.Collectors;
34 import org.apache.commons.collections.CollectionUtils;
35 import org.apache.commons.lang3.StringUtils;
36 import org.apache.commons.lang3.tuple.ImmutablePair;
37 import org.openecomp.sdc.be.catalog.enums.ChangeTypeEnum;
38 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
39 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
40 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
41 import org.openecomp.sdc.be.components.impl.generic.GenericTypeBusinessLogic;
42 import org.openecomp.sdc.be.components.validation.component.ComponentContactIdValidator;
43 import org.openecomp.sdc.be.components.validation.component.ComponentDescriptionValidator;
44 import org.openecomp.sdc.be.components.validation.component.ComponentIconValidator;
45 import org.openecomp.sdc.be.components.validation.component.ComponentNameValidator;
46 import org.openecomp.sdc.be.components.validation.component.ComponentProjectCodeValidator;
47 import org.openecomp.sdc.be.components.validation.component.ComponentTagsValidator;
48 import org.openecomp.sdc.be.components.validation.component.ComponentValidator;
49 import org.openecomp.sdc.be.config.BeEcompErrorManager;
50 import org.openecomp.sdc.be.config.ConfigurationManager;
51 import org.openecomp.sdc.be.dao.api.ActionStatus;
52 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
53 import org.openecomp.sdc.be.dao.utils.MapUtil;
54 import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum;
55 import org.openecomp.sdc.be.datatypes.components.ServiceMetadataDataDefinition;
56 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
57 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
58 import org.openecomp.sdc.be.datatypes.enums.FilterKeyEnum;
59 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
60 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
61 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
62 import org.openecomp.sdc.be.facade.operations.CatalogOperation;
63 import org.openecomp.sdc.be.impl.ComponentsUtils;
64 import org.openecomp.sdc.be.model.ArtifactDefinition;
65 import org.openecomp.sdc.be.model.AttributeDefinition;
66 import org.openecomp.sdc.be.model.CapReqDef;
67 import org.openecomp.sdc.be.model.Component;
68 import org.openecomp.sdc.be.model.ComponentInstance;
69 import org.openecomp.sdc.be.model.ComponentInstanceInput;
70 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
71 import org.openecomp.sdc.be.model.ComponentParametersView;
72 import org.openecomp.sdc.be.model.DataTypeDefinition;
73 import org.openecomp.sdc.be.model.GroupDefinition;
74 import org.openecomp.sdc.be.model.IComponentInstanceConnectedElement;
75 import org.openecomp.sdc.be.model.InputDefinition;
76 import org.openecomp.sdc.be.model.LifecycleStateEnum;
77 import org.openecomp.sdc.be.model.Operation;
78 import org.openecomp.sdc.be.model.PropertyDefinition;
79 import org.openecomp.sdc.be.model.Resource;
80 import org.openecomp.sdc.be.model.User;
81 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
82 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
83 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
84 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
85 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
86 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
87 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
88 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
89 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
90 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
91 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
92 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
93 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo;
94 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
95 import org.openecomp.sdc.be.user.Role;
96 import org.openecomp.sdc.be.utils.CommonBeUtils;
97 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
98 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
99 import org.openecomp.sdc.common.log.wrappers.Logger;
100 import org.openecomp.sdc.common.util.ValidationUtils;
101 import org.openecomp.sdc.exception.ResponseFormat;
102 import org.springframework.beans.factory.annotation.Autowired;
103
104 public abstract class ComponentBusinessLogic extends BaseBusinessLogic {
105
106     private static final Logger log = Logger.getLogger(ComponentBusinessLogic.class.getName());
107
108     protected final GroupBusinessLogic groupBusinessLogic;
109     protected ArtifactsBusinessLogic artifactsBusinessLogic;
110     protected GenericTypeBusinessLogic genericTypeBusinessLogic;
111     protected ComponentDescriptionValidator componentDescriptionValidator;
112     protected ComponentProjectCodeValidator componentProjectCodeValidator;
113     protected CatalogOperation catalogOperations;
114     protected ComponentIconValidator componentIconValidator;
115     protected ComponentTagsValidator componentTagsValidator;
116     protected ComponentNameValidator componentNameValidator;
117     protected ComponentContactIdValidator componentContactIdValidator;
118
119     public ComponentBusinessLogic(IElementOperation elementDao, IGroupOperation groupOperation, IGroupInstanceOperation groupInstanceOperation,
120                                   IGroupTypeOperation groupTypeOperation, GroupBusinessLogic groupBusinessLogic,
121                                   InterfaceOperation interfaceOperation, InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
122                                   ArtifactsBusinessLogic artifactsBusinessLogic, ArtifactsOperations artifactToscaOperation,
123                                   ComponentContactIdValidator componentContactIdValidator, ComponentNameValidator componentNameValidator,
124                                   ComponentTagsValidator componentTagsValidator, ComponentValidator componentValidator,
125                                   ComponentIconValidator componentIconValidator, ComponentProjectCodeValidator componentProjectCodeValidator,
126                                   ComponentDescriptionValidator componentDescriptionValidator) {
127         super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation,
128             artifactToscaOperation);
129         this.artifactsBusinessLogic = artifactsBusinessLogic;
130         this.groupBusinessLogic = groupBusinessLogic;
131         this.componentContactIdValidator = componentContactIdValidator;
132         this.componentNameValidator = componentNameValidator;
133         this.componentTagsValidator = componentTagsValidator;
134         this.componentIconValidator = componentIconValidator;
135         this.componentProjectCodeValidator = componentProjectCodeValidator;
136         this.componentDescriptionValidator = componentDescriptionValidator;
137     }
138
139     private static Either<ArtifactDefinition, Operation> saveToscaArtifactAndPopulateToscaArtifactsWithResult(Component component,
140                                                                                                               final ComponentsUtils componentsUtils,
141                                                                                                               final ArtifactTypeEnum artifactEnum,
142                                                                                                               final BiFunction<Component, ArtifactDefinition, Either<ArtifactDefinition, Operation>> saveToscaArtifactPayloadFunction) {
143         ArtifactDefinition artifactDefinition = getToscaArtifactByTypeOrThrowException(component, artifactEnum, componentsUtils);
144         Either<ArtifactDefinition, Operation> result = saveToscaArtifactPayloadFunction.apply(component, artifactDefinition);
145         if (result.isLeft()) {
146             ArtifactDefinition def = result.left().value();
147             component.getToscaArtifacts().put(def.getArtifactLabel(), def);
148         }
149         return result;
150     }
151
152     private static Optional<ArtifactDefinition> getToscaArtifactByType(final Map<String, ArtifactDefinition> toscaArtifacts,
153                                                                        final ArtifactTypeEnum typeEnum) {
154         return toscaArtifacts.values().stream().filter(p -> p.getArtifactType().equals(typeEnum.getType())).findAny();
155     }
156
157     private static ArtifactDefinition getToscaArtifactByTypeOrThrowException(final Component component, final ArtifactTypeEnum typeEnum,
158                                                                              final ComponentsUtils componentsUtils) {
159         return Optional.ofNullable(component.getToscaArtifacts()).flatMap(toscaArtifacts -> getToscaArtifactByType(toscaArtifacts, typeEnum))
160             .orElseThrow(() -> {
161                 log.debug("Impossible to find a ToscaArtifact with type '{}' for {}", typeEnum.getType(), component);
162                 return new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, typeEnum.name()));
163             });
164     }
165
166     public void setComponentDescriptionValidator(ComponentDescriptionValidator componentDescriptionValidator) {
167         this.componentDescriptionValidator = componentDescriptionValidator;
168     }
169
170     public void setComponentProjectCodeValidator(ComponentProjectCodeValidator componentProjectCodeValidator) {
171         this.componentProjectCodeValidator = componentProjectCodeValidator;
172     }
173
174     public void setComponentIconValidator(ComponentIconValidator componentIconValidator) {
175         this.componentIconValidator = componentIconValidator;
176     }
177
178     public void setComponentContactIdValidator(ComponentContactIdValidator componentContactIdValidator) {
179         this.componentContactIdValidator = componentContactIdValidator;
180     }
181
182     public void setComponentTagsValidator(ComponentTagsValidator componentTagsValidator) {
183         this.componentTagsValidator = componentTagsValidator;
184     }
185
186     public void setComponentNameValidator(ComponentNameValidator componentNameValidator) {
187         this.componentNameValidator = componentNameValidator;
188     }
189
190     @Autowired
191     public void setGenericTypeBusinessLogic(GenericTypeBusinessLogic genericTypeBusinessLogic) {
192         this.genericTypeBusinessLogic = genericTypeBusinessLogic;
193     }
194
195     public abstract Either<List<String>, ResponseFormat> deleteMarkedComponents();
196
197     public abstract ComponentInstanceBusinessLogic getComponentInstanceBL();
198
199     public abstract Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId,
200                                                                                                                        String userId);
201
202     /**
203      * @param componentId
204      * @param dataParamsToReturn
205      * @return
206      */
207     public abstract Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String componentId,
208                                                                                                             List<String> dataParamsToReturn);
209     
210     public Either<ComponentMetadataData, StorageOperationStatus> getComponentMetadata(final String componentId) {
211         return toscaOperationFacade.getComponentMetadata(componentId);
212     }
213
214     User validateUser(User user, String ecompErrorContext, Component component, AuditingActionEnum auditAction, boolean inTransaction) {
215         User validatedUser;
216         ResponseFormat responseFormat;
217         try {
218             validateUserNotEmpty(user, ecompErrorContext);
219             validatedUser = validateUserExists(user);
220         } catch (ByActionStatusComponentException e) {
221             if (e.getActionStatus() == ActionStatus.MISSING_INFORMATION) {
222                 user.setUserId("UNKNOWN");
223             }
224             responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
225             componentsUtils.auditComponentAdmin(responseFormat, user, component, auditAction, component.getComponentType());
226             throw e;
227         } catch (ByResponseFormatComponentException e) {
228             responseFormat = e.getResponseFormat();
229             componentsUtils.auditComponentAdmin(responseFormat, user, component, auditAction, component.getComponentType());
230             throw e;
231         }
232         return validatedUser;
233     }
234
235     protected void validateUserRole(User user, Component component, List<Role> roles, AuditingActionEnum auditAction, String comment) {
236         if (roles != null && roles.isEmpty()) {
237             roles.add(Role.ADMIN);
238             roles.add(Role.DESIGNER);
239         }
240         try {
241             validateUserRole(user, roles);
242         } catch (ByActionStatusComponentException e) {
243             ResponseFormat responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
244             handleComponentException(component, comment, responseFormat, user, auditAction);
245             throw e;
246         } catch (ByResponseFormatComponentException e) {
247             ResponseFormat responseFormat = e.getResponseFormat();
248             handleComponentException(component, comment, responseFormat, user, auditAction);
249             throw e;
250         }
251     }
252
253     private void handleComponentException(Component component, String comment, ResponseFormat responseFormat, User user,
254                                           AuditingActionEnum auditAction) {
255         String commentStr = null;
256         String distrStatus = null;
257         ComponentTypeEnum componentType = component.getComponentType();
258         if (componentType == ComponentTypeEnum.SERVICE) {
259             distrStatus = ((ServiceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition())
260                 .getDistributionStatus();
261             commentStr = comment;
262         }
263         componentsUtils.auditComponent(responseFormat, user, component, auditAction, new ResourceCommonInfo(componentType.getValue()),
264             ResourceVersionInfo.newBuilder().distributionStatus(distrStatus).build(),
265             ResourceVersionInfo.newBuilder().distributionStatus(distrStatus).build(), commentStr, null, null);
266     }
267
268     public Either<Boolean, ResponseFormat> validateConformanceLevel(String componentUuid, ComponentTypeEnum componentTypeEnum, String userId) {
269         log.trace("validate conformance level");
270         if (componentTypeEnum != ComponentTypeEnum.SERVICE) {
271             log.error("conformance level validation for non service component, id {}", componentUuid);
272             ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
273             return Either.right(errorResponse);
274         }
275         validateUserExists(userId);
276         Either<ComponentMetadataData, StorageOperationStatus> eitherComponent = toscaOperationFacade
277             .getLatestComponentMetadataByUuid(componentUuid, JsonParseFlagEnum.ParseMetadata, null);
278         if (eitherComponent.isRight()) {
279             log.error("can't validate conformance level, component not found, uuid {}", componentUuid);
280             BeEcompErrorManager.getInstance().logBeComponentMissingError("validateConformanceLevel", componentTypeEnum.getValue(), componentUuid);
281             StorageOperationStatus status = eitherComponent.right().value();
282             ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(status, componentTypeEnum);
283             ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus);
284             return Either.right(responseFormat);
285         }
286         String componentConformanceLevel = eitherComponent.left().value().getMetadataDataDefinition().getConformanceLevel();
287         if (StringUtils.isBlank(componentConformanceLevel)) {
288             log.error("component conformance level property is null or empty, uuid {}", componentUuid);
289             ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
290             return Either.right(errorResponse);
291         }
292         String configConformanceLevel = ConfigurationManager.getConfigurationManager().getConfiguration().getMinToscaConformanceLevel();
293         Boolean result = true;
294         if (CommonBeUtils.conformanceLevelCompare(componentConformanceLevel, configConformanceLevel) < 0) {
295             log.error("invalid asset conformance level, uuid {}, asset conformanceLevel {}, config conformanceLevel {}", componentUuid,
296                 componentConformanceLevel, configConformanceLevel);
297             result = false;
298         }
299         log.trace("conformance level validation finished");
300         return Either.left(result);
301     }
302
303     protected void validateIcon(User user, Component component, AuditingActionEnum actionEnum) {
304         log.debug("validate Icon");
305         ComponentTypeEnum type = component.getComponentType();
306         String icon = component.getIcon();
307         if (!ValidationUtils.validateStringNotEmpty(icon)) {
308             log.info("icon is missing.");
309             ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_ICON, type.getValue());
310             componentsUtils.auditComponentAdmin(errorResponse, user, component, actionEnum, type);
311             throw new ComponentException(ActionStatus.COMPONENT_MISSING_ICON, type.getValue());
312         }
313         try {
314             validateIcon(icon, type);
315         } catch (ComponentException e) {
316             ResponseFormat responseFormat =
317                 e.getResponseFormat() != null ? e.getResponseFormat() : componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
318             componentsUtils.auditComponentAdmin(responseFormat, user, component, actionEnum, type);
319             throw e;
320         }
321     }
322
323     private void validateIcon(String icon, ComponentTypeEnum type) {
324         if (icon != null) {
325             if (!ValidationUtils.validateIconLength(icon)) {
326                 log.debug("icon exceeds max length");
327                 throw new ComponentException(ActionStatus.COMPONENT_ICON_EXCEEDS_LIMIT, type.getValue(), "" + ValidationUtils.ICON_MAX_LENGTH);
328             }
329             if (!ValidationUtils.validateIcon(icon)) {
330                 log.info("icon is invalid.");
331                 throw new ComponentException(ActionStatus.COMPONENT_INVALID_ICON, type.getValue());
332             }
333         }
334     }
335
336     protected void checkComponentFieldsForOverrideAttempt(Component component) {
337         if (component.getLifecycleState() != null) {
338             log.info("LifecycleState cannot be defined by user. This field will be overridden by the application");
339         }
340         if (component.getVersion() != null) {
341             log.info("Version cannot be defined by user. This field will be overridden by the application");
342         }
343         if (component.getCreatorUserId() != null || component.getCreatorFullName() != null) {
344             log.info("Creator cannot be defined by user. This field will be overridden by the application");
345         }
346         if (component.getLastUpdaterUserId() != null || component.getLastUpdaterFullName() != null) {
347             log.info("Last Updater cannot be defined by user. This field will be overridden by the application");
348         }
349         if (component.getCreationDate() != null) {
350             log.info("Creation Date cannot be defined by user. This field will be overridden by the application");
351         }
352         if (component.isHighestVersion() != null) {
353             log.info("Is Highest Version cannot be defined by user. This field will be overridden by the application");
354         }
355         if (component.getUUID() != null) {
356             log.info("UUID cannot be defined by user. This field will be overridden by the application");
357         }
358         if (component.getLastUpdateDate() != null) {
359             log.info("Last Update Date cannot be defined by user. This field will be overridden by the application");
360         }
361         if (component.getUniqueId() != null) {
362             log.info("uid cannot be defined by user. This field will be overridden by the application.");
363             component.setUniqueId(null);
364         }
365         if (component.getInvariantUUID() != null) {
366             log.info("Invariant UUID cannot be defined by user. This field will be overridden by the application.");
367         }
368     }
369
370     protected void validateComponentFieldsBeforeCreate(User user, Component component, AuditingActionEnum actionEnum) {
371         // validate component name uniqueness
372         log.debug("validate component name ");
373         componentNameValidator.validateAndCorrectField(user, component, actionEnum);
374         // validate description
375         log.debug("validate description");
376         componentDescriptionValidator.validateAndCorrectField(user, component, actionEnum);
377         // validate tags
378         log.debug("validate tags");
379         componentTagsValidator.validateAndCorrectField(user, component, actionEnum);
380         // validate contact info
381         log.debug("validate contact info");
382         componentContactIdValidator.validateAndCorrectField(user, component, actionEnum);
383         // validate icon
384         log.debug("validate icon");
385         validateIcon(user, component, actionEnum);
386     }
387
388     public CapReqDef getRequirementsAndCapabilities(String componentId, ComponentTypeEnum componentTypeEnum, String userId) {
389         validateUserExists(userId);
390         ComponentParametersView filter = new ComponentParametersView(true);
391         filter.setIgnoreCapabilities(false);
392         filter.setIgnoreRequirements(false);
393         filter.setIgnoreComponentInstances(false);
394         try {
395             Component component = validateComponentExists(componentId, componentTypeEnum, filter);
396             return new CapReqDef(component.getRequirements(), component.getCapabilities());
397         } catch (ComponentException e) {
398             BeEcompErrorManager.getInstance().logBeComponentMissingError("getRequirementsAndCapabilities", componentTypeEnum.getValue(), componentId);
399             throwComponentException(e.getResponseFormat());
400         }
401         return null;
402     }
403
404     public Either<List<Component>, ResponseFormat> getLatestVersionNotAbstractComponents(boolean isAbstractAbstract,
405                                                                                          ComponentTypeEnum componentTypeEnum,
406                                                                                          String internalComponentType, List<String> componentUids,
407                                                                                          String userId) {
408         try {
409             validateUserExists(userId);
410             List<Component> result = new ArrayList<>();
411             List<String> componentsUidToFetch = new ArrayList<>();
412             componentsUidToFetch.addAll(componentUids);
413             if (!componentsUidToFetch.isEmpty()) {
414                 log.debug("Number of Components to fetch from graph is {}", componentsUidToFetch.size());
415                 Either<List<Component>, StorageOperationStatus> nonCheckoutCompResponse = toscaOperationFacade
416                     .getLatestVersionNotAbstractComponents(isAbstractAbstract, componentTypeEnum, internalComponentType, componentsUidToFetch);
417                 if (nonCheckoutCompResponse.isLeft()) {
418                     log.debug("Retrived Resource successfully.");
419                     result.addAll(nonCheckoutCompResponse.left().value());
420                 } else {
421                     return Either.right(
422                         componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nonCheckoutCompResponse.right().value())));
423                 }
424             }
425             return Either.left(result);
426         } finally {
427             janusGraphDao.commit();
428         }
429     }
430
431     public Either<List<Component>, ResponseFormat> getLatestVersionNotAbstractComponentsMetadata(final boolean isAbstractAbstract,
432                                                                                                  final HighestFilterEnum highestFilter,
433                                                                                                  final ComponentTypeEnum componentTypeEnum,
434                                                                                                  final String internalComponentType, String userId,
435                                                                                                  final String modelName,
436                                                                                                  final boolean includeNormativeExtensionModels) {
437         Either<List<Component>, StorageOperationStatus> nonCheckoutCompResponse = null;
438         try {
439             validateUserExists(userId);
440             nonCheckoutCompResponse = toscaOperationFacade
441                 .getLatestVersionNotAbstractMetadataOnly(isAbstractAbstract, componentTypeEnum, internalComponentType, modelName,
442                     includeNormativeExtensionModels);
443             if (nonCheckoutCompResponse.isLeft()) {
444                 log.debug("Retrieved Resource successfully.");
445                 return Either.left(nonCheckoutCompResponse.left().value());
446             }
447             return Either
448                 .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nonCheckoutCompResponse.right().value())));
449         } finally {
450             if (nonCheckoutCompResponse != null && nonCheckoutCompResponse.isLeft()) {
451                 janusGraphDao.commit();
452             }
453         }
454     }
455
456     public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
457     }
458
459     @SuppressWarnings("unchecked")
460     public void setToscaArtifactsPlaceHolders(Component component, User user) {
461         Map<String, ArtifactDefinition> artifactMap = component.getToscaArtifacts();
462         if (artifactMap == null) {
463             artifactMap = new HashMap<>();
464         }
465         String componentUniqueId = component.getUniqueId();
466         String componentSystemName = component.getSystemName();
467         String componentType = component.getComponentType().getValue().toLowerCase();
468         Map<String, Object> toscaArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getToscaArtifacts();
469         if (toscaArtifacts != null) {
470             for (Entry<String, Object> artifactInfoMap : toscaArtifacts.entrySet()) {
471                 Map<String, Object> artifactInfo = (Map<String, Object>) artifactInfoMap.getValue();
472                 ArtifactDefinition artifactDefinition = artifactsBusinessLogic
473                     .createArtifactPlaceHolderInfo(componentUniqueId, artifactInfoMap.getKey(), artifactInfo, user, ArtifactGroupTypeEnum.TOSCA);
474                 artifactDefinition
475                     .setArtifactName(ValidationUtils.normalizeFileName(componentType + "-" + componentSystemName + artifactInfo.get("artifactName")));
476                 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
477             }
478         }
479         component.setToscaArtifacts(artifactMap);
480     }
481
482     public Either<ArtifactDefinition, Operation> populateToscaArtifacts(Component component, User user, boolean isInCertificationRequest,
483                                                                         boolean inTransaction, boolean shouldLock) {
484         return populateToscaArtifacts(component, user, isInCertificationRequest, inTransaction, shouldLock, true, true);
485     }
486
487     public Either<ArtifactDefinition, Operation> populateToscaArtifacts(Component component, User user, boolean isInCertificationRequest,
488                                                                         boolean inTransaction, boolean shouldLock, boolean retrieveResource) {
489         return populateToscaArtifacts(component, user, isInCertificationRequest, inTransaction, shouldLock, true, retrieveResource);
490     }
491
492     private Either<ArtifactDefinition, Operation> populateToscaArtifacts(Component component, User user, boolean isInCertificationRequest,
493                                                                          boolean inTransaction, boolean shouldLock, boolean fetchTemplatesFromDB,
494                                                                          boolean retrieveResource) {
495         if (retrieveResource) {
496             Either<Component, StorageOperationStatus> toscaElement = toscaOperationFacade.getToscaFullElement(component.getUniqueId());
497             if (toscaElement.isRight()) {
498                 throw new ByActionStatusComponentException(
499                     componentsUtils.convertFromStorageResponse(toscaElement.right().value(), component.getComponentType()));
500             }
501             component = toscaElement.left().value();
502         }
503         Either<ArtifactDefinition, Operation> generateToscaRes = saveToscaArtifactAndPopulateToscaArtifactsWithResult(component, componentsUtils,
504             ArtifactTypeEnum.TOSCA_TEMPLATE,
505             (comp, toscaArtifact) -> saveToscaArtifactPayload(toscaArtifact, comp, user, isInCertificationRequest, shouldLock, inTransaction,
506                 fetchTemplatesFromDB));
507         if (!isAbstractResource(component)) {
508             generateToscaRes = saveToscaArtifactAndPopulateToscaArtifactsWithResult(component, componentsUtils, ArtifactTypeEnum.TOSCA_CSAR,
509                 (comp, toscaArtifactArg) -> saveToscaArtifactPayload(toscaArtifactArg, comp, user, isInCertificationRequest, shouldLock,
510                     inTransaction, true));
511         }
512         return generateToscaRes;
513     }
514
515     private boolean isAbstractResource(Component component) {
516         return component.getComponentType() == ComponentTypeEnum.RESOURCE && ((Resource) component).isAbstract();
517     }
518
519     private Either<ArtifactDefinition, Operation> saveToscaArtifactPayload(ArtifactDefinition artifactDefinition,
520                                                                            org.openecomp.sdc.be.model.Component component, User user,
521                                                                            boolean isInCertificationRequest, boolean shouldLock,
522                                                                            boolean inTransaction, boolean fetchTemplatesFromDB) {
523         return artifactsBusinessLogic
524             .generateAndSaveToscaArtifact(artifactDefinition, component, user, isInCertificationRequest, shouldLock, inTransaction,
525                 fetchTemplatesFromDB);
526     }
527
528     public ImmutablePair<String, byte[]> getToscaModelByComponentUuid(ComponentTypeEnum componentType, String uuid,
529                                                                       ResourceCommonInfo resourceCommonInfo) {
530         Either<List<Component>, StorageOperationStatus> latestVersionEither = toscaOperationFacade.getComponentListByUuid(uuid, null);
531         if (latestVersionEither.isRight()) {
532             throw new ByActionStatusComponentException(
533                 componentsUtils.convertFromStorageResponse(latestVersionEither.right().value(), componentType));
534         }
535         List<Component> components = latestVersionEither.left().value();
536         Component component = components.stream().filter(Component::isHighestVersion).findFirst().orElse(null);
537         if (component == null) {
538             component = components.stream().filter(c -> c.getLifecycleState() == LifecycleStateEnum.CERTIFIED).findFirst().orElse(null);
539         }
540         if (component == null) {
541             throw new ByResponseFormatComponentException(
542                 componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND, componentType)));
543         }
544         resourceCommonInfo.setResourceName(component.getName());
545         // TODO remove after migration - handle artifact not found(no
546
547         // placeholder)
548         if (null == component.getToscaArtifacts() || component.getToscaArtifacts().isEmpty()) {
549             throw new ByResponseFormatComponentException(
550                 componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, ArtifactTypeEnum.TOSCA_CSAR.name()));
551         }
552
553         final ArtifactDefinition csarArtifact = component.getToscaArtifacts().values().stream()
554             .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.TOSCA_CSAR.getType())).findAny().orElseThrow(() -> {
555                 throw new ByResponseFormatComponentException(
556                     componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, ArtifactTypeEnum.TOSCA_CSAR.name()));
557             });
558         return artifactsBusinessLogic.handleDownloadToscaModelRequest(component, csarArtifact);
559     }
560
561     protected StorageOperationStatus markComponentToDelete(Component component) {
562         ComponentTypeEnum componentType = component.getComponentType();
563         String uniqueId = component.getUniqueId();
564         if (Boolean.TRUE.equals(component.getIsDeleted())) {
565             log.info("component {} already marked as deleted. id= {}, type={}", component.getName(), uniqueId, componentType);
566             return StorageOperationStatus.NOT_FOUND;
567         }
568         StorageOperationStatus markResourceToDelete = toscaOperationFacade.markComponentToDelete(component);
569         if (StorageOperationStatus.OK != markResourceToDelete) {
570             log.debug("failed to mark component {} of type {} for delete. error = {}", uniqueId, componentType, markResourceToDelete);
571             return markResourceToDelete;
572         } else {
573             log.debug("Component {}  of type {} was marked as deleted", uniqueId, componentType);
574             updateCatalog(component, ChangeTypeEnum.DELETE);
575             return StorageOperationStatus.OK;
576         }
577     }
578
579     public Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Component currentComponent, Component updatedComponent,
580                                                                         AuditingActionEnum auditingAction) {
581         String descriptionUpdated = updatedComponent.getDescription();
582         String descriptionCurrent = currentComponent.getDescription();
583         if (descriptionUpdated != null && !descriptionCurrent.equals(descriptionUpdated)) {
584             componentDescriptionValidator.validateAndCorrectField(user, updatedComponent, auditingAction);
585             currentComponent.setDescription(updatedComponent.getDescription());
586         }
587         return Either.left(true);
588     }
589
590     public Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Component currentComponent, Component updatedComponent) {
591         String projectCodeUpdated = updatedComponent.getProjectCode();
592         String projectCodeCurrent = currentComponent.getProjectCode();
593         if (projectCodeUpdated != null && !projectCodeCurrent.equals(projectCodeUpdated)) {
594             try {
595                 componentProjectCodeValidator.validateAndCorrectField(user, updatedComponent, null);
596             } catch (ComponentException exp) {
597                 ResponseFormat errorRespons = exp.getResponseFormat();
598                 return Either.right(errorRespons);
599             }
600             currentComponent.setProjectCode(updatedComponent.getProjectCode());
601         }
602         return Either.left(true);
603     }
604
605     public Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Component currentComponent, Component updatedComponent,
606                                                                  boolean hasBeenCertified) {
607         String iconUpdated = updatedComponent.getIcon();
608         String iconCurrent = currentComponent.getIcon();
609         if (iconUpdated != null && !iconCurrent.equals(iconUpdated)) {
610             if (!hasBeenCertified) {
611                 componentIconValidator.validateAndCorrectField(user, updatedComponent, null);
612                 currentComponent.setIcon(updatedComponent.getIcon());
613             } else {
614                 log.info("icon {} cannot be updated once the component has been certified once.", iconUpdated);
615                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_PARAMETER_CANNOT_BE_CHANGED, "Icon",
616                     currentComponent.getComponentType().name().toLowerCase());
617                 return Either.right(errorResponse);
618             }
619         }
620         return Either.left(true);
621     }
622
623     protected Either<List<String>, ResponseFormat> deleteMarkedComponents(ComponentTypeEnum componentType) {
624         log.trace("start deleteMarkedComponents");
625         Either<List<String>, StorageOperationStatus> deleteMarkedElements = toscaOperationFacade.deleteMarkedElements(componentType);
626         if (deleteMarkedElements.isRight()) {
627             janusGraphDao.rollback();
628             ResponseFormat responseFormat = componentsUtils
629                 .getResponseFormat(componentsUtils.convertFromStorageResponse(deleteMarkedElements.right().value(), componentType));
630             return Either.right(responseFormat);
631         }
632         log.trace("end deleteMarkedComponents");
633         janusGraphDao.commit();
634         return Either.left(deleteMarkedElements.left().value());
635     }
636
637     public Either<List<ArtifactDefinition>, StorageOperationStatus> getComponentArtifactsForDelete(String parentId, NodeTypeEnum parentType) {
638         List<ArtifactDefinition> artifacts = new ArrayList<>();
639         Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifactsResponse = artifactToscaOperation.getArtifacts(parentId);
640         if (artifactsResponse.isRight()) {
641             if (artifactsResponse.right().value() != StorageOperationStatus.NOT_FOUND) {
642                 log.debug("failed to retrieve artifacts for {} {}", parentType, parentId);
643                 return Either.right(artifactsResponse.right().value());
644             }
645         } else {
646             artifacts.addAll(artifactsResponse.left().value().values());
647         }
648         return Either.left(artifacts);
649     }
650
651     /**
652      * @param componentId
653      * @param user
654      * @param dataParamsToReturn - ui list of params to return
655      * @return
656      */
657     public Either<UiComponentDataTransfer, ResponseFormat> getComponentDataFilteredByParams(String componentId, User user,
658                                                                                             List<String> dataParamsToReturn) {
659         if (user != null) {
660             validateUserExists(user);
661         }
662         UiComponentDataTransfer result = new UiComponentDataTransfer();
663         if (dataParamsToReturn == null || dataParamsToReturn.isEmpty()) {
664             Either.left(result);
665         } else {
666             Either<UiComponentDataTransfer, ResponseFormat> uiDataTransferEither = getUiComponentDataTransferByComponentId(componentId,
667                 dataParamsToReturn);
668             if (uiDataTransferEither.isRight()) {
669                 return Either.right(uiDataTransferEither.right().value());
670             }
671             result = uiDataTransferEither.left().value();
672         }
673         return Either.left(result);
674     }
675
676     protected <T extends Component> void generateAndAddInputsFromGenericTypeProperties(T component, Resource genericType) {
677         List<InputDefinition> genericAndComponentInputs = new ArrayList<>();
678         List<InputDefinition> genericInputs = genericTypeBusinessLogic.generateInputsFromGenericTypeProperties(genericType);
679         genericAndComponentInputs.addAll(genericInputs);
680         if (null != component.getInputs()) {
681             List<InputDefinition> nonGenericInputsFromComponent = getAllNonGenericInputsFromComponent(genericInputs, component.getInputs());
682             genericAndComponentInputs.addAll(nonGenericInputsFromComponent);
683         }
684         component.setInputs(genericAndComponentInputs);
685     }
686
687     private List<InputDefinition> getAllNonGenericInputsFromComponent(List<InputDefinition> genericInputs, List<InputDefinition> componentInputs) {
688         if (genericInputs == null) {
689             return componentInputs;
690         }
691         Map<String, InputDefinition> inputByNameMap = MapUtil.toMap(genericInputs, InputDefinition::getName);
692         List<InputDefinition> componentNonGenericInputs = new ArrayList<>();
693         componentInputs.stream().forEach(input -> {
694             if (!inputByNameMap.containsKey(input.getName())) {
695                 componentNonGenericInputs.add(input);
696             }
697         });
698         return componentNonGenericInputs;
699     }
700
701     protected void generatePropertiesFromGenericType(final Component component, final Resource genericType) {
702         if (CollectionUtils.isEmpty(genericType.getProperties())) {
703             return;
704         }
705         final List<PropertyDefinition> genericTypePropertyList = genericType.getProperties().stream().map(PropertyDefinition::new)
706             .peek(propertyDefinition -> propertyDefinition.setUniqueId(null)).collect(Collectors.toList());
707         if (component.getProperties() == null) {
708             component.setProperties(new ArrayList<>(genericTypePropertyList));
709         } else {
710             List<PropertyDefinition> servicePropertyList = component.getProperties();
711             genericTypePropertyList.stream()
712                 .filter(property -> servicePropertyList.stream().noneMatch(property1 -> property1.getName().equals(property.getName())))
713                 .forEach(servicePropertyList::add);
714         }
715         component.getProperties().forEach(propertyDefinition -> propertyDefinition.setUniqueId(null));
716     }
717
718     protected <T extends Component> Resource fetchAndSetDerivedFromGenericType(final T component) {
719         return fetchAndSetDerivedFromGenericType(component, null);
720     }
721
722     protected <T extends Component> Resource fetchAndSetDerivedFromGenericType(final T component, final String toscaType) {
723         final Either<Resource, ResponseFormat> genericTypeEither = this.genericTypeBusinessLogic.fetchDerivedFromGenericType(component, toscaType);
724         if (genericTypeEither.isRight()) {
725             log.debug("Failed to fetch latest generic type for component {} of type", component.getName(), component.assetType());
726             throw new ByActionStatusComponentException(ActionStatus.GENERIC_TYPE_NOT_FOUND, component.assetType());
727         }
728         final Resource genericTypeResource = genericTypeEither.left().value();
729         component.setDerivedFromGenericInfo(genericTypeResource);
730         return genericTypeResource;
731     }
732
733     public Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> getFilteredComponentInstanceProperties(String componentId,
734                                                                                                                                 Map<FilterKeyEnum, List<String>> filters,
735                                                                                                                                 String userId) {
736         Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> response = null;
737         Either<Component, StorageOperationStatus> getResourceRes = null;
738         try {
739             if (!filters.containsKey(FilterKeyEnum.NAME_FRAGMENT) && StringUtils.isEmpty(filters.get(FilterKeyEnum.NAME_FRAGMENT).get(0))) {
740                 response = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
741             }
742             if (userId != null && response == null) {
743                 validateUserExists(userId);
744             }
745             if (response == null) {
746                 getResourceRes = toscaOperationFacade.getToscaElement(componentId);
747                 if (getResourceRes.isRight()) {
748                     response = Either
749                         .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(getResourceRes.right().value())));
750                 }
751             }
752             if (response == null) {
753                 response = getFilteredComponentInstancesProperties(getResourceRes.left().value(), filters);
754             }
755         } catch (Exception e) {
756             log.debug("The exception {} occured during filtered instance properties fetching. the  containing component is {}. ", e, componentId);
757             response = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
758         } finally {
759             if (response != null && response.isLeft()) {
760                 toscaOperationFacade.commit();
761             } else {
762                 toscaOperationFacade.rollback();
763             }
764         }
765         return response;
766     }
767
768     private Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> getFilteredComponentInstancesProperties(Component component,
769                                                                                                                                   Map<FilterKeyEnum, List<String>> filters) {
770         Map<String, List<IComponentInstanceConnectedElement>> filteredProperties = new HashMap<>();
771         Either<Map<String, List<IComponentInstanceConnectedElement>>, ResponseFormat> result = Either.left(filteredProperties);
772         List<ComponentInstance> filteredInstances = getFilteredInstances(component, filters.get(FilterKeyEnum.RESOURCE_TYPE));
773         String propertyNameFragment = filters.get(FilterKeyEnum.NAME_FRAGMENT).get(0);
774         boolean searchByFragment = propertyNameFragment.length() > 3;
775         if (CollectionUtils.isNotEmpty(filteredInstances)) {
776             for (ComponentInstance instance : filteredInstances) {
777                 if (component.getComponentInstancesProperties() != null && component.getComponentInstancesProperties()
778                     .containsKey(instance.getUniqueId())) {
779                     List<IComponentInstanceConnectedElement> currProperties = getFilteredComponentInstanceProperties(
780                         component.getComponentInstancesProperties().get(instance.getUniqueId()), propertyNameFragment, searchByFragment);
781                     setFilteredProperties(filteredProperties, instance, currProperties);
782                 }
783                 if (component.getComponentInstancesInputs() != null && component.getComponentInstancesInputs().containsKey(instance.getUniqueId())) {
784                     List<IComponentInstanceConnectedElement> currInputs = getFilteredComponentInstanceInputs(
785                         component.getComponentInstancesInputs().get(instance.getUniqueId()), propertyNameFragment, searchByFragment);
786                     if (CollectionUtils.isNotEmpty(currInputs)) {
787                         checkFilteredProperties(filteredProperties, instance, currInputs);
788                     }
789                 }
790             }
791         }
792         return result;
793     }
794
795     private void setFilteredProperties(Map<String, List<IComponentInstanceConnectedElement>> filteredProperties, ComponentInstance instance,
796                                        List<IComponentInstanceConnectedElement> currProperties) {
797         if (CollectionUtils.isNotEmpty(currProperties)) {
798             filteredProperties.put(instance.getUniqueId(), currProperties);
799         }
800     }
801
802     private void checkFilteredProperties(Map<String, List<IComponentInstanceConnectedElement>> filteredProperties, ComponentInstance instance,
803                                          List<IComponentInstanceConnectedElement> currInputs) {
804         if (filteredProperties.get(instance.getUniqueId()) != null) {
805             filteredProperties.get(instance.getUniqueId()).addAll(currInputs);
806         } else {
807             filteredProperties.put(instance.getUniqueId(), currInputs);
808         }
809     }
810
811     private List<IComponentInstanceConnectedElement> getFilteredComponentInstanceInputs(List<ComponentInstanceInput> inputs,
812                                                                                         String propertyNameFragment, boolean searchByFragment) {
813         return inputs.stream().filter(i -> isMatchingInput(i, propertyNameFragment, searchByFragment)).collect(Collectors.toList());
814     }
815
816     private List<IComponentInstanceConnectedElement> getFilteredComponentInstanceProperties(List<ComponentInstanceProperty> instanceProperties,
817                                                                                             String propertyNameFragment, boolean searchByFragment) {
818         return instanceProperties.stream().filter(p -> isMatchingProperty(p, propertyNameFragment, searchByFragment)).collect(Collectors.toList());
819     }
820
821     private boolean isMatchingInput(ComponentInstanceInput input, String propertyNameFragment, boolean searchByFragment) {
822         boolean isMatching = false;
823         if (searchByFragment && input.getName().toLowerCase().contains(propertyNameFragment)) {
824             isMatching = true;
825         }
826         if (!searchByFragment && input.getName().equalsIgnoreCase(propertyNameFragment)) {
827             isMatching = true;
828         }
829         return isMatching;
830     }
831
832     private boolean isMatchingProperty(ComponentInstanceProperty property, String propertyNameFragment, boolean searchByFragment) {
833         boolean isMatching = false;
834         if (searchByFragment && property.getName().toLowerCase().contains(propertyNameFragment)) {
835             isMatching = true;
836         }
837         if (!searchByFragment && property.getName().equalsIgnoreCase(propertyNameFragment)) {
838             isMatching = true;
839         }
840         if (!isMatching && !ToscaPropertyType.isPrimitiveType(property.getType())) {
841             isMatching = isMatchingComplexPropertyByRecursively(property, propertyNameFragment, searchByFragment);
842         }
843         return isMatching;
844     }
845
846     private boolean isMatchingComplexPropertyByRecursively(PropertyDataDefinition property, String propertyNameFragment, boolean searchByFragment) {
847         String propertyType;
848         List<PropertyDefinition> dataTypeProperties;
849         DataTypeDefinition currentProperty;
850         if (searchByFragment && property.getName().toLowerCase().contains(propertyNameFragment.toLowerCase())) {
851             return true;
852         }
853         if (!searchByFragment && property.getName().equalsIgnoreCase(propertyNameFragment)) {
854             return true;
855         }
856         propertyType = isEmptyInnerType(property) ? property.getType() : property.getSchema().getProperty().getType();
857         if (ToscaPropertyType.isScalarType(propertyType)) {
858             return false;
859         }
860         Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByNameRes = propertyOperation.getDataTypeByName(propertyType, null);
861         if (getDataTypeByNameRes.isRight()) {
862             return false;
863         }
864         currentProperty = getDataTypeByNameRes.left().value();
865         dataTypeProperties = currentProperty.getProperties();
866         boolean dataPropertiesNotNull = CollectionUtils.isNotEmpty(dataTypeProperties);
867         BooleanSupplier dataMatchesComplexProperty = () -> isMatchingComplexProperty(propertyNameFragment, searchByFragment, dataTypeProperties);
868         BooleanSupplier parentPropertiesNotNull = () -> CollectionUtils.isNotEmpty(currentProperty.getDerivedFrom().getProperties());
869         BooleanSupplier parentDataMatchesComplexProperty = () -> isMatchingComplexProperty(propertyNameFragment, searchByFragment,
870             currentProperty.getDerivedFrom().getProperties());
871         return ((dataPropertiesNotNull && dataMatchesComplexProperty.getAsBoolean()) || (parentPropertiesNotNull.getAsBoolean()
872             && parentDataMatchesComplexProperty.getAsBoolean()));
873     }
874
875     private boolean isMatchingComplexProperty(String propertyNameFragment, boolean searchByFragment, List<PropertyDefinition> dataTypeProperties) {
876         for (PropertyDefinition prop : dataTypeProperties) {
877             if (isMatchingComplexPropertyByRecursively(prop, propertyNameFragment, searchByFragment)) {
878                 return true;
879             }
880         }
881         return false;
882     }
883
884     private boolean isEmptyInnerType(PropertyDataDefinition property) {
885         return property == null || property.getSchema() == null || property.getSchema().getProperty() == null
886             || property.getSchema().getProperty().getType() == null;
887     }
888
889     public Either<Boolean, ResponseFormat> shouldUpgradeToLatestGeneric(Component clonedComponent) {
890         if (!clonedComponent.deriveFromGeneric() || StringUtils.isNotEmpty(clonedComponent.getModel())) {
891             return Either.left(false);
892         }
893         Boolean shouldUpgrade = false;
894         String currentGenericType = clonedComponent.getDerivedFromGenericType();
895         String currentGenericVersion = clonedComponent.getDerivedFromGenericVersion();
896         Resource genericTypeResource = fetchAndSetDerivedFromGenericType(clonedComponent);
897         if (null == currentGenericType || !currentGenericType.equals(genericTypeResource.getToscaResourceName()) || !currentGenericVersion
898             .equals(genericTypeResource.getVersion())) {
899             shouldUpgrade = upgradeToLatestGeneric(clonedComponent, genericTypeResource);
900             if (!shouldUpgrade) {
901                 reverntUpdateOfGenericVersion(clonedComponent, currentGenericType, currentGenericVersion);
902             }
903         }
904         return Either.left(shouldUpgrade);
905     }
906
907     private void reverntUpdateOfGenericVersion(Component clonedComponent, String currentGenericType, String currentGenericVersion) {
908         clonedComponent.setDerivedFromGenericType(currentGenericType);
909         clonedComponent.setDerivedFromGenericVersion(currentGenericVersion);
910     }
911
912     private <T extends ToscaDataDefinition> Either<Map<String, T>, String> validateNoConflictingProperties(List<T> currentList,
913                                                                                                            List<T> upgradedList) {
914         Map<String, T> currentMap = ToscaDataDefinition.listToMapByName(currentList);
915         Map<String, T> upgradedMap = ToscaDataDefinition.listToMapByName(upgradedList);
916         return ToscaDataDefinition.mergeDataMaps(upgradedMap, currentMap, true);
917     }
918
919     private boolean shouldUpgradeNodeType(Component componentToCheckOut, Resource latestGeneric) {
920         List<PropertyDefinition> genericTypeProps = latestGeneric.getProperties();
921         Either<Map<String, PropertyDefinition>, String> validPropertiesMerge = validateNoConflictingProperties(genericTypeProps,
922             ((Resource) componentToCheckOut).getProperties());
923         if (validPropertiesMerge.isRight()) {
924             if (log.isDebugEnabled()) {
925                 log.debug("property {} cannot be overriden, check out performed without upgrading to latest generic",
926                     validPropertiesMerge.right().value());
927             }
928             return false;
929         }
930         List<AttributeDefinition> genericTypeAttributes = latestGeneric.getAttributes();
931         final Either<Map<String, AttributeDefinition>, String> validAttributesMerge = validateNoConflictingProperties(genericTypeAttributes,
932             ((Resource) componentToCheckOut).getAttributes());
933         if (validAttributesMerge.isRight()) {
934             if (log.isDebugEnabled()) {
935                 log.debug("attribute {} cannot be overriden, check out performed without upgrading to latest generic",
936                     validAttributesMerge.right().value());
937             }
938             return false;
939         }
940         return true;
941     }
942
943     private boolean upgradeToLatestGeneric(Component componentToCheckOut, Resource latestGeneric) {
944         if (!componentToCheckOut.shouldGenerateInputs()) {
945             //node type - validate properties and attributes
946             return shouldUpgradeNodeType(componentToCheckOut, latestGeneric);
947         }
948         List<PropertyDefinition> genericTypeProps = latestGeneric.getProperties();
949         List<InputDefinition> genericTypeInputs = null == genericTypeProps ? null
950             : genericTypeBusinessLogic.convertGenericTypePropertiesToInputsDefintion(genericTypeProps, latestGeneric.getUniqueId());
951         List<InputDefinition> currentList = new ArrayList<>();
952         // nullify existing ownerId from existing list and merge into updated list
953         if (null != componentToCheckOut.getInputs()) {
954             for (InputDefinition input : componentToCheckOut.getInputs()) {
955                 InputDefinition copy = new InputDefinition(input);
956                 copy.setOwnerId(null);
957                 currentList.add(copy);
958             }
959         }
960         if (null == genericTypeInputs) {
961             componentToCheckOut.setInputs(currentList);
962             return true;
963         }
964         Either<Map<String, InputDefinition>, String> eitherMerged = validateNoConflictingProperties(genericTypeInputs, currentList);
965         if (eitherMerged.isRight()) {
966             if (log.isDebugEnabled()) {
967                 log.debug("input {} cannot be overriden, check out performed without upgrading to latest generic", eitherMerged.right().value());
968             }
969             return false;
970         }
971         componentToCheckOut.setInputs(new ArrayList<>(eitherMerged.left().value().values()));
972         return true;
973     }
974
975     private List<ComponentInstance> getFilteredInstances(Component component, List<String> resourceTypes) {
976         List<ComponentInstance> filteredInstances = null;
977         if (CollectionUtils.isEmpty(resourceTypes)) {
978             filteredInstances = component.getComponentInstances();
979         } else if (CollectionUtils.isNotEmpty(component.getComponentInstances())) {
980             filteredInstances = component.getComponentInstances().stream().filter(i -> isMatchingType(i.getOriginType(), resourceTypes))
981                 .collect(Collectors.toList());
982         }
983         if (filteredInstances == null) {
984             filteredInstances = new ArrayList<>();
985         }
986         return filteredInstances;
987     }
988
989     private boolean isMatchingType(OriginTypeEnum originType, List<String> resourceTypes) {
990         boolean isMatchingType = false;
991         for (String resourceType : resourceTypes) {
992             if (originType == OriginTypeEnum.findByValue(resourceType.toUpperCase())) {
993                 isMatchingType = true;
994                 break;
995             }
996         }
997         return isMatchingType;
998     }
999
1000     public Either<Component, ActionStatus> shouldUpgradeToLatestDerived(Component clonedComponent) {
1001         //general implementation. Must be error for service, VF . In ResourceBuisnessLogic exist override
1002         return Either.right(ActionStatus.GENERAL_ERROR);
1003     }
1004
1005     protected Either<Component, ResponseFormat> updateCatalog(Component component, ChangeTypeEnum changeStatus) {
1006         if (log.isDebugEnabled()) {
1007             log.debug("update Catalog start with Component Type {} And Componet Name {} with change status {}",
1008                 component.getComponentType().name(), component.getName(), changeStatus.name());
1009         }
1010         ActionStatus status = catalogOperations.updateCatalog(changeStatus, component);
1011         if (status != ActionStatus.OK) {
1012             return Either.right(componentsUtils.getResponseFormat(status));
1013         }
1014         return Either.left(component);
1015     }
1016
1017     public CatalogOperation getCatalogOperations() {
1018         return catalogOperations;
1019     }
1020
1021     @Autowired
1022     public void setCatalogOperations(CatalogOperation catalogOperations) {
1023         this.catalogOperations = catalogOperations;
1024     }
1025
1026     public List<GroupDefinition> throwComponentException(ResponseFormat responseFormat) {
1027         throw new ByResponseFormatComponentException(responseFormat);
1028     }
1029 }