Initial OpenECOMP SDC commit
[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  */
20
21 package org.openecomp.sdc.be.components.impl;
22
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.EnumMap;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Map.Entry;
31 import java.util.Set;
32 import java.util.stream.Collectors;
33
34 import org.apache.commons.lang3.tuple.ImmutablePair;
35 import org.apache.commons.lang3.tuple.ImmutableTriple;
36 import org.openecomp.sdc.be.config.BeEcompErrorManager;
37 import org.openecomp.sdc.be.config.ConfigurationManager;
38 import org.openecomp.sdc.be.dao.api.ActionStatus;
39 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
40 import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum;
41 import org.openecomp.sdc.be.datatypes.components.ServiceMetadataDataDefinition;
42 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
43 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
44 import org.openecomp.sdc.be.model.ArtifactDefinition;
45 import org.openecomp.sdc.be.model.CapReqDef;
46 import org.openecomp.sdc.be.model.CapabilityDefinition;
47 import org.openecomp.sdc.be.model.Component;
48 import org.openecomp.sdc.be.model.ComponentInstance;
49 import org.openecomp.sdc.be.model.Operation;
50 import org.openecomp.sdc.be.model.RequirementDefinition;
51 import org.openecomp.sdc.be.model.User;
52 import org.openecomp.sdc.be.model.cache.ComponentCache;
53 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
54 import org.openecomp.sdc.be.model.operations.impl.ComponentOperation;
55 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
56 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
57 import org.openecomp.sdc.be.user.Role;
58 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
59 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
60 import org.openecomp.sdc.common.config.EcompErrorName;
61 import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum;
62 import org.openecomp.sdc.common.util.ValidationUtils;
63 import org.openecomp.sdc.exception.ResponseFormat;
64 import org.slf4j.Logger;
65 import org.slf4j.LoggerFactory;
66 import org.springframework.beans.factory.annotation.Autowired;
67
68 import fj.data.Either;
69
70 public abstract class ComponentBusinessLogic extends BaseBusinessLogic {
71
72         @Autowired
73         protected ArtifactsBusinessLogic artifactsBusinessLogic;
74
75         @Autowired
76         protected ComponentCache componentCache;
77
78         private static Logger log = LoggerFactory.getLogger(ComponentBusinessLogic.class.getName());
79
80         private static final String TAG_FIELD_LABEL = "tag";
81
82         public abstract Either<List<String>, ResponseFormat> deleteMarkedComponents();
83
84         public abstract ComponentInstanceBusinessLogic getComponentInstanceBL();
85
86         public abstract Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, ComponentTypeEnum componentTypeEnum, String userId, String searchText);
87
88         protected Either<User, ResponseFormat> validateUser(User user, String ecompErrorContext, Component component, AuditingActionEnum auditAction, boolean inTransaction) {
89                 Either<User, ResponseFormat> userValidationResult = validateUserNotEmpty(user, ecompErrorContext);
90                 ResponseFormat responseFormat;
91                 if (userValidationResult.isRight()) {
92                         user.setUserId("UNKNOWN");
93                         responseFormat = userValidationResult.right().value();
94                         componentsUtils.auditComponentAdmin(responseFormat, user, component, "", "", auditAction, component.getComponentType());
95                         return Either.right(responseFormat);
96                 }
97                 Either<User, ResponseFormat> userResult = validateUserExists(user, ecompErrorContext, inTransaction);
98                 if (userResult.isRight()) {
99                         responseFormat = userResult.right().value();
100                         componentsUtils.auditComponentAdmin(responseFormat, user, component, "", "", auditAction, component.getComponentType());
101                         return Either.right(responseFormat);
102                 }
103                 user = userResult.left().value();
104                 return userResult;
105         }
106
107         protected Either<Boolean, ResponseFormat> validateUserRole(User user, Component component, List<Role> roles, AuditingActionEnum auditAction, String comment) {
108                 if (roles != null && roles.isEmpty()) {
109                         roles.add(Role.ADMIN);
110                         roles.add(Role.DESIGNER);
111                 }
112                 Either<Boolean, ResponseFormat> validationResult = validateUserRole(user, roles);
113                 if (validationResult.isRight()) {
114                         ComponentTypeEnum componentType = component.getComponentType();
115                         EnumMap<AuditingFieldsKeysEnum, Object> additionalParams = new EnumMap<>(AuditingFieldsKeysEnum.class);
116                         if (componentType.equals(ComponentTypeEnum.SERVICE)) {
117                                 additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_COMMENT, comment);
118                                 String distributionStatus = ((ServiceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition()).getDistributionStatus();
119                                 additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_DPREV_STATUS, distributionStatus);
120                                 additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_DCURR_STATUS, distributionStatus);
121                         }
122                         componentsUtils.auditComponent(validationResult.right().value(), user, component, "", "", auditAction, componentType, additionalParams);
123                 }
124                 return validationResult;
125         }
126
127         protected Either<Boolean, ResponseFormat> validateComponentName(User user, Component component, AuditingActionEnum actionEnum) {
128                 ComponentTypeEnum type = component.getComponentType();
129                 String componentName = component.getName();
130                 if (!ValidationUtils.validateStringNotEmpty(componentName)) {
131                         log.debug("component name is empty");
132                         ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_COMPONENT_NAME, type.getValue());
133                         componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type);
134                         return Either.right(errorResponse);
135                 }
136
137                 if (!ValidationUtils.validateComponentNameLength(componentName)) {
138                         log.debug("Component name exceeds max length {} ", ValidationUtils.COMPONENT_NAME_MAX_LENGTH);
139                         ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_NAME_EXCEEDS_LIMIT, type.getValue(), "" + ValidationUtils.COMPONENT_NAME_MAX_LENGTH);
140                         componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type);
141                         return Either.right(errorResponse);
142                 }
143
144                 if (!validateTagPattern(componentName)) {
145                         log.debug("Component name {} has invalid format", componentName);
146                         ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_COMPONENT_NAME, type.getValue());
147                         componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type);
148                         return Either.right(errorResponse);
149                 }
150                 component.setNormalizedName(ValidationUtils.normaliseComponentName(componentName));
151                 component.setSystemName(ValidationUtils.convertToSystemName(componentName));
152
153                 return Either.left(true);
154         }
155
156         protected Either<Boolean, ResponseFormat> validateDescriptionAndCleanup(User user, Component component, AuditingActionEnum actionEnum) {
157                 ComponentTypeEnum type = component.getComponentType();
158                 String description = component.getDescription();
159                 if (!ValidationUtils.validateStringNotEmpty(description)) {
160                         ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_DESCRIPTION, type.getValue());
161                         componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type);
162                         return Either.right(errorResponse);
163                 }
164
165                 description = ValidationUtils.removeNoneUtf8Chars(description);
166                 description = ValidationUtils.normaliseWhitespace(description);
167                 description = ValidationUtils.stripOctets(description);
168                 description = ValidationUtils.removeHtmlTagsOnly(description);
169
170                 Either<Boolean, ResponseFormat> validatDescription = validateComponentDescription(description, type);
171                 if (validatDescription.isRight()) {
172                         ResponseFormat responseFormat = validatDescription.right().value();
173                         componentsUtils.auditComponentAdmin(responseFormat, user, component, "", "", actionEnum, type);
174                         return Either.right(responseFormat);
175                 }
176                 component.setDescription(description);
177                 return Either.left(true);
178         }
179
180         public Either<Boolean, ResponseFormat> validateComponentDescription(String description, ComponentTypeEnum type) {
181                 if (description != null) {
182                         if (!ValidationUtils.validateDescriptionLength(description)) {
183                                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_DESCRIPTION_EXCEEDS_LIMIT, type.getValue(), "" + ValidationUtils.COMPONENT_DESCRIPTION_MAX_LENGTH));
184                         }
185
186                         if (!ValidationUtils.validateIsEnglish(description)) {
187                                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_DESCRIPTION, type.getValue()));
188                         }
189                         return Either.left(true);
190                 }
191                 return Either.left(false);
192         }
193
194         protected Either<Boolean, ResponseFormat> validateComponentNameUnique(User user, Component component, AuditingActionEnum actionEnum) {
195                 ComponentTypeEnum type = component.getComponentType();
196                 ComponentOperation componentOperation = getComponentOperation(type);
197                 Either<Boolean, StorageOperationStatus> dataModelResponse;
198                 dataModelResponse = componentOperation.validateComponentNameExists(component.getName());
199
200                 if (dataModelResponse.isLeft()) {
201                         if (dataModelResponse.left().value()) {
202                                 return Either.left(true);
203                         } else {
204                                 log.info("Component with name {} already exists", component.getName());
205                                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_NAME_ALREADY_EXIST, type.getValue(), component.getName());
206                                 componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type);
207                                 return Either.right(errorResponse);
208                         }
209                 }
210                 BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "validateComponentNameUnique");
211                 BeEcompErrorManager.getInstance().logBeSystemError("validateComponentNameUnique");
212                 log.debug("Error while validateComponentNameUnique for component: {}", component.getName());
213                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
214                 componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type);
215                 return Either.right(errorResponse);
216         }
217
218         protected Either<Boolean, ResponseFormat> validateContactId(User user, Component component, AuditingActionEnum actionEnum) {
219                 log.debug("validate component contact info");
220                 ComponentTypeEnum type = component.getComponentType();
221                 String contactId = component.getContactId();
222
223                 if (!ValidationUtils.validateStringNotEmpty(contactId)) {
224                         log.info("contact info is missing.");
225                         ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CONTACT, type.getValue());
226                         componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type);
227                         return Either.right(errorResponse);
228                 }
229
230                 Either<Boolean, ResponseFormat> validateContactIdResponse = validateContactId(contactId, type);
231                 if (validateContactIdResponse.isRight()) {
232                         ResponseFormat responseFormat = validateContactIdResponse.right().value();
233                         componentsUtils.auditComponentAdmin(responseFormat, user, component, "", "", actionEnum, type);
234                 }
235                 return validateContactIdResponse;
236         }
237
238         private Either<Boolean, ResponseFormat> validateContactId(String contactId, ComponentTypeEnum type) {
239                 if (contactId != null) {
240                         if (!ValidationUtils.validateContactId(contactId)) {
241                                 log.info("contact info is invalid.");
242                                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_CONTACT, type.getValue());
243                                 return Either.right(errorResponse);
244                         }
245                         return Either.left(true);
246                 }
247                 return Either.left(false);
248         }
249
250         protected Either<Boolean, ResponseFormat> validateIcon(User user, Component component, AuditingActionEnum actionEnum) {
251                 log.debug("validate Icon");
252                 ComponentTypeEnum type = component.getComponentType();
253                 String icon = component.getIcon();
254                 if (!ValidationUtils.validateStringNotEmpty(icon)) {
255                         log.info("icon is missing.");
256                         ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_ICON, type.getValue());
257                         componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type);
258                         return Either.right(errorResponse);
259                 }
260
261                 Either<Boolean, ResponseFormat> validateIcon = validateIcon(icon, type);
262                 if (validateIcon.isRight()) {
263                         ResponseFormat responseFormat = validateIcon.right().value();
264                         componentsUtils.auditComponentAdmin(responseFormat, user, component, "", "", actionEnum, type);
265                 }
266                 return validateIcon;
267         }
268
269         private Either<Boolean, ResponseFormat> validateIcon(String icon, ComponentTypeEnum type) {
270                 if (icon != null) {
271                         if (!ValidationUtils.validateIconLength(icon)) {
272                                 log.debug("icon exceeds max length");
273                                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ICON_EXCEEDS_LIMIT, type.getValue(), "" + ValidationUtils.ICON_MAX_LENGTH));
274                         }
275
276                         if (!ValidationUtils.validateIcon(icon)) {
277                                 log.info("icon is invalid.");
278                                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_ICON, type.getValue());
279                                 return Either.right(errorResponse);
280                         }
281                         return Either.left(true);
282                 }
283                 return Either.left(false);
284         }
285
286         protected Either<Boolean, ResponseFormat> validateTagsListAndRemoveDuplicates(User user, Component component, AuditingActionEnum actionEnum) {
287                 List<String> tagsList = component.getTags();
288
289                 Either<Boolean, ResponseFormat> validateTags = validateComponentTags(tagsList, component.getName(), component.getComponentType());
290                 if (validateTags.isRight()) {
291                         ResponseFormat responseFormat = validateTags.right().value();
292                         componentsUtils.auditComponentAdmin(responseFormat, user, component, "", "", actionEnum, component.getComponentType());
293                         return Either.right(responseFormat);
294                 }
295                 ValidationUtils.removeDuplicateFromList(tagsList);
296                 return Either.left(true);
297         }
298
299         protected Either<Boolean, ResponseFormat> validateComponentTags(List<String> tags, String name, ComponentTypeEnum componentType) {
300                 log.debug("validate component tags");
301                 boolean includesComponentName = false;
302                 int tagListSize = 0;
303                 if (tags != null && !tags.isEmpty()) {
304                         for (String tag : tags) {
305                                 if (!ValidationUtils.validateTagLength(tag)) {
306                                         log.debug("tag length exceeds limit {}", ValidationUtils.TAG_MAX_LENGTH);
307                                         return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_SINGLE_TAG_EXCEED_LIMIT, "" + ValidationUtils.TAG_MAX_LENGTH));
308                                 }
309                                 if (validateTagPattern(tag)) {
310                                         if (!includesComponentName) {
311                                                 includesComponentName = name.equals(tag);
312                                         }
313                                 } else {
314                                         log.debug("invalid tag {}", tag);
315                                         return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_FIELD_FORMAT, componentType.getValue(), TAG_FIELD_LABEL));
316                                 }
317                                 tagListSize += tag.length() + 1;
318                         }
319                         if (tagListSize > 0) {
320                                 tagListSize--;
321                         }
322
323                         if (!includesComponentName) {
324                                 log.debug("tags must include component name");
325                                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_TAGS_NO_COMP_NAME));
326                         }
327                         if (!ValidationUtils.validateTagListLength(tagListSize)) {
328                                 log.debug("overall tags length exceeds limit {}", ValidationUtils.TAG_LIST_MAX_LENGTH);
329                                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_TAGS_EXCEED_LIMIT, "" + ValidationUtils.TAG_LIST_MAX_LENGTH));
330                         }
331                         return Either.left(true);
332                 }
333                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_TAGS));
334         }
335
336         protected boolean validateTagPattern(String tag) {
337                 return ValidationUtils.validateComponentNamePattern(tag);
338         }
339
340         protected Either<Boolean, ResponseFormat> validateProjectCode(User user, Component component, AuditingActionEnum actionEnum) {
341                 if (ComponentTypeEnum.RESOURCE.equals(component.getComponentType())) {
342                         return Either.left(true);
343                 }
344                 log.debug("validate PROJECT_CODE name ");
345                 String projectCode = component.getProjectCode();
346
347                 if (!ValidationUtils.validateStringNotEmpty(projectCode)) {
348                         log.info("projectCode is missing.");
349                         ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_PROJECT_CODE);
350                         componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, component.getComponentType());
351                         return Either.right(errorResponse);
352                 }
353
354                 Either<Boolean, ResponseFormat> validateProjectCodeResponse = validateProjectCode(projectCode);
355                 if (validateProjectCodeResponse.isRight()) {
356                         ResponseFormat responseFormat = validateProjectCodeResponse.right().value();
357                         componentsUtils.auditComponentAdmin(responseFormat, user, component, "", "", actionEnum, component.getComponentType());
358                 }
359                 return validateProjectCodeResponse;
360
361         }
362
363         private Either<Boolean, ResponseFormat> validateProjectCode(String projectCode) {
364                 if (projectCode != null) {
365                         if (!ValidationUtils.validateProjectCode(projectCode)) {
366                                 log.info("projectCode  is not valid.");
367                                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_PROJECT_CODE);
368                                 return Either.right(errorResponse);
369                         }
370                         return Either.left(true);
371                 }
372                 return Either.left(false);
373         }
374
375         protected void checkComponentFieldsForOverrideAttempt(Component component) {
376                 if (component.getLifecycleState() != null) {
377                         log.info("LifecycleState cannot be defined by user. This field will be overridden by the application");
378                 }
379                 if (component.getVersion() != null) {
380                         log.info("Version cannot be defined by user. This field will be overridden by the application");
381                 }
382                 if ((component.getCreatorUserId() != null) || (component.getCreatorFullName() != null)) {
383                         log.info("Creator cannot be defined by user. This field will be overridden by the application");
384                 }
385                 if ((component.getLastUpdaterUserId() != null) || (component.getLastUpdaterFullName() != null)) {
386                         log.info("Last Updater cannot be defined by user. This field will be overridden by the application");
387                 }
388                 if ((component.getCreationDate() != null)) {
389                         log.info("Creation Date cannot be defined by user. This field will be overridden by the application");
390                 }
391                 if ((component.isHighestVersion() != null)) {
392                         log.info("Is Highest Version cannot be defined by user. This field will be overridden by the application");
393                 }
394                 if ((component.getUUID() != null)) {
395                         log.info("UUID cannot be defined by user. This field will be overridden by the application");
396                 }
397                 if ((component.getLastUpdateDate() != null)) {
398                         log.info("Last Update Date cannot be defined by user. This field will be overridden by the application");
399                 }
400                 if (component.getUniqueId() != null) {
401                         log.info("uid cannot be defined by user. This field will be overridden by the application.");
402                         component.setUniqueId(null);
403                 }
404                 if (component.getInvariantUUID() != null) {
405                         log.info("Invariant UUID cannot be defined by user. This field will be overridden by the application.");
406                 }
407         }
408
409         protected Either<Boolean, ResponseFormat> validateComponentFieldsBeforeCreate(User user, Component component, AuditingActionEnum actionEnum) {
410                 // validate component name uniqueness
411                 log.debug("validate component name ");
412                 Either<Boolean, ResponseFormat> componentNameValidation = validateComponentName(user, component, actionEnum);
413                 if (componentNameValidation.isRight()) {
414                         return componentNameValidation;
415                 }
416
417                 // validate description
418                 log.debug("validate description");
419                 Either<Boolean, ResponseFormat> descValidation = validateDescriptionAndCleanup(user, component, actionEnum);
420                 if (descValidation.isRight()) {
421                         return descValidation;
422                 }
423
424                 // validate tags
425                 log.debug("validate tags");
426                 Either<Boolean, ResponseFormat> tagsValidation = validateTagsListAndRemoveDuplicates(user, component, actionEnum);
427                 if (tagsValidation.isRight()) {
428                         return tagsValidation;
429                 }
430
431                 // validate contact info
432                 log.debug("validate contact info");
433                 Either<Boolean, ResponseFormat> contactIdValidation = validateContactId(user, component, actionEnum);
434                 if (contactIdValidation.isRight()) {
435                         return contactIdValidation;
436                 }
437
438                 // validate icon
439                 log.debug("validate icon");
440                 Either<Boolean, ResponseFormat> iconValidation = validateIcon(user, component, actionEnum);
441                 if (iconValidation.isRight()) {
442                         return iconValidation;
443                 }
444                 return Either.left(true);
445         }
446
447         /***
448          * Fetches Component From the DB
449          * 
450          * @param componentId
451          * @param componentTypeEnum
452          * @return
453          */
454         public <R extends Component> Either<R, StorageOperationStatus> getComponent(String componentId, ComponentTypeEnum componentTypeEnum) {
455                 ComponentOperation componentOperation = getComponentOperation(componentTypeEnum);
456                 Either<R, StorageOperationStatus> eitherComponent = componentOperation.getComponent(componentId, false);
457                 return eitherComponent;
458         }
459
460         public Either<CapReqDef, ResponseFormat> getRequirementsAndCapabilities(String componentId, ComponentTypeEnum componentTypeEnum, String userId) {
461
462                 Either<User, ResponseFormat> resp = validateUserExists(userId, "create Component Instance", false);
463                 if (resp.isRight()) {
464                         return Either.right(resp.right().value());
465                 }
466
467                 Map<String, List<CapabilityDefinition>> capabilities = new HashMap<>();
468                 Map<String, List<RequirementDefinition>> requirements = new HashMap<>();
469                 Either<CapReqDef, ResponseFormat> eitherRet;
470                 ComponentOperation componentOperation = getComponentOperation(componentTypeEnum);
471                 Either<Component, ResponseFormat> eitherComponent = validateComponentExists(componentId, componentTypeEnum, false, true);
472                 if (eitherComponent.isLeft()) {
473                         Either<Map<String, List<CapabilityDefinition>>, TitanOperationStatus> eitherCapabilities = componentOperation.getCapabilities(eitherComponent.left().value(), componentTypeEnum.getNodeType(), false);
474                         if (eitherCapabilities.isRight()) {
475                                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
476                                 eitherRet = Either.right(errorResponse);
477                         } else {
478                                 Either<Map<String, List<RequirementDefinition>>, TitanOperationStatus> eitherRequirements = componentOperation.getRequirements(eitherComponent.left().value(), componentTypeEnum.getNodeType(), false);
479                                 if (eitherRequirements.isRight()) {
480                                         ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
481                                         eitherRet = Either.right(errorResponse);
482                                 } else {
483                                         requirements = eitherRequirements.left().value();
484                                         capabilities = eitherCapabilities.left().value();
485                                         eitherRet = Either.left(new CapReqDef(requirements, capabilities));
486                                 }
487                         }
488                 } else {
489                         BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeResourceMissingError, "getRequirementsAndCapabilities", componentId);
490                         BeEcompErrorManager.getInstance().logBeComponentMissingError("getRequirementsAndCapabilities", componentTypeEnum.getValue(), componentId);
491                         eitherRet = Either.right(eitherComponent.right().value());
492                 }
493
494                 return eitherRet;
495         }
496
497         public Either<List<Component>, ResponseFormat> getLatestVersionNotAbstractComponents(boolean isAbstractAbstract, HighestFilterEnum highestFilter, ComponentTypeEnum componentTypeEnum, String internalComponentType, List<String> componentUids,
498                         String userId) {
499
500                 long startUser = System.currentTimeMillis();
501                 Either<User, ResponseFormat> resp = validateUserExists(userId, "get Latest Version Not Abstract Components", false);
502                 long endUser = System.currentTimeMillis();
503                 log.debug("Activation time of get user {} ms", (endUser - startUser));
504                 ResponseFormat responseFormat;
505                 if (resp.isLeft()) {
506
507                         List<Component> result = new ArrayList<Component>();
508                         Set<String> nonProcessesComponents = new HashSet<>();
509                         nonProcessesComponents.addAll(componentUids);
510
511                         long startGetComp = System.currentTimeMillis();
512                         // Read components from cache
513                         Set<String> filteredComponents = new HashSet<>();
514                         filteredComponents.addAll(componentUids);
515
516                         Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> allPartialComponents = componentCache.getComponentsForLeftPanel(componentTypeEnum, internalComponentType, filteredComponents);
517
518                         if (allPartialComponents.isRight()) {
519                                 log.debug("Components was not fetched from cache. Status is {}", allPartialComponents.right().value());
520                         } else {
521                                 ImmutableTriple<List<Component>, List<Component>, Set<String>> immutableTriple = allPartialComponents.left().value();
522                                 List<Component> processedComponents = immutableTriple.left;
523                                 if (processedComponents != null) {
524                                         result.addAll(processedComponents);
525                                 }
526                                 List<Component> dirtyComponents = immutableTriple.middle;
527                                 if (dirtyComponents != null) {
528                                         result.addAll(dirtyComponents);
529                                 }
530
531                                 Set<String> nonProcessesComponentsFromCache = immutableTriple.right;
532                                 nonProcessesComponents = nonProcessesComponentsFromCache;
533                         }
534                         long endGetComp = System.currentTimeMillis();
535                         log.debug("Activation time of get Comp from cache {} ms", (endGetComp - startGetComp));
536
537                         // Fecth non cached components
538                         List<String> componentsUidToFetch = new ArrayList<String>();
539                         componentsUidToFetch.addAll(nonProcessesComponents);
540
541                         long startGetCompFromGraph = System.currentTimeMillis();
542                         if (componentsUidToFetch.size() > 0) {
543                                 log.debug("Number of Components to fetch from graph is {}", componentsUidToFetch.size());
544                                 ComponentOperation componentOperation = getComponentOperation(componentTypeEnum);
545                                 Boolean isHighest = isHighest(highestFilter);
546                                 Either<List<Component>, StorageOperationStatus> nonCheckoutCompResponse = componentOperation.getLatestVersionNotAbstractComponents(isAbstractAbstract, isHighest, componentTypeEnum, internalComponentType, componentsUidToFetch);
547
548                                 if (nonCheckoutCompResponse.isLeft()) {
549                                         log.debug("Retrived Resource successfully.");
550                                         result.addAll(nonCheckoutCompResponse.left().value());
551                                 } else {
552                                         responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nonCheckoutCompResponse.right().value()));
553                                 }
554                         }
555                         long endGetCompFromGraph = System.currentTimeMillis();
556                         log.debug("Activation time of get Comp from graph {} ms", (endGetCompFromGraph - startGetCompFromGraph));
557
558                         return Either.left(result);
559                 } else {
560                         responseFormat = resp.right().value();
561                 }
562
563                 return Either.right(responseFormat);
564         }
565
566         private Boolean isHighest(HighestFilterEnum highestFilter) {
567                 Boolean isHighest = null;
568                 switch (highestFilter) {
569                 case ALL:
570                         break;
571                 case HIGHEST_ONLY:
572                         isHighest = true;
573                         break;
574                 case NON_HIGHEST_ONLY:
575                         isHighest = false;
576                         break;
577                 default:
578                         break;
579                 }
580                 return isHighest;
581         }
582
583         public Either<List<Map<String, String>>, ResponseFormat> getLatestVersionNotAbstractComponentsUidOnly(boolean isAbstractAbstract, HighestFilterEnum highestFilter, ComponentTypeEnum componentTypeEnum, String internalComponentType, String userId) {
584                 Either<User, ResponseFormat> resp = validateUserExists(userId, "get Latest Version Not Abstract Components", false);
585                 ResponseFormat responseFormat;
586                 if (resp.isLeft()) {
587
588                         ComponentOperation componentOperation = getComponentOperation(componentTypeEnum);
589                         Boolean isHighest = isHighest(highestFilter);
590                         Either<Collection<ComponentMetadataData>, StorageOperationStatus> nonCheckoutCompResponse = componentOperation.getLatestVersionNotAbstractComponentsMetadataOnly(isAbstractAbstract, isHighest, componentTypeEnum, internalComponentType);
591
592                         if (nonCheckoutCompResponse.isLeft()) {
593                                 log.debug("Retrived Resource successfully.");
594                                 List<Map<String, String>> res = new ArrayList<>();
595
596                                 // Map<String,String>resMap =
597                                 // nonCheckoutCompResponse.left().value().stream().collect()
598                                 // .collect(Collectors.toMap(
599                                 // p -> p.getMetadataDataDefinition().getUniqueId(),
600                                 // p-> p.getMetadataDataDefinition().getVersion()));
601
602                                 res = nonCheckoutCompResponse.left().value().stream().map(p -> {
603                                         HashMap<String, String> map = new HashMap<>();
604                                         map.put("uid", p.getMetadataDataDefinition().getUniqueId());
605                                         map.put("version", p.getMetadataDataDefinition().getVersion());
606                                         Long lastUpdateDate = p.getMetadataDataDefinition().getLastUpdateDate();
607                                         String lastUpdateDateStr = lastUpdateDate != null ? String.valueOf(lastUpdateDate.longValue()) : "0";
608                                         map.put("timestamp", lastUpdateDateStr);
609                                         return map;
610                                 }).collect(Collectors.toList());
611
612                                 return Either.left(res);
613                         }
614                         responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nonCheckoutCompResponse.right().value()));
615                 } else {
616                         responseFormat = resp.right().value();
617                 }
618
619                 return Either.right(responseFormat);
620         }
621
622         public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
623
624         }
625
626         public void setToscaArtifactsPlaceHolders(Component component, User user) {
627                 Map<String, ArtifactDefinition> artifactMap = component.getToscaArtifacts();
628                 if (artifactMap == null) {
629                         artifactMap = new HashMap<String, ArtifactDefinition>();
630                 }
631                 String componentUniqueId = component.getUniqueId();
632                 String componentSystemName = component.getSystemName();
633                 String componentType = component.getComponentType().getValue().toLowerCase();
634                 Map<String, Object> toscaArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getToscaArtifacts();
635
636                 if (toscaArtifacts != null) {
637                         for (Entry<String, Object> artifactInfoMap : toscaArtifacts.entrySet()) {
638                                 Map<String, Object> artifactInfo = (Map<String, Object>) artifactInfoMap.getValue();
639                                 ArtifactDefinition artifactDefinition = artifactsBusinessLogic.createArtifactPlaceHolderInfo(componentUniqueId, artifactInfoMap.getKey(), artifactInfo, user, ArtifactGroupTypeEnum.TOSCA);
640                                 artifactDefinition.setArtifactName(componentType + "-" + componentSystemName + artifactInfo.get("artifactName"));
641                                 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
642                         }
643                 }
644                 component.setToscaArtifacts(artifactMap);
645         }
646
647         public Either<Either<ArtifactDefinition, Operation>, ResponseFormat> populateToscaArtifacts(Component component, User user, boolean isInCertificationRequest, boolean inTransaction, boolean shouldLock) {
648                 Either<Either<ArtifactDefinition, Operation>, ResponseFormat> generateToscaRes = null;
649                 if (component.getToscaArtifacts() != null && !component.getToscaArtifacts().isEmpty()) {
650                         ArtifactDefinition toscaArtifact = component.getToscaArtifacts().values().stream().filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.TOSCA_TEMPLATE.getType())).findAny().get();
651                         generateToscaRes = saveToscaArtifactPayload(toscaArtifact, component, user, isInCertificationRequest, shouldLock, inTransaction, true);
652                         if (generateToscaRes.isRight()) {
653                                 return generateToscaRes;
654                         }
655                         toscaArtifact = component.getToscaArtifacts().values().stream().filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.TOSCA_CSAR.getType())).findAny().get();
656                         generateToscaRes = saveToscaArtifactPayload(toscaArtifact, component, user, isInCertificationRequest, shouldLock, inTransaction, true);
657                 }
658                 // TODO if csar artifact fails delete template artifact
659                 return generateToscaRes;
660         }
661
662         public Either<Either<ArtifactDefinition, Operation>, ResponseFormat> saveToscaArtifactPayload(ArtifactDefinition artifactDefinition, org.openecomp.sdc.be.model.Component component, User user, boolean isInCertificationRequest, boolean shouldLock,
663                         boolean inTransaction, boolean fetchTemplatesFromDB) {
664                 return artifactsBusinessLogic.generateAndSaveToscaArtifact(artifactDefinition, component, user, isInCertificationRequest, shouldLock, inTransaction, fetchTemplatesFromDB);
665         }
666
667         public Either<ImmutablePair<String, byte[]>, ResponseFormat> getToscaModelByComponentUuid(ComponentTypeEnum componentType, String uuid, EnumMap<AuditingFieldsKeysEnum, Object> additionalParam) {
668                 // get info
669                 ComponentOperation componentOperation = getComponentOperation(componentType);
670                 Either<Component, StorageOperationStatus> latestVersion = componentOperation.getLatestComponentByUuid(componentType.getNodeType(), uuid);
671                 if (latestVersion.isRight()) {
672                         ResponseFormat response = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(latestVersion.right().value(), componentType));
673                         return Either.right(response);
674
675                 }
676                 Component component = latestVersion.left().value();
677                 additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, component.getName());
678                 // TODO remove after migration - handle artifact not found(no
679                 // placeholder)
680                 if (null == component.getToscaArtifacts() || component.getToscaArtifacts().isEmpty()) {
681                         return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, ArtifactTypeEnum.TOSCA_CSAR.name()));
682                 }
683                 ArtifactDefinition csarArtifact = component.getToscaArtifacts().values().stream().filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.TOSCA_CSAR.getType())).findAny().get();
684                 return artifactsBusinessLogic.handleDownloadToscaModelRequest(component, csarArtifact, true, false);
685         }
686
687         protected StorageOperationStatus markComponentToDelete(Component component) {
688
689                 ComponentTypeEnum componentType = component.getComponentType();
690                 String uniqueId = component.getUniqueId();
691                 if ((component.getIsDeleted() != null) && (component.getIsDeleted() == true)) {
692                         log.info("component {} already marked as deleted. id= {}, type={}", component.getName(), uniqueId, componentType);
693                         return StorageOperationStatus.NOT_FOUND;
694                 }
695
696                 ComponentOperation componentOperation = getComponentOperation(componentType);
697
698                 Either<Component, StorageOperationStatus> markResourceToDelete = componentOperation.markComponentToDelete(component, true);
699                 if (markResourceToDelete.isRight()) {
700                         StorageOperationStatus result = markResourceToDelete.right().value();
701                         log.debug("failed to mark component {} of type {} for delete. error = {}", uniqueId, componentType, result);
702                         return result;
703                 } else {
704                         log.debug("Component {}  of type {} was marked as deleted", uniqueId, componentType);
705                         return StorageOperationStatus.OK;
706                 }
707         }
708
709         public Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Component currentComponent, Component updatedComponent, AuditingActionEnum audatingAction) {
710                 String descriptionUpdated = updatedComponent.getDescription();
711                 String descriptionCurrent = currentComponent.getDescription();
712                 if (descriptionUpdated != null && !descriptionCurrent.equals(descriptionUpdated)) {
713                         Either<Boolean, ResponseFormat> validateDescriptionResponse = validateDescriptionAndCleanup(user, updatedComponent, audatingAction);
714                         if (validateDescriptionResponse.isRight()) {
715                                 ResponseFormat errorRespons = validateDescriptionResponse.right().value();
716                                 return Either.right(errorRespons);
717                         }
718                         currentComponent.setDescription(updatedComponent.getDescription());
719                 }
720                 return Either.left(true);
721         }
722
723         public Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Component currentComponent, Component updatedComponent) {
724                 String projectCodeUpdated = updatedComponent.getProjectCode();
725                 String projectCodeCurrent = currentComponent.getProjectCode();
726                 if (projectCodeUpdated != null && !projectCodeCurrent.equals(projectCodeUpdated)) {
727                         Either<Boolean, ResponseFormat> validatProjectCodeResponse = validateProjectCode(user, updatedComponent, null);
728                         if (validatProjectCodeResponse.isRight()) {
729                                 ResponseFormat errorRespons = validatProjectCodeResponse.right().value();
730                                 return Either.right(errorRespons);
731                         }
732                         currentComponent.setProjectCode(updatedComponent.getProjectCode());
733                 }
734                 return Either.left(true);
735         }
736
737         public Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Component currentComponent, Component updatedComponent, boolean hasBeenCertified) {
738                 String iconUpdated = updatedComponent.getIcon();
739                 String iconCurrent = currentComponent.getIcon();
740                 if (iconUpdated != null && !iconCurrent.equals(iconUpdated)) {
741                         if (!hasBeenCertified) {
742                                 Either<Boolean, ResponseFormat> validatIconResponse = validateIcon(user, updatedComponent, null);
743                                 if (validatIconResponse.isRight()) {
744                                         ResponseFormat errorRespons = validatIconResponse.right().value();
745                                         return Either.right(errorRespons);
746                                 }
747                                 currentComponent.setIcon(updatedComponent.getIcon());
748                         } else {
749                                 log.info("icon {} cannot be updated once the component has been certified once.", iconUpdated);
750                                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_PARAMETER_CANNOT_BE_CHANGED, "Icon", currentComponent.getComponentType().name().toLowerCase());
751                                 return Either.right(errorResponse);
752                         }
753                 }
754                 return Either.left(true);
755         }
756
757         protected Either<List<String>, ResponseFormat> deleteMarkedComponents(ComponentTypeEnum componentType) {
758
759                 List<String> deletedComponents = new ArrayList<String>();
760                 log.trace("start deleteMarkedComponents");
761                 ComponentOperation componentOperation = getComponentOperation(componentType);
762                 Either<List<String>, StorageOperationStatus> resourcesToDelete = componentOperation.getAllComponentsMarkedForDeletion();
763                 if (resourcesToDelete.isRight()) {
764                         ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resourcesToDelete.right().value(), componentType));
765                         return Either.right(responseFormat);
766                 }
767
768                 for (String resourceToDelete : resourcesToDelete.left().value()) {
769
770                         Either<String, ResponseFormat> deleteMarkedResource = deleteMarkedComponent(resourceToDelete, componentType);
771                         if (deleteMarkedResource.isLeft()) {
772                                 deletedComponents.add(deleteMarkedResource.left().value());
773                         }
774                 }
775
776                 log.trace("end deleteMarkedComponents");
777                 return Either.left(deletedComponents);
778         }
779
780         private Either<String, ResponseFormat> deleteMarkedComponent(String componentToDelete, ComponentTypeEnum componentType) {
781
782                 Either<String, ResponseFormat> result = null;
783                 ComponentOperation componentOperation = getComponentOperation(componentType);
784                 NodeTypeEnum compNodeType = componentType.getNodeType();
785                 StorageOperationStatus lockResult = graphLockOperation.lockComponent(componentToDelete, compNodeType);
786                 if (!lockResult.equals(StorageOperationStatus.OK)) {
787                         BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedLockObjectError, "Delete marked component");
788                         log.debug("Failed to lock component {}. error - {}", componentToDelete, lockResult);
789                         result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
790                         return result;
791                 }
792                 try {
793
794                         // check if resource has relations
795                         Either<Boolean, StorageOperationStatus> isResourceInUse = componentOperation.isComponentInUse(componentToDelete);
796                         if (isResourceInUse.isRight()) {
797                                 log.info("deleteMarkedResource - failed to find relations to resource. id = {}, type = {}, error = {}", componentToDelete, componentType, isResourceInUse.right().value().name());
798                                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
799                                 result = Either.right(responseFormat);
800                                 return result;
801                         }
802
803                         if (isResourceInUse.isLeft() && isResourceInUse.left().value() == false) {
804
805                                 // delete resource and its artifacts in one transaction
806                                 Either<List<ArtifactDefinition>, StorageOperationStatus> artifactsRes = componentOperation.getComponentArtifactsForDelete(componentToDelete, compNodeType, true);
807                                 if (artifactsRes.isRight() && !artifactsRes.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
808                                         log.info("failed to check artifacts for component node. id = {}, type = {}, error = {}", componentToDelete, componentType, artifactsRes.right().value().name());
809                                         ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
810                                         result = Either.right(responseFormat);
811                                         return result;
812                                 }
813                                 List<ArtifactDefinition> artifactsToDelete = new ArrayList<>();
814                                 if (artifactsRes.isLeft()) {
815                                         artifactsToDelete = artifactsRes.left().value();
816                                 }
817
818                                 Either<Component, StorageOperationStatus> deleteComponentRes = componentOperation.deleteComponent(componentToDelete, true);
819                                 if (deleteComponentRes.isRight()) {
820                                         log.info("failed to delete component. id = {}, type = {}, error = {}", componentToDelete, componentType, deleteComponentRes.right().value().name());
821                                         ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(deleteComponentRes.right().value());
822                                         ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus, componentToDelete);
823                                         result = Either.right(responseFormat);
824                                 } else {
825                                         log.trace("component was deleted, id = {}, type = {}", componentToDelete, componentType);
826                                         // delete related artifacts
827                                         StorageOperationStatus deleteFromEsRes = artifactsBusinessLogic.deleteAllComponentArtifactsIfNotOnGraph(artifactsToDelete);
828                                         if (!deleteFromEsRes.equals(StorageOperationStatus.OK)) {
829                                                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(deleteFromEsRes);
830                                                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus, componentToDelete);
831                                                 result = Either.right(responseFormat);
832                                                 return result;
833                                         }
834                                         log.debug("component and all its artifacts were deleted, id = {}, type = {}", componentToDelete, componentType);
835                                         result = Either.left(componentToDelete);
836                                 }
837                         } else {
838                                 // resource in use
839                                 log.debug("componentis marked for delete but still in use, id = {}, type = {}", componentToDelete, componentType);
840                                 ActionStatus actionStatus = ActionStatus.RESTRICTED_OPERATION;
841                                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus, componentToDelete);
842                                 result = Either.right(responseFormat);
843                                 return result;
844                         }
845                 } finally {
846                         if (result == null || result.isRight()) {
847                                 BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "delete marked component");
848                                 log.debug("operation failed. do rollback");
849                                 titanGenericDao.rollback();
850                         } else {
851                                 log.debug("operation success. do commit");
852                                 titanGenericDao.commit();
853                         }
854                         graphLockOperation.unlockComponent(componentToDelete, compNodeType);
855                 }
856
857                 return result;
858         }
859
860 }