Merge "Change healing manager logic"
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / ServiceBusinessLogic.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.nio.charset.StandardCharsets;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Collection;
27 import java.util.Collections;
28 import java.util.EnumMap;
29 import java.util.HashMap;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Optional;
33 import java.util.Set;
34 import java.util.concurrent.Callable;
35 import java.util.function.Function;
36 import java.util.stream.Collectors;
37
38 import javax.servlet.ServletContext;
39 import javax.servlet.http.HttpServletRequest;
40
41 import org.apache.commons.collections.CollectionUtils;
42 import org.apache.commons.collections.MapUtils;
43 import org.apache.commons.lang3.tuple.ImmutablePair;
44 import org.openecomp.sdc.be.components.distribution.engine.IDistributionEngine;
45 import org.openecomp.sdc.be.components.distribution.engine.INotificationData;
46 import org.openecomp.sdc.be.components.distribution.engine.VfModuleArtifactPayload;
47 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction;
48 import org.openecomp.sdc.be.config.BeEcompErrorManager;
49 import org.openecomp.sdc.be.config.ConfigurationManager;
50 import org.openecomp.sdc.be.dao.api.ActionStatus;
51 import org.openecomp.sdc.be.dao.cassandra.AuditCassandraDao;
52 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
53 import org.openecomp.sdc.be.datamodel.utils.UiComponentDataConverter;
54 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
55 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
56 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
57 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
58 import org.openecomp.sdc.be.model.ArtifactDefinition;
59 import org.openecomp.sdc.be.model.Component;
60 import org.openecomp.sdc.be.model.ComponentInstance;
61 import org.openecomp.sdc.be.model.ComponentParametersView;
62 import org.openecomp.sdc.be.model.DistributionStatusEnum;
63 import org.openecomp.sdc.be.model.DistributionTransitionEnum;
64 import org.openecomp.sdc.be.model.GroupInstance;
65 import org.openecomp.sdc.be.model.GroupInstanceProperty;
66 import org.openecomp.sdc.be.model.LifecycleStateEnum;
67 import org.openecomp.sdc.be.model.Resource;
68 import org.openecomp.sdc.be.model.Service;
69 import org.openecomp.sdc.be.model.User;
70 import org.openecomp.sdc.be.model.category.CategoryDefinition;
71 import org.openecomp.sdc.be.model.operations.api.ICacheMangerOperation;
72 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
73 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
74 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
75 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
76 import org.openecomp.sdc.be.resources.data.ComponentInstanceData;
77 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
78 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
79 import org.openecomp.sdc.be.resources.data.auditing.AuditingGenericEvent;
80 import org.openecomp.sdc.be.resources.data.auditing.DistributionDeployEvent;
81 import org.openecomp.sdc.be.resources.data.auditing.DistributionNotificationEvent;
82 import org.openecomp.sdc.be.resources.data.auditing.ResourceAdminEvent;
83 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
84 import org.openecomp.sdc.be.user.Role;
85 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
86 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
87 import org.openecomp.sdc.common.api.Constants;
88 import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum;
89 import org.openecomp.sdc.common.datastructure.Wrapper;
90 import org.openecomp.sdc.common.kpi.api.ASDCKpiApi;
91 import org.openecomp.sdc.common.util.GeneralUtility;
92 import org.openecomp.sdc.common.util.ThreadLocalsHolder;
93 import org.openecomp.sdc.common.util.ValidationUtils;
94 import org.openecomp.sdc.exception.ResponseFormat;
95 import org.slf4j.Logger;
96 import org.slf4j.LoggerFactory;
97 import org.springframework.beans.factory.annotation.Autowired;
98 import org.springframework.web.context.WebApplicationContext;
99
100 import com.google.gson.Gson;
101 import com.google.gson.GsonBuilder;
102
103 import fj.data.Either;
104
105 @org.springframework.stereotype.Component("serviceBusinessLogic")
106 public class ServiceBusinessLogic extends ComponentBusinessLogic {
107
108         private static final String STATUS_SUCCESS_200 = "200";
109
110         private static final String STATUS_DEPLOYED = "DEPLOYED";
111
112         @Autowired
113         private IElementOperation elementDao;
114
115         @Autowired
116         private IDistributionEngine distributionEngine;
117
118         // @Autowired
119         // private AuditingDao auditingDao;
120
121         @Autowired
122         private AuditCassandraDao auditCassandraDao;
123
124         @Autowired
125         private ServiceComponentInstanceBusinessLogic serviceComponentInstanceBusinessLogic;
126
127         @Autowired
128         private GroupBusinessLogic groupBusinessLogic;
129
130         @Autowired
131         private ICacheMangerOperation cacheManagerOperation;
132
133         private static Logger log = LoggerFactory.getLogger(ServiceBusinessLogic.class.getName());
134         private static final String INITIAL_VERSION = "0.1";
135
136         public ServiceBusinessLogic() {
137                 log.debug("ServiceBusinessLogic started");
138         }
139
140         public Either<Service, ResponseFormat> changeServiceDistributionState(String serviceId, String state, LifecycleChangeInfoWithAction commentObj, User user) {
141
142                 Either<User, ResponseFormat> resp = validateUserExists(user.getUserId(), "change Service Distribution State", false);
143                 if (resp.isRight()) {
144                         return Either.right(resp.right().value());
145                 }
146
147                 log.debug("check request state");
148                 Either<DistributionTransitionEnum, ResponseFormat> validateEnum = validateTransitionEnum(state, user);
149                 if (validateEnum.isRight()) {
150                         return Either.right(validateEnum.right().value());
151                 }
152                 DistributionTransitionEnum distributionTransition = validateEnum.left().value();
153                 AuditingActionEnum auditAction = (distributionTransition == DistributionTransitionEnum.APPROVE ? AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_APPROV : AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REJECT);
154                 Either<String, ResponseFormat> commentResponse = validateComment(commentObj, user, auditAction);
155                 if (commentResponse.isRight()) {
156                         return Either.right(commentResponse.right().value());
157                 }
158                 String comment = commentResponse.left().value();
159
160                 Either<Service, ResponseFormat> validateService = validateServiceDistributionChange(user, serviceId, auditAction, comment);
161                 if (validateService.isRight()) {
162                         return Either.right(validateService.right().value());
163                 }
164                 Service service = validateService.left().value();
165                 DistributionStatusEnum initState = service.getDistributionStatus();
166
167                 Either<User, ResponseFormat> validateUser = validateUserDistributionChange(user, service, auditAction, comment);
168                 if (validateUser.isRight()) {
169                         return Either.right(validateUser.right().value());
170                 }
171                 user = validateUser.left().value();
172
173                 // lock resource
174                 /*
175                  * StorageOperationStatus lockResult = graphLockOperation.lockComponent(serviceId, NodeTypeEnum.Service); if (!lockResult.equals(StorageOperationStatus.OK)) { BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.
176                  * BeFailedLockObjectError, "ChangeServiceDistributionState"); log.debug("Failed to lock service {} error - {}", serviceId, lockResult); ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR,
177                  * service.getVersion(), service.getServiceName());
178                  * 
179                  * createAudit(user, auditAction, comment, service, responseFormat); return Either.right(componentsUtils.getResponseFormat(ActionStatus. GENERAL_ERROR)); }
180                  */
181                 Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, service, "ChangeServiceDistributionState");
182                 if (lockResult.isRight()) {
183                         ResponseFormat responseFormat = lockResult.right().value();
184                         createAudit(user, auditAction, comment, service, responseFormat);
185                         return Either.right(responseFormat);
186                 }
187
188                 try {
189
190                         DistributionStatusEnum newState;
191                         if (distributionTransition == DistributionTransitionEnum.APPROVE) {
192                                 newState = DistributionStatusEnum.DISTRIBUTION_APPROVED;
193                         } else {
194                                 newState = DistributionStatusEnum.DISTRIBUTION_REJECTED;
195                         }
196                         Either<Service, StorageOperationStatus> result = toscaOperationFacade.updateDistributionStatus(service, user, newState);
197                         if (result.isRight()) {
198                                 titanDao.rollback();
199                                 BeEcompErrorManager.getInstance().logBeSystemError("ChangeServiceDistributionState");
200                                 log.debug("service {} is  change destribuation status failed", service.getUniqueId());
201                                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR, service.getVersion(), service.getName());
202                                 createAudit(user, auditAction, comment, service, responseFormat);
203                                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
204                         }
205                         titanDao.commit();
206                         Service updatedService = result.left().value();
207                         ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
208                         EnumMap<AuditingFieldsKeysEnum, Object> auditingFields = new EnumMap<AuditingFieldsKeysEnum, Object>(AuditingFieldsKeysEnum.class);
209                         auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_DCURR_STATUS, updatedService.getDistributionStatus().name());
210                         auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_DPREV_STATUS, initState.name());
211                         createAudit(user, auditAction, comment, updatedService, responseFormat, auditingFields);
212                         return Either.left(result.left().value());
213
214                 } finally {
215                         graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
216                 }
217
218         }
219
220         public Either<List<Map<String, Object>>, ResponseFormat> getComponentAuditRecords(String componentVersion, String componentUUID, String userId) {
221                 Either<User, ResponseFormat> resp = validateUserExists(userId, "get Component Audit Records", false);
222                 if (resp.isRight()) {
223                         return Either.right(resp.right().value());
224                 }
225                 Either<List<Map<String, Object>>, ActionStatus> result;
226                 try {
227
228                         // Certified Version
229                         if (componentVersion.endsWith(".0")) {
230                                 Either<List<ResourceAdminEvent>, ActionStatus> eitherAuditingForCertified = auditCassandraDao.getByServiceInstanceId(componentUUID);
231                                 if (eitherAuditingForCertified.isLeft()) {
232                                         result = Either.left(getAuditingFieldsList(eitherAuditingForCertified.left().value()));
233                                 } else {
234                                         result = Either.right(eitherAuditingForCertified.right().value());
235                                 }
236                         }
237                         // Uncertified Version
238                         else {
239                                 result = getAuditRecordsForUncertifiedComponent(componentUUID, componentVersion);
240                         }
241                 } catch (Exception e) {
242                         log.debug("get Audit Records failed with exception {}", e);
243                         result = Either.right(ActionStatus.GENERAL_ERROR);
244                 }
245
246                 if (result.isRight()) {
247                         return Either.right(componentsUtils.getResponseFormat(result.right().value()));
248                 } else {
249                         return Either.left(result.left().value());
250                 }
251
252         }
253
254         private Either<List<Map<String, Object>>, ActionStatus> getAuditRecordsForUncertifiedComponent(String componentUUID, String componentVersion) {
255                 // First Query
256                 Either<List<ResourceAdminEvent>, ActionStatus> eitherprevVerAudit = auditCassandraDao.getAuditByServiceIdAndPrevVersion(componentUUID, componentVersion);
257
258                 if (eitherprevVerAudit.isRight()) {
259                         return Either.right(eitherprevVerAudit.right().value());
260                 }
261
262                 // Second Query
263                 Either<List<ResourceAdminEvent>, ActionStatus> eitherCurrVerAudit = auditCassandraDao.getAuditByServiceIdAndCurrVersion(componentUUID, componentVersion);
264                 if (eitherCurrVerAudit.isRight()) {
265                         return Either.right(eitherCurrVerAudit.right().value());
266                 }
267
268                 List<Map<String, Object>> prevVerAuditList = getAuditingFieldsList(eitherprevVerAudit.left().value());
269                 List<Map<String, Object>> currVerAuditList = getAuditingFieldsList(eitherCurrVerAudit.left().value());
270
271                 List<Map<String, Object>> duplicateElements = new ArrayList<Map<String, Object>>();
272                 duplicateElements.addAll(prevVerAuditList);
273                 duplicateElements.retainAll(currVerAuditList);
274
275                 List<Map<String, Object>> joinedNonDuplicatedList = new ArrayList<Map<String, Object>>();
276                 joinedNonDuplicatedList.addAll(prevVerAuditList);
277                 joinedNonDuplicatedList.removeAll(duplicateElements);
278                 joinedNonDuplicatedList.addAll(currVerAuditList);
279
280                 return Either.left(joinedNonDuplicatedList);
281         }
282
283         private List<Map<String, Object>> getAuditingFieldsList(List<? extends AuditingGenericEvent> prevVerAuditList) {
284
285                 List<Map<String, Object>> prevVerAudit = new ArrayList<Map<String, Object>>();
286                 for (AuditingGenericEvent auditEvent : prevVerAuditList) {
287                         auditEvent.fillFields();
288                         prevVerAudit.add(auditEvent.getFields());
289                 }
290                 return prevVerAudit;
291         }
292
293         /**
294          * createService
295          * 
296          * @param service
297          *            - Service
298          * @param user
299          *            - modifier data (userId)
300          * @return Either<Service, responseFormat>
301          */
302         public Either<Service, ResponseFormat> createService(Service service, User user) {
303
304                 // get user details
305                 Either<User, ResponseFormat> eitherCreator = validateUser(user, "Create Service", service, AuditingActionEnum.CREATE_RESOURCE, false);
306                 if (eitherCreator.isRight()) {
307                         return Either.right(eitherCreator.right().value());
308                 }
309                 user = eitherCreator.left().value();
310
311                 // validate user role
312                 Either<Boolean, ResponseFormat> validateRes = validateUserRole(user, service, new ArrayList<Role>(), AuditingActionEnum.CREATE_RESOURCE, null);
313                 if (validateRes.isRight()) {
314                         return Either.right(validateRes.right().value());
315                 }
316                 service.setCreatorUserId(user.getUserId());
317
318                 // warn on overridden fields
319                 checkFieldsForOverideAttampt(service);
320                 // enrich object
321                 log.debug("enrich service with version and state");
322                 service.setState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
323                 service.setVersion(INITIAL_VERSION);
324                 service.setConformanceLevel(ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel());
325                 service.setDistributionStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED);
326
327                 Either<Service, ResponseFormat> createServiceResponse = validateServiceBeforeCreate(service, user, AuditingActionEnum.CREATE_RESOURCE);
328                 if (createServiceResponse.isRight()) {
329                         return createServiceResponse;
330                 }
331                 return createServiceByDao(service, AuditingActionEnum.CREATE_RESOURCE, user);
332         }
333
334         private void checkFieldsForOverideAttampt(Service service) {
335                 checkComponentFieldsForOverrideAttempt(service);
336                 if ((service.getDistributionStatus() != null)) {
337                         log.info("Distribution Status cannot be defined by user. This field will be overridden by the application");
338                 }
339         }
340
341         private Either<Service, ResponseFormat> createServiceByDao(Service service, AuditingActionEnum actionEnum, User user) {
342                 log.debug("send service {} to dao for create", service.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
343
344                 Either<Boolean, ResponseFormat> lockResult = lockComponentByName(service.getSystemName(), service, "Create Service");
345                 if (lockResult.isRight()) {
346                         ResponseFormat responseFormat = lockResult.right().value();
347                         componentsUtils.auditComponentAdmin(responseFormat, user, service, "", "", actionEnum, ComponentTypeEnum.SERVICE);
348                         return Either.right(responseFormat);
349                 }
350
351                 log.debug("System name locked is {}, status = {}", service.getSystemName(), lockResult);
352
353                 try {
354
355                         createMandatoryArtifactsData(service, user);
356                         createServiceApiArtifactsData(service, user);
357                         setToscaArtifactsPlaceHolders(service, user);
358                         Either<Resource, ResponseFormat> genericServiceEither = fetchAndSetDerivedFromGenericType(service);
359                         if (genericServiceEither.isRight())
360                                 return Either.right(genericServiceEither.right().value());
361
362                         generateInputsFromGenericTypeProperties(service, genericServiceEither.left().value());
363
364                         Either<Service, StorageOperationStatus> dataModelResponse = toscaOperationFacade.createToscaComponent(service);
365
366                         // service created successfully!!!
367                         if (dataModelResponse.isLeft()) {
368                                 log.debug("Service created successfully!!!");
369                                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED);
370                                 componentsUtils.auditComponentAdmin(responseFormat, user, service, "", "", actionEnum, ComponentTypeEnum.SERVICE);
371                                 ASDCKpiApi.countCreatedServicesKPI();
372                                 return Either.left(dataModelResponse.left().value());
373                         }
374
375                         ResponseFormat responseFormat = componentsUtils.getResponseFormatByComponent(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()), service, ComponentTypeEnum.SERVICE);
376                         log.debug("audit before sending response");
377                         componentsUtils.auditComponentAdmin(responseFormat, user, service, "", "", actionEnum, ComponentTypeEnum.SERVICE);
378                         return Either.right(responseFormat);
379
380                 } finally {
381                         graphLockOperation.unlockComponentByName(service.getSystemName(), service.getUniqueId(), NodeTypeEnum.Service);
382                 }
383         }
384
385         @SuppressWarnings("unchecked")
386         private void createServiceApiArtifactsData(Service service, User user) {
387                 // create mandatory artifacts
388
389                 // TODO it must be removed after that artifact uniqueId creation will be
390                 // moved to ArtifactOperation
391                 // String serviceUniqueId =
392                 // UniqueIdBuilder.buildServiceUniqueId(service.getComponentMetadataDefinition().getMetadataDataDefinition().getName(),
393                 // service.getComponentMetadataDefinition().getMetadataDataDefinition().getVersion());
394                 String serviceUniqueId = service.getUniqueId();
395                 Map<String, ArtifactDefinition> artifactMap = service.getServiceApiArtifacts();
396                 if (artifactMap == null)
397                         artifactMap = new HashMap<String, ArtifactDefinition>();
398
399                 Map<String, Object> serviceApiArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getServiceApiArtifacts();
400                 List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
401
402                 List<CategoryDefinition> categories = service.getCategories();
403                 boolean isCreateArtifact = true;
404                 if (categories != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
405                         for (String exlude : exludeServiceCategory) {
406                                 if (exlude.equalsIgnoreCase(categories.get(0).getName())) {
407                                         isCreateArtifact = false;
408                                         break;
409                                 }
410                         }
411
412                 }
413
414                 if (serviceApiArtifacts != null && isCreateArtifact) {
415                         Set<String> keys = serviceApiArtifacts.keySet();
416                         for (String serviceApiArtifactName : keys) {
417                                 Map<String, Object> artifactInfoMap = (Map<String, Object>) serviceApiArtifacts.get(serviceApiArtifactName);
418                                 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, serviceApiArtifactName, artifactInfoMap, user, true);
419                                 artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.SERVICE_API);
420                                 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
421                         }
422
423                         service.setServiceApiArtifacts(artifactMap);
424                 }
425         }
426
427         private Either<Service, ResponseFormat> validateServiceBeforeCreate(Service service, User user, AuditingActionEnum actionEnum) {
428
429                 Either<Boolean, ResponseFormat> validationResponse = validateServiceFieldsBeforeCreate(user, service, actionEnum);
430                 if (validationResponse.isRight()) {
431                         return Either.right(validationResponse.right().value());
432                 }
433                 service.setCreatorFullName(user.getFirstName() + " " + user.getLastName());
434                 service.setContactId(service.getContactId().toLowerCase());
435
436                 // Generate invariant UUID - must be here and not in operation since it
437                 // should stay constant during clone
438                 String invariantUUID = UniqueIdBuilder.buildInvariantUUID();
439                 service.setInvariantUUID(invariantUUID);
440
441                 return Either.left(service);
442         }
443
444         private Either<Boolean, ResponseFormat> validateServiceFieldsBeforeCreate(User user, Service service, AuditingActionEnum actionEnum) {
445                 Either<Boolean, ResponseFormat> componentsFieldsValidation = validateComponentFieldsBeforeCreate(user, service, actionEnum);
446                 if (componentsFieldsValidation.isRight()) {
447                         return componentsFieldsValidation;
448                 }
449
450                 log.debug("validate service name uniqueness");
451                 Either<Boolean, ResponseFormat> serviceNameUniquenessValidation = validateComponentNameUnique(user, service, actionEnum);
452                 if (serviceNameUniquenessValidation.isRight()) {
453                         return serviceNameUniquenessValidation;
454                 }
455
456                 log.debug("validate category");
457                 Either<Boolean, ResponseFormat> categoryValidation = validateServiceCategory(user, service, actionEnum);
458                 if (categoryValidation.isRight()) {
459                         return categoryValidation;
460                 }
461
462                 // validate project name (ProjectCode) - mandatory in service
463                 log.debug("validate projectName");
464                 Either<Boolean, ResponseFormat> projectCodeValidation = validateProjectCode(user, service, actionEnum);
465                 if (projectCodeValidation.isRight()) {
466                         return projectCodeValidation;
467                 }
468                 
469                 log.debug("validate service type");
470                 Either<Boolean, ResponseFormat> serviceTypeValidation = validateServiceTypeAndCleanup(user, service, actionEnum);
471                 if (serviceTypeValidation.isRight()) {
472                         return serviceTypeValidation;
473                 }
474                 
475                 log.debug("validate service role");
476                 Either<Boolean, ResponseFormat> serviceRoleValidation = validateServiceRoleAndCleanup(user, service, actionEnum);
477                 if (serviceRoleValidation.isRight()) {
478                         return serviceRoleValidation;
479                 }
480
481                 return Either.left(true);
482
483         }
484
485         private Either<Boolean, ResponseFormat> validateServiceCategory(User user, Service service, AuditingActionEnum actionEnum) {
486                 log.debug("validate Service category");
487
488                 if (service.getCategories() == null || service.getCategories().size() == 0) {
489                         ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.SERVICE.getValue());
490                         componentsUtils.auditComponentAdmin(errorResponse, user, service, "", "", actionEnum, ComponentTypeEnum.SERVICE);
491                         return Either.right(errorResponse);
492                 }
493
494                 Either<Boolean, ResponseFormat> validatCategory = validateServiceCategory(service.getCategories());
495                 if (validatCategory.isRight()) {
496                         ResponseFormat responseFormat = validatCategory.right().value();
497                         componentsUtils.auditComponentAdmin(responseFormat, user, service, "", "", actionEnum, ComponentTypeEnum.SERVICE);
498                         return Either.right(responseFormat);
499                 }
500
501                 return Either.left(true);
502         }
503
504         public Either<Map<String, Boolean>, ResponseFormat> validateServiceNameExists(String serviceName, String userId) {
505
506                 Either<User, ResponseFormat> resp = validateUserExists(userId, "validate Service Name Exists", false);
507                 if (resp.isRight()) {
508                         return Either.right(resp.right().value());
509                 }
510
511                 Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade.validateComponentNameUniqueness(serviceName, null, ComponentTypeEnum.SERVICE);
512
513                 // DE242223
514                 titanDao.commit();
515
516                 if (dataModelResponse.isLeft()) {
517                         Map<String, Boolean> result = new HashMap<>();
518                         result.put("isValid", dataModelResponse.left().value());
519                         log.debug("validation was successfully performed.");
520                         return Either.left(result);
521                 }
522
523                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()));
524
525                 return Either.right(responseFormat);
526         }
527
528         public void setElementDao(IElementOperation elementDao) {
529                 this.elementDao = elementDao;
530         }
531
532         public void setCassandraAuditingDao(AuditCassandraDao auditingDao) {
533                 this.auditCassandraDao = auditingDao;
534         }
535
536         /*
537          * public void setUserAdmin(UserAdminBuisinessLogic userAdmin) { this.userAdmin = userAdmin; }
538          * 
539          * public void setComponentsUtils(ComponentsUtils componentsUtils) { this.componentsUtils = componentsUtils; }
540          * 
541          * public void setGraphLockOperation(IGraphLockOperation graphLockOperation) { this.graphLockOperation = graphLockOperation; }
542          */
543
544         public ArtifactsBusinessLogic getArtifactBl() {
545                 return artifactsBusinessLogic;
546         }
547
548         public void setArtifactBl(ArtifactsBusinessLogic artifactBl) {
549                 this.artifactsBusinessLogic = artifactBl;
550         }
551
552         public Either<Service, ResponseFormat> updateServiceMetadata(String serviceId, Service serviceUpdate, User user) {
553                 Either<User, ResponseFormat> eitherCreator = validateUser(user, "updateServiceMetadata", serviceUpdate, null, false);
554                 if (eitherCreator.isRight()) {
555                         return Either.right(eitherCreator.right().value());
556                 }
557                 user = eitherCreator.left().value();
558
559                 // validate user role
560                 Either<Boolean, ResponseFormat> validateRes = validateUserRole(user, serviceUpdate, new ArrayList<Role>(), null, null);
561                 if (validateRes.isRight()) {
562                         return Either.right(validateRes.right().value());
563                 }
564
565                 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
566                 if (storageStatus.isRight()) {
567                         return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
568                 }
569
570                 Service currentService = storageStatus.left().value();
571
572                 if (!ComponentValidationUtils.canWorkOnComponent(currentService, user.getUserId())) {
573                         log.info("Restricted operation for user: {}, on service: {}", user.getUserId(), currentService.getCreatorUserId());
574                         return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
575                 }
576
577                 Either<Service, ResponseFormat> validationRsponse = validateAndUpdateServiceMetadata(user, currentService, serviceUpdate);
578                 if (validationRsponse.isRight()) {
579                         log.info("service update metadata: validations field.");
580                         return validationRsponse;
581                 }
582                 Service serviceToUpdate = validationRsponse.left().value();
583                 // lock resource
584
585                 Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, currentService, "Update Service Metadata");
586                 if (lockResult.isRight()) {
587                         return Either.right(lockResult.right().value());
588                 }
589                 try {
590                         Either<Service, StorageOperationStatus> updateResponse = toscaOperationFacade.updateToscaElement(serviceToUpdate);
591                         if (updateResponse.isRight()) {
592                                 titanDao.rollback();
593                                 BeEcompErrorManager.getInstance().logBeSystemError("Update Service Metadata");
594                                 log.debug("failed to update sevice {}", serviceToUpdate.getUniqueId());
595                                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
596                         }
597                         titanDao.commit();
598                         return Either.left(updateResponse.left().value());
599                 } finally {
600                         graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
601                 }
602         }
603
604         private Either<Service, ResponseFormat> validateAndUpdateServiceMetadata(User user, Service currentService, Service serviceUpdate) {
605
606                 boolean hasBeenCertified = ValidationUtils.hasBeenCertified(currentService.getVersion());
607                 Either<Boolean, ResponseFormat> response = validateAndUpdateCategory(user, currentService, serviceUpdate, hasBeenCertified, null);
608                 if (response.isRight()) {
609                         ResponseFormat errorResponse = response.right().value();
610                         return Either.right(errorResponse);
611                 }
612
613                 String creatorUserIdUpdated = serviceUpdate.getCreatorUserId();
614                 String creatorUserIdCurrent = currentService.getCreatorUserId();
615                 if (creatorUserIdUpdated != null && !creatorUserIdCurrent.equals(creatorUserIdUpdated)) {
616                         log.info("update srvice: recived request to update creatorUserId to {} the field is not updatable ignoring.", creatorUserIdUpdated);
617                 }
618
619                 String creatorFullNameUpdated = serviceUpdate.getCreatorFullName();
620                 String creatorFullNameCurrent = currentService.getCreatorFullName();
621                 if (creatorFullNameUpdated != null && !creatorFullNameCurrent.equals(creatorFullNameUpdated)) {
622                         log.info("update srvice: recived request to update creatorFullName to {} the field is not updatable ignoring.", creatorFullNameUpdated);
623                 }
624
625                 String lastUpdaterUserIdUpdated = serviceUpdate.getLastUpdaterUserId();
626                 String lastUpdaterUserIdCurrent = currentService.getLastUpdaterUserId();
627                 if (lastUpdaterUserIdUpdated != null && !lastUpdaterUserIdCurrent.equals(lastUpdaterUserIdUpdated)) {
628                         log.info("update srvice: recived request to update lastUpdaterUserId to {} the field is not updatable ignoring.", lastUpdaterUserIdUpdated);
629                 }
630
631                 String lastUpdaterFullNameUpdated = serviceUpdate.getLastUpdaterFullName();
632                 String lastUpdaterFullNameCurrent = currentService.getLastUpdaterFullName();
633                 if (lastUpdaterFullNameUpdated != null && !lastUpdaterFullNameCurrent.equals(lastUpdaterFullNameUpdated)) {
634                         log.info("update srvice: recived request to update lastUpdaterFullName to {} the field is not updatable ignoring.", lastUpdaterFullNameUpdated);
635                 }
636
637                 response = validateAndUpdateServiceName(user, currentService, serviceUpdate, hasBeenCertified, null);
638                 if (response.isRight()) {
639                         ResponseFormat errorResponse = response.right().value();
640                         return Either.right(errorResponse);
641                 }
642
643                 DistributionStatusEnum distributionStatusUpdated = serviceUpdate.getDistributionStatus();
644                 DistributionStatusEnum distributionStatusCurrent = currentService.getDistributionStatus();
645                 if (distributionStatusUpdated != null && !distributionStatusUpdated.name().equals((distributionStatusCurrent != null ? distributionStatusCurrent.name() : null))) {
646                         log.info("update srvice: recived request to update distributionStatus to {} the field is not updatable ignoring.", distributionStatusUpdated);
647                 }
648
649                 if (serviceUpdate.getProjectCode() != null) {
650                         response = validateAndUpdateProjectCode(user, currentService, serviceUpdate, null);
651                         if (response.isRight()) {
652                                 ResponseFormat errorResponse = response.right().value();
653                                 return Either.right(errorResponse);
654                         }
655                 }
656
657                 response = validateAndUpdateIcon(user, currentService, serviceUpdate, hasBeenCertified, null);
658                 if (response.isRight()) {
659                         ResponseFormat errorResponse = response.right().value();
660                         return Either.right(errorResponse);
661                 }
662
663                 Long creationDateUpdated = serviceUpdate.getCreationDate();
664                 Long creationDateCurrent = currentService.getCreationDate();
665                 if (creationDateUpdated != null && !creationDateCurrent.equals(creationDateUpdated)) {
666                         log.info("update srvice: recived request to update creationDate to {} the field is not updatable ignoring.", creationDateUpdated);
667                 }
668
669                 String versionUpdated = serviceUpdate.getVersion();
670                 String versionCurrent = currentService.getVersion();
671                 if (versionUpdated != null && !versionCurrent.equals(versionUpdated)) {
672                         log.info("update srvice: recived request to update version to {} the field is not updatable ignoring.", versionUpdated);
673                 }
674
675                 response = validateAndUpdateDescription(user, currentService, serviceUpdate, hasBeenCertified, null);
676                 if (response.isRight()) {
677                         ResponseFormat errorResponse = response.right().value();
678                         return Either.right(errorResponse);
679                 }
680
681                 response = validateAndUpdateTags(user, currentService, serviceUpdate, hasBeenCertified, null);
682                 if (response.isRight()) {
683                         ResponseFormat errorResponse = response.right().value();
684                         return Either.right(errorResponse);
685                 }
686
687                 response = validateAndUpdateContactId(user, currentService, serviceUpdate, null);
688                 if (response.isRight()) {
689                         ResponseFormat errorResponse = response.right().value();
690                         return Either.right(errorResponse);
691                 }
692
693                 Long lastUpdateDateUpdated = serviceUpdate.getLastUpdateDate();
694                 Long lastUpdateDateCurrent = currentService.getLastUpdateDate();
695                 if (lastUpdateDateUpdated != null && !lastUpdateDateCurrent.equals(lastUpdateDateUpdated)) {
696                         log.info("update srvice: recived request to update lastUpdateDate to {} the field is not updatable ignoring.", lastUpdateDateUpdated);
697                 }
698
699                 LifecycleStateEnum lifecycleStateUpdated = serviceUpdate.getLifecycleState();
700                 LifecycleStateEnum lifecycleStateCurrent = currentService.getLifecycleState();
701                 if (lifecycleStateUpdated != null && !lifecycleStateCurrent.name().equals(lifecycleStateUpdated.name())) {
702                         log.info("update srvice: recived request to update lifecycleState to {} the field is not updatable ignoring.", lifecycleStateUpdated);
703                 }
704
705                 Boolean isHighestVersionUpdated = serviceUpdate.isHighestVersion();
706                 Boolean isHighestVersionCurrent = currentService.isHighestVersion();
707                 if (isHighestVersionUpdated != null && !isHighestVersionCurrent.equals(isHighestVersionUpdated)) {
708                         log.info("update srvice: recived request to update isHighestVersion to {} the field is not updatable ignoring.", isHighestVersionUpdated);
709                 }
710
711                 String uuidUpdated = serviceUpdate.getUUID();
712                 String uuidCurrent = currentService.getUUID();
713                 if (!uuidCurrent.equals(uuidUpdated)) {
714                         log.info("update srvice: recived request to update uuid to {} the field is not updatable ignoring.", uuidUpdated);
715                 }
716                 
717                 response = validateAndUpdateServiceType(user, currentService, serviceUpdate, null);
718                 if (response.isRight()) {
719                         ResponseFormat errorResponse = response.right().value();
720                         return Either.right(errorResponse);
721                 }
722                 
723                 response = validateAndUpdateServiceRole(user, currentService, serviceUpdate, null);
724                 if (response.isRight()) {
725                         ResponseFormat errorResponse = response.right().value();
726                         return Either.right(errorResponse);
727                 }
728
729                 String currentInvariantUuid = currentService.getInvariantUUID();
730                 String updatedInvariantUuid = serviceUpdate.getInvariantUUID();
731
732                 if ((updatedInvariantUuid != null) && (!updatedInvariantUuid.equals(currentInvariantUuid))) {
733                         log.warn("Product invariant UUID is automatically set and cannot be updated");
734                         serviceUpdate.setInvariantUUID(currentInvariantUuid);
735                 }
736                 validateAndUpdateEcompNaming(currentService, serviceUpdate);
737                 
738                 return Either.left(currentService);
739
740         }
741
742         private void validateAndUpdateEcompNaming(Service currentService, Service serviceUpdate) {
743                 Boolean isEcompoGeneratedCurr = currentService.isEcompGeneratedNaming();
744                 Boolean isEcompoGeneratedUpdate = serviceUpdate.isEcompGeneratedNaming();
745                 if (isEcompoGeneratedUpdate != null && isEcompoGeneratedCurr != isEcompoGeneratedUpdate) {
746                         currentService.setEcompGeneratedNaming(isEcompoGeneratedUpdate);
747                 }
748                 String namingPolicyUpd = serviceUpdate.getNamingPolicy();
749                 if (!currentService.isEcompGeneratedNaming()) {
750                         if (ValidationUtils.validateStringNotEmpty(namingPolicyUpd)) {
751                                 log.warn("NamingPolicy must be empty for EcompGeneratedNaming=false");
752                                 currentService.setNamingPolicy("");
753                         } else {
754                                 currentService.setNamingPolicy(namingPolicyUpd);
755                         }
756                 }else{
757                         currentService.setNamingPolicy(namingPolicyUpd);
758                 }
759         }
760
761         private Either<Boolean, ResponseFormat> validateAndUpdateContactId(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
762                 String contactIdUpdated = serviceUpdate.getContactId();
763                 String contactIdCurrent = currentService.getContactId();
764                 if (!contactIdCurrent.equals(contactIdUpdated)) {
765                         Either<Boolean, ResponseFormat> validatContactId = validateContactId(user, serviceUpdate, audatingAction);
766                         if (validatContactId.isRight()) {
767                                 ResponseFormat errorRespons = validatContactId.right().value();
768                                 return Either.right(errorRespons);
769                         }
770                         currentService.setContactId(contactIdUpdated.toLowerCase());
771                 }
772                 return Either.left(true);
773         }
774
775         private Either<Boolean, ResponseFormat> validateAndUpdateTags(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
776                 List<String> tagsUpdated = serviceUpdate.getTags();
777                 List<String> tagsCurrent = currentService.getTags();
778                 if (tagsUpdated == null || tagsUpdated.isEmpty()) {
779                         ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_TAGS);
780                         componentsUtils.auditComponentAdmin(responseFormat, user, serviceUpdate, "", "", audatingAction, ComponentTypeEnum.SERVICE);
781                         return Either.right(responseFormat);
782                 }
783
784                 if (!(tagsCurrent.containsAll(tagsUpdated) && tagsUpdated.containsAll(tagsCurrent))) {
785                         Either<Boolean, ResponseFormat> validatResponse = validateTagsListAndRemoveDuplicates(user, serviceUpdate, audatingAction);
786                         if (validatResponse.isRight()) {
787                                 ResponseFormat errorRespons = validatResponse.right().value();
788                                 return Either.right(errorRespons);
789                         }
790                         currentService.setTags(tagsUpdated);
791                 }
792                 return Either.left(true);
793         }
794
795         private Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
796                 String descriptionUpdated = serviceUpdate.getDescription();
797                 String descriptionCurrent = currentService.getDescription();
798                 if (!descriptionCurrent.equals(descriptionUpdated)) {
799                         Either<Boolean, ResponseFormat> validateDescriptionResponse = validateDescriptionAndCleanup(user, serviceUpdate, audatingAction);
800                         if (validateDescriptionResponse.isRight()) {
801                                 ResponseFormat errorRespons = validateDescriptionResponse.right().value();
802                                 return Either.right(errorRespons);
803                         }
804                         currentService.setDescription(serviceUpdate.getDescription());
805                 }
806                 return Either.left(true);
807         }
808
809         private Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
810                 String projectCodeUpdated = serviceUpdate.getProjectCode();
811                 String projectCodeCurrent = currentService.getProjectCode();
812                 if (!projectCodeCurrent.equals(projectCodeUpdated)) {
813
814                         Either<Boolean, ResponseFormat> validatProjectCodeResponse = validateProjectCode(user, serviceUpdate, audatingAction);
815                         if (validatProjectCodeResponse.isRight()) {
816                                 ResponseFormat errorRespons = validatProjectCodeResponse.right().value();
817                                 return Either.right(errorRespons);
818                         }
819                         currentService.setProjectCode(projectCodeUpdated);
820
821                 }
822                 return Either.left(true);
823         }
824
825         private Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
826                 String iconUpdated = serviceUpdate.getIcon();
827                 String iconCurrent = currentService.getIcon();
828                 if (!iconCurrent.equals(iconUpdated)) {
829                         if (!hasBeenCertified) {
830                                 Either<Boolean, ResponseFormat> validatIconResponse = validateIcon(user, serviceUpdate, audatingAction);
831                                 if (validatIconResponse.isRight()) {
832                                         ResponseFormat errorRespons = validatIconResponse.right().value();
833                                         return Either.right(errorRespons);
834                                 }
835                                 currentService.setIcon(iconUpdated);
836                         } else {
837                                 log.info("icon {} cannot be updated once the service has been certified once.", iconUpdated);
838                                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ICON_CANNOT_BE_CHANGED);
839                                 return Either.right(errorResponse);
840                         }
841                 }
842                 return Either.left(true);
843         }
844
845         private Either<Boolean, ResponseFormat> validateAndUpdateServiceName(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum auditingAction) {
846                 String serviceNameUpdated = serviceUpdate.getName();
847                 String serviceNameCurrent = currentService.getName();
848                 if (!serviceNameCurrent.equals(serviceNameUpdated)) {
849                         if (!hasBeenCertified) {
850                                 Either<Boolean, ResponseFormat> validatServiceNameResponse = validateComponentName(user, serviceUpdate, auditingAction);
851                                 if (validatServiceNameResponse.isRight()) {
852                                         ResponseFormat errorRespons = validatServiceNameResponse.right().value();
853                                         return Either.right(errorRespons);
854                                 }
855
856                                 Either<Boolean, ResponseFormat> serviceNameUniquenessValidation = validateComponentNameUnique(user, serviceUpdate, auditingAction);
857                                 if (serviceNameUniquenessValidation.isRight()) {
858                                         return serviceNameUniquenessValidation;
859                                 }
860                                 currentService.setName(serviceNameUpdated);
861                                 currentService.getComponentMetadataDefinition().getMetadataDataDefinition().setNormalizedName(ValidationUtils.normaliseComponentName(serviceNameUpdated));
862                                 currentService.getComponentMetadataDefinition().getMetadataDataDefinition().setSystemName(ValidationUtils.convertToSystemName(serviceNameUpdated));
863
864                         } else {
865                                 log.info("service name {} cannot be updated once the service has been certified once.", serviceNameUpdated);
866                                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NAME_CANNOT_BE_CHANGED);
867                                 return Either.right(errorResponse);
868                         }
869                 }
870                 return Either.left(true);
871         }
872         
873         private Either<Boolean, ResponseFormat> validateAndUpdateServiceType(User user, Service currentService, Service updatedService, AuditingActionEnum auditingAction) {
874                 String updatedServiceType = updatedService.getServiceType();
875                 String currentServiceType = currentService.getServiceType();
876                 if (!currentServiceType.equals(updatedServiceType)) {
877                         Either<Boolean, ResponseFormat> validateServiceType = validateServiceTypeAndCleanup(user, updatedService , auditingAction);
878                         if (validateServiceType.isRight()) {
879                                 ResponseFormat errorResponse = validateServiceType.right().value();
880                                 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, "", "", auditingAction, ComponentTypeEnum.SERVICE);
881                                 return Either.right(errorResponse);
882                         }
883                         currentService.setServiceType(updatedServiceType);
884                 }
885                 return Either.left(true);
886         }
887
888         protected Either<Boolean, ResponseFormat> validateServiceTypeAndCleanup(User user, Component component, AuditingActionEnum actionEnum) {
889                 String serviceType = ((Service)component).getServiceType();
890                 if (serviceType != null){
891                         serviceType = cleanUpText(serviceType);
892                         Either<Boolean, ResponseFormat> validateServiceType = validateServiceType(serviceType);
893                         if (validateServiceType.isRight()) {
894                                 ResponseFormat responseFormat = validateServiceType.right().value();
895                                 componentsUtils.auditComponentAdmin(responseFormat, user, component, "", "", actionEnum, ComponentTypeEnum.SERVICE);
896                                 return Either.right(responseFormat);
897                         }
898                         return Either.left(true);
899                 } else {
900                         return Either.left(false);
901                 }
902         }
903
904         
905         private Either<Boolean, ResponseFormat> validateServiceType(String serviceType) {
906                 if (serviceType.equals("")){
907                         return Either.left(true);
908                 } else {
909                         if (!ValidationUtils.validateServiceTypeLength(serviceType)) {
910                                 log.info("service type exceeds limit.");
911                                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_TYPE_EXCEEDS_LIMIT, "" + ValidationUtils.SERVICE_TYPE_MAX_LENGTH);
912                                 return Either.right(errorResponse);
913                         }
914
915                         if (!ValidationUtils.validateIsEnglish(serviceType)) {
916                                 log.info("service type is not valid.");
917                                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_SERVICE_TYPE);
918                                 return Either.right(errorResponse);
919                         }
920                         return Either.left(true);
921                 }
922         }
923         
924         private Either<Boolean, ResponseFormat> validateAndUpdateServiceRole(User user, Service currentService, Service updatedService, AuditingActionEnum auditingAction) {
925                 String updatedServiceRole = updatedService.getServiceRole();
926                 String currentServiceRole = currentService.getServiceRole();
927                 if (!currentServiceRole.equals(updatedServiceRole)) {
928                         Either<Boolean, ResponseFormat> validateServiceRole = validateServiceRoleAndCleanup(user, updatedService , auditingAction);
929                         if (validateServiceRole.isRight()) {
930                                 ResponseFormat errorResponse = validateServiceRole.right().value();
931                                 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, "", "", auditingAction, ComponentTypeEnum.SERVICE);
932                                 return Either.right(errorResponse);
933                         }
934                         currentService.setServiceRole(updatedServiceRole);
935                 }
936                 return Either.left(true);
937         }
938
939         protected Either<Boolean, ResponseFormat> validateServiceRoleAndCleanup(User user, Component component, AuditingActionEnum actionEnum) {
940                 String serviceRole = ((Service)component).getServiceRole();
941                 if (serviceRole != null){
942                         serviceRole = cleanUpText(serviceRole);
943         
944                         Either<Boolean, ResponseFormat> validateServiceRole = validateServiceRole(serviceRole);
945                         if (validateServiceRole.isRight()) {
946                                 ResponseFormat responseFormat = validateServiceRole.right().value();
947                                 componentsUtils.auditComponentAdmin(responseFormat, user, component, "", "", actionEnum, ComponentTypeEnum.SERVICE);
948                                 return Either.right(responseFormat);
949                         }
950                         return Either.left(true);
951                 } else {
952                         return Either.left(false);
953                 }
954         }
955
956         
957         private Either<Boolean, ResponseFormat> validateServiceRole(String serviceRole) {
958                 if (serviceRole.equals("")){
959                         return Either.left(true);
960                 } else {
961                         if (!ValidationUtils.validateServiceRoleLength(serviceRole)) {
962                                 log.info("service role exceeds limit.");
963                                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ROLE_EXCEEDS_LIMIT, "" + ValidationUtils.SERVICE_ROLE_MAX_LENGTH);
964                                 return Either.right(errorResponse);
965                         }
966
967                         if (!ValidationUtils.validateIsEnglish(serviceRole)) {
968                                 log.info("service role is not valid.");
969                                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_SERVICE_ROLE);
970                                 return Either.right(errorResponse);
971                         }
972                         return Either.left(true);
973                 }
974         }
975
976
977
978         private Either<Boolean, ResponseFormat> validateAndUpdateCategory(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
979                 List<CategoryDefinition> categoryUpdated = serviceUpdate.getCategories();
980                 List<CategoryDefinition> categoryCurrent = currentService.getCategories();
981                 Either<Boolean, ResponseFormat> validatCategoryResponse = validateServiceCategory(user, serviceUpdate, audatingAction);
982                 if (validatCategoryResponse.isRight()) {
983                         ResponseFormat errorRespons = validatCategoryResponse.right().value();
984                         return Either.right(errorRespons);
985                 }
986                 if (!categoryCurrent.get(0).getName().equals(categoryUpdated.get(0).getName())) {
987                         if (!hasBeenCertified) {
988                                 currentService.setCategories(categoryUpdated);
989                         } else {
990                                 log.info("category {} cannot be updated once the service has been certified once.", categoryUpdated);
991                                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CATEGORY_CANNOT_BE_CHANGED);
992                                 return Either.right(errorResponse);
993                         }
994                 }
995                 return Either.left(true);
996
997         }
998
999         public Either<Boolean, ResponseFormat> validateServiceCategory(List<CategoryDefinition> list) {
1000                 if (list != null) {
1001                         if (list.size() > 1) {
1002                                 log.debug("Must be only one category for service");
1003                                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_TOO_MUCH_CATEGORIES, ComponentTypeEnum.SERVICE.getValue());
1004                                 return Either.right(responseFormat);
1005                         }
1006                         CategoryDefinition category = list.get(0);
1007                         if (category.getSubcategories() != null) {
1008                                 log.debug("Subcategories cannot be defined for service");
1009                                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CANNOT_CONTAIN_SUBCATEGORY);
1010                                 return Either.right(responseFormat);
1011                         }
1012                         if (!ValidationUtils.validateStringNotEmpty(category.getName())) {
1013                                 log.debug("Resource category is empty");
1014                                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.SERVICE.getValue());
1015                                 return Either.right(responseFormat);
1016                         }
1017
1018                         log.debug("validating service category {} against valid categories list", list);
1019                         Either<List<CategoryDefinition>, ActionStatus> categorys = elementDao.getAllServiceCategories();
1020                         if (categorys.isRight()) {
1021                                 log.debug("failed to retrive service categories from Titan");
1022                                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(categorys.right().value());
1023                                 return Either.right(responseFormat);
1024                         }
1025                         List<CategoryDefinition> categoryList = categorys.left().value();
1026                         for (CategoryDefinition value : categoryList) {
1027                                 if (value.getName().equals(category.getName())) {
1028                                         return Either.left(true);
1029                                 }
1030                         }
1031                         log.debug("Category {} is not part of service category group. Service category valid values are {}", list, categoryList);
1032                         return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.SERVICE.getValue()));
1033                 }
1034                 return Either.left(false);
1035         }
1036
1037         public ResponseFormat deleteService(String serviceId, User user) {
1038                 ResponseFormat responseFormat;
1039                 String ecompErrorContext = "delete service";
1040
1041                 Either<User, ResponseFormat> eitherCreator = validateUserExists(user, ecompErrorContext, false);
1042                 if (eitherCreator.isRight()) {
1043                         return eitherCreator.right().value();
1044                 }
1045                 user = eitherCreator.left().value();
1046
1047                 Either<Service, StorageOperationStatus> serviceStatus = toscaOperationFacade.getToscaElement(serviceId);
1048                 if (serviceStatus.isRight()) {
1049                         log.debug("failed to get service {}", serviceId);
1050                         return componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceStatus.right().value()), "");
1051                 }
1052
1053                 Service service = serviceStatus.left().value();
1054
1055                 StorageOperationStatus result = StorageOperationStatus.OK;
1056                 Either<Boolean, ResponseFormat> lockResult = lockComponent(service, "Mark service to delete");
1057                 if (lockResult.isRight()) {
1058                         result = StorageOperationStatus.GENERAL_ERROR;
1059                         return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1060                 }
1061
1062                 try {
1063
1064                         result = markComponentToDelete(service);
1065                         if (result.equals(StorageOperationStatus.OK)) {
1066                                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1067                         } else {
1068                                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1069                                 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1070                         }
1071                         return responseFormat;
1072
1073                 } finally {
1074                         if (result == null || !result.equals(StorageOperationStatus.OK)) {
1075                                 log.warn("operation failed. do rollback");
1076                                 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1077                                 titanDao.rollback();
1078                         } else {
1079                                 log.debug("operation success. do commit");
1080                                 titanDao.commit();
1081                         }
1082                         graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1083                 }
1084         }
1085
1086         public ResponseFormat deleteServiceByNameAndVersion(String serviceName, String version, User user) {
1087                 ResponseFormat responseFormat;
1088                 String ecompErrorContext = "delete service";
1089                 Either<User, ResponseFormat> validateEmptyResult = validateUserNotEmpty(user, ecompErrorContext);
1090                 if (validateEmptyResult.isRight()) {
1091                         return validateEmptyResult.right().value();
1092                 }
1093
1094                 Either<User, ResponseFormat> eitherCreator = validateUserExists(user, ecompErrorContext, false);
1095                 if (eitherCreator.isRight()) {
1096                         return eitherCreator.right().value();
1097                 }
1098                 user = eitherCreator.left().value();
1099
1100                 Either<Service, ResponseFormat> getResult = getServiceByNameAndVersion(serviceName, version, user.getUserId());
1101                 if (getResult.isRight()) {
1102                         return getResult.right().value();
1103                 }
1104                 Service service = getResult.left().value();
1105
1106                 StorageOperationStatus result = StorageOperationStatus.OK;
1107                 Either<Boolean, ResponseFormat> lockResult = lockComponent(service, "Mark service to delete");
1108                 if (lockResult.isRight()) {
1109                         result = StorageOperationStatus.GENERAL_ERROR;
1110                         return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1111                 }
1112
1113                 try {
1114                         result = markComponentToDelete(service);
1115                         if (result.equals(StorageOperationStatus.OK)) {
1116                                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1117                         } else {
1118                                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1119                                 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1120                         }
1121                         return responseFormat;
1122
1123                 } finally {
1124                         if (result == null || !result.equals(StorageOperationStatus.OK)) {
1125                                 log.warn("operation failed. do rollback");
1126                                 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1127                                 titanDao.rollback();
1128                         } else {
1129                                 log.debug("operation success. do commit");
1130                                 titanDao.commit();
1131                         }
1132                         graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
1133                 }
1134         }
1135
1136         public Either<Service, ResponseFormat> getService(String serviceId, User user) {
1137                 String ecompErrorContext = "Get service";
1138                 Either<User, ResponseFormat> validateEmptyResult = validateUserNotEmpty(user, ecompErrorContext);
1139                 if (validateEmptyResult.isRight()) {
1140                         return Either.right(validateEmptyResult.right().value());
1141                 }
1142
1143                 Either<User, ResponseFormat> eitherCreator = validateUserExists(user, ecompErrorContext, false);
1144                 if (eitherCreator.isRight()) {
1145                         return Either.right(eitherCreator.right().value());
1146                 }
1147
1148                 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1149                 if (storageStatus.isRight()) {
1150                         log.debug("failed to get service by id {}", serviceId);
1151                         return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceId));
1152                 }
1153
1154                 if(!(storageStatus.left().value() instanceof Service)){
1155                         return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND), serviceId));
1156                 }
1157                 Service service = storageStatus.left().value();
1158                 return Either.left(service);
1159
1160
1161
1162
1163         }
1164
1165         public Either<Service, ResponseFormat> getServiceByNameAndVersion(String serviceName, String serviceVersion, String userId) {
1166                 Either<User, ResponseFormat> resp = validateUserExists(userId, "get Service By Name And Version", false);
1167                 if (resp.isRight()) {
1168                         return Either.right(resp.right().value());
1169                 }
1170                 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getComponentByNameAndVersion(ComponentTypeEnum.SERVICE, serviceName, serviceVersion);
1171                 if (storageStatus.isRight()) {
1172                         log.debug("failed to get service by name {} and version {}", serviceName, serviceVersion);
1173                         return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceName));
1174                 }
1175                 Service service = storageStatus.left().value();
1176                 return Either.left(service);
1177         }
1178
1179         @SuppressWarnings("unchecked")
1180         private void createMandatoryArtifactsData(Service service, User user) {
1181                 // create mandatory artifacts
1182
1183                 // TODO it must be removed after that artifact uniqueId creation will be
1184                 // moved to ArtifactOperation
1185                 // String serviceUniqueId =
1186                 // UniqueIdBuilder.buildServiceUniqueId(service.getComponentMetadataDefinition().getMetadataDataDefinition().getName(),
1187                 // service.getComponentMetadataDefinition().getMetadataDataDefinition().getVersion());
1188                 String serviceUniqueId = service.getUniqueId();
1189                 Map<String, ArtifactDefinition> artifactMap = service.getArtifacts();
1190                 if (artifactMap == null)
1191                         artifactMap = new HashMap<String, ArtifactDefinition>();
1192
1193                 Map<String, Object> informationalServiceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getInformationalServiceArtifacts();
1194                 List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
1195
1196                 String category = service.getCategories().get(0).getName();
1197                 boolean isCreateArtifact = true;
1198                 if (category != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
1199                         for (String exlude : exludeServiceCategory) {
1200                                 if (exlude.equalsIgnoreCase(category)) {
1201                                         isCreateArtifact = false;
1202                                         break;
1203                                 }
1204                         }
1205
1206                 }
1207
1208                 if (informationalServiceArtifacts != null && isCreateArtifact) {
1209                         Set<String> keys = informationalServiceArtifacts.keySet();
1210                         for (String informationalServiceArtifactName : keys) {
1211                                 Map<String, Object> artifactInfoMap = (Map<String, Object>) informationalServiceArtifacts.get(informationalServiceArtifactName);
1212                                 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, informationalServiceArtifactName, artifactInfoMap, user, false);
1213                                 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
1214
1215                         }
1216
1217                         service.setArtifacts(artifactMap);
1218                 }
1219         }
1220
1221         private ArtifactDefinition createArtifactDefinition(String serviceId, String logicalName, Map<String, Object> artifactInfoMap, User user, Boolean isServiceApi) {
1222
1223                 ArtifactDefinition artifactInfo = artifactsBusinessLogic.createArtifactPlaceHolderInfo(serviceId, logicalName, artifactInfoMap, user, ArtifactGroupTypeEnum.INFORMATIONAL);
1224
1225                 if (isServiceApi) {
1226                         artifactInfo.setMandatory(false);
1227                         artifactInfo.setServiceApi(true);
1228                 }
1229                 return artifactInfo;
1230         }
1231
1232         private Either<DistributionTransitionEnum, ResponseFormat> validateTransitionEnum(String distributionTransition, User user) {
1233                 DistributionTransitionEnum transitionEnum = null;
1234
1235                 transitionEnum = DistributionTransitionEnum.getFromDisplayName(distributionTransition);
1236                 if (transitionEnum == null) {
1237                         BeEcompErrorManager.getInstance().logBeSystemError("Change Service Distribution");
1238                         log.info("state operation is not valid. operations allowed are: {}", DistributionTransitionEnum.valuesAsString());
1239                         ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1240                         return Either.right(error);
1241                 }
1242
1243                 return Either.left(transitionEnum);
1244         }
1245
1246         private Either<String, ResponseFormat> validateComment(LifecycleChangeInfoWithAction comment, User user, AuditingActionEnum auditAction) {
1247                 String data = comment.getUserRemarks();
1248
1249                 if (data == null || data.trim().isEmpty()) {
1250                         BeEcompErrorManager.getInstance().logBeInvalidJsonInput("Change Service Distribution");
1251                         log.debug("user comment cannot be empty or null.");
1252                         return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1253                 }
1254                 data = ValidationUtils.removeNoneUtf8Chars(data);
1255                 data = ValidationUtils.removeHtmlTags(data);
1256                 data = ValidationUtils.normaliseWhitespace(data);
1257                 data = ValidationUtils.stripOctets(data);
1258
1259                 if (!ValidationUtils.validateLength(data, ValidationUtils.COMMENT_MAX_LENGTH)) {
1260                         BeEcompErrorManager.getInstance().logBeInvalidJsonInput("Change Service Distribution");
1261                         log.debug("user comment exceeds limit.");
1262                         return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, "comment", String.valueOf(ValidationUtils.COMMENT_MAX_LENGTH)));
1263                 }
1264                 if (!ValidationUtils.validateIsEnglish(data)) {
1265                         return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1266                 }
1267                 return Either.left(data);
1268         }
1269
1270         private Either<Service, ResponseFormat> validateServiceDistributionChange(User user, String serviceId, AuditingActionEnum auditAction, String comment) {
1271                 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1272                 if (storageStatus.isRight()) {
1273                         ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId);
1274                         createAudit(user, auditAction, comment, responseFormat);
1275                         return Either.right(responseFormat);
1276                 }
1277                 Service service = storageStatus.left().value();
1278
1279                 if (service.getLifecycleState() != LifecycleStateEnum.CERTIFIED) {
1280                         log.info("service {} is  not available for distribution. Should be in certified state", service.getUniqueId());
1281                         ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION, service.getVersion(), service.getName());
1282                         createAudit(user, auditAction, comment, service, responseFormat);
1283                         return Either.right(responseFormat);
1284                 }
1285                 return Either.left(service);
1286         }
1287
1288         private Either<User, ResponseFormat> validateUserDistributionChange(User user, Service service, AuditingActionEnum auditAction, String comment) {
1289                 log.debug("get user from DB");
1290
1291                 // get user details
1292                 Either<User, ResponseFormat> eitherCreator = validateUser(user, "Activate Distribution", service, auditAction, false);
1293                 if (eitherCreator.isRight()) {
1294                         return Either.right(eitherCreator.right().value());
1295                 }
1296                 user = eitherCreator.left().value();
1297
1298                 // validate user role
1299                 List<Role> roles = new ArrayList<>();
1300                 roles.add(Role.ADMIN);
1301                 roles.add(Role.GOVERNOR);
1302                 roles.add(Role.OPS);
1303                 Either<Boolean, ResponseFormat> validateRes = validateUserRole(user, service, roles, auditAction, comment);
1304                 if (validateRes.isRight()) {
1305                         return Either.right(validateRes.right().value());
1306                 }
1307                 return Either.left(user);
1308         }
1309
1310         private void createAudit(User user, AuditingActionEnum auditAction, String comment, ResponseFormat responseFormat) {
1311                 EnumMap<AuditingFieldsKeysEnum, Object> auditingFields = new EnumMap<AuditingFieldsKeysEnum, Object>(AuditingFieldsKeysEnum.class);
1312
1313                 createAudit(user, auditAction, comment, null, responseFormat, auditingFields);
1314         }
1315
1316         private void createAudit(User user, AuditingActionEnum auditAction, String comment, Service component, ResponseFormat responseFormat) {
1317                 EnumMap<AuditingFieldsKeysEnum, Object> auditingFields = new EnumMap<AuditingFieldsKeysEnum, Object>(AuditingFieldsKeysEnum.class);
1318                 auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_DCURR_STATUS, component.getDistributionStatus().name());
1319                 auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_DPREV_STATUS, component.getDistributionStatus().name());
1320                 createAudit(user, auditAction, comment, component, component.getLifecycleState().name(), component.getVersion(), responseFormat, auditingFields);
1321         }
1322
1323         private void createAudit(User user, AuditingActionEnum auditAction, String comment, Service component, ResponseFormat responseFormat, EnumMap<AuditingFieldsKeysEnum, Object> auditingFields) {
1324                 log.debug("audit before sending response");
1325                 auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_COMMENT, comment);
1326                 componentsUtils.auditComponent(responseFormat, user, component, null, null, auditAction, ComponentTypeEnum.SERVICE, auditingFields);
1327         }
1328
1329         private void createAudit(User user, AuditingActionEnum auditAction, String comment, Service component, String prevState, String prevVersion, ResponseFormat responseFormat, EnumMap<AuditingFieldsKeysEnum, Object> auditingFields) {
1330                 log.debug("audit before sending response");
1331                 auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_COMMENT, comment);
1332                 componentsUtils.auditComponent(responseFormat, user, component, prevState, prevVersion, auditAction, ComponentTypeEnum.SERVICE, auditingFields);
1333         }
1334
1335         public Either<Service, ResponseFormat> activateDistribution(String serviceId, String envName, User modifier, HttpServletRequest request) {
1336
1337                 Either<User, ResponseFormat> eitherCreator = validateUserExists(modifier.getUserId(), "activate Distribution", false);
1338                 if (eitherCreator.isRight()) {
1339                         return Either.right(eitherCreator.right().value());
1340                 }
1341
1342                 User user = eitherCreator.left().value();
1343
1344                 Either<Service, ResponseFormat> result = null;
1345                 ResponseFormat response = null;
1346                 Service updatedService = null;
1347                 String did = ThreadLocalsHolder.getUuid();
1348                 EnumMap<AuditingFieldsKeysEnum, Object> auditingFields = new EnumMap<AuditingFieldsKeysEnum, Object>(AuditingFieldsKeysEnum.class);
1349                 auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_ID, did);
1350                 // DE194021
1351                 String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1352                 if (configuredEnvName != null && false == envName.equals(configuredEnvName)) {
1353                         log.trace("Update environment name to be {} instead of {}", configuredEnvName, envName);
1354                         envName = configuredEnvName;
1355                 }
1356                 // DE194021
1357
1358                 ServletContext servletContext = request.getSession().getServletContext();
1359                 boolean isDistributionEngineUp = getHealthCheckBL(servletContext).isDistributionEngineUp(); // DE
1360                 if (!isDistributionEngineUp) {
1361                         BeEcompErrorManager.getInstance().logBeSystemError("Distribution Engine is DOWN");
1362                         log.debug("Distribution Engine is DOWN");
1363                         response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1364                         return Either.right(response);
1365                 }
1366
1367                 Either<Service, StorageOperationStatus> serviceRes = toscaOperationFacade.getToscaElement(serviceId);
1368                 if (serviceRes.isRight()) {
1369                         log.debug("failed retrieving service");
1370                         response = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceRes.right().value(), ComponentTypeEnum.SERVICE), serviceId);
1371                         componentsUtils.auditComponent(response, user, null, null, null, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST, ComponentTypeEnum.SERVICE, auditingFields);
1372                         return Either.right(response);
1373                 }
1374                 Service service = serviceRes.left().value();
1375                 String dcurrStatus = service.getDistributionStatus().name();
1376                 auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_DPREV_STATUS, dcurrStatus);
1377
1378                 Either<INotificationData, StorageOperationStatus> readyForDistribution = distributionEngine.isReadyForDistribution(service, did, envName);
1379                 if (readyForDistribution.isLeft()) {
1380                         INotificationData notificationData = readyForDistribution.left().value();
1381                         StorageOperationStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envName, user.getUserId(), user.getFullName());
1382                         if (notifyServiceResponse == StorageOperationStatus.OK) {
1383                                 Either<Service, ResponseFormat> updateStateRes = updateDistributionStatusForActivation(service, user, DistributionStatusEnum.DISTRIBUTED);
1384                                 if (updateStateRes.isLeft() && updateStateRes.left().value() != null) {
1385                                         updatedService = updateStateRes.left().value();
1386                                         dcurrStatus = updatedService.getDistributionStatus().name();
1387                                 } else {
1388                                         // The response is not relevant
1389                                         updatedService = service;
1390                                 }
1391                                 ASDCKpiApi.countActivatedDistribution();
1392                                 response = componentsUtils.getResponseFormat(ActionStatus.OK);
1393                                 result = Either.left(updatedService);
1394                         } else {
1395                                 BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1396                                 log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1397                                 response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1398                                 result = Either.right(response);
1399                         }
1400                 } else {
1401                         StorageOperationStatus distEngineValidationResponse = readyForDistribution.right().value();
1402                         response = componentsUtils.getResponseFormatByDE(componentsUtils.convertFromStorageResponse(distEngineValidationResponse), service.getName(), envName);
1403                         result = Either.right(response);
1404                 }
1405                 auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_DCURR_STATUS, dcurrStatus);
1406                 componentsUtils.auditComponent(response, user, service, null, null, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST, ComponentTypeEnum.SERVICE, auditingFields);
1407                 return result;
1408         }
1409
1410         // convert to private after deletion of temp url
1411         public Either<Service, ResponseFormat> updateDistributionStatusForActivation(Service service, User user, DistributionStatusEnum state) {
1412
1413                 Either<User, ResponseFormat> resp = validateUserExists(user.getUserId(), "update Distribution Status For Activation", false);
1414                 if (resp.isRight()) {
1415                         return Either.right(resp.right().value());
1416                 }
1417
1418                 String serviceId = service.getUniqueId();
1419                 Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, service, "updateDistributionStatusForActivation");
1420                 if (lockResult.isRight()) {
1421                         return Either.right(lockResult.right().value());
1422                 }
1423                 try {
1424                         Either<Service, StorageOperationStatus> result = toscaOperationFacade.updateDistributionStatus(service, user, state);
1425                         if (result.isRight()) {
1426                                 titanDao.rollback();
1427                                 BeEcompErrorManager.getInstance().logBeSystemError("updateDistributionStatusForActivation");
1428                                 log.debug("service {}  change distribution status failed", serviceId);
1429                                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1430                         }
1431                         titanDao.commit();
1432                         return Either.left(result.left().value());
1433                 } finally {
1434                         graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1435                 }
1436         }
1437
1438         public Either<Service, ResponseFormat> markDistributionAsDeployed(String serviceId, String did, User user) {
1439
1440                 Either<User, ResponseFormat> resp = validateUserExists(user.getUserId(), "mark Distribution As Deployed", false);
1441                 if (resp.isRight()) {
1442                         return Either.right(resp.right().value());
1443                 }
1444
1445                 log.debug("mark distribution deployed");
1446
1447                 AuditingActionEnum auditAction = AuditingActionEnum.DISTRIBUTION_DEPLOY;
1448                 Either<Service, StorageOperationStatus> getServiceResponse = toscaOperationFacade.getToscaElement(serviceId);
1449                 if (getServiceResponse.isRight()) {
1450                         BeEcompErrorManager.getInstance().logBeComponentMissingError("markDistributionAsDeployed", ComponentTypeEnum.SERVICE.getValue(), serviceId);
1451                         log.debug("service {} not found", serviceId);
1452                         ResponseFormat responseFormat = auditDeployError(did, user, auditAction, null, componentsUtils.convertFromStorageResponse(getServiceResponse.right().value(), ComponentTypeEnum.SERVICE), "");
1453
1454                         return Either.right(responseFormat);
1455                 }
1456
1457                 Service service = getServiceResponse.left().value();
1458
1459                 Either<User, ResponseFormat> validateRoleForDeploy = validateRoleForDeploy(did, user, auditAction, service);
1460                 if (validateRoleForDeploy.isRight()) {
1461                         return Either.right(validateRoleForDeploy.right().value());
1462                 }
1463                 user = validateRoleForDeploy.left().value();
1464
1465                 return checkDistributionAndDeploy(did, user, auditAction, service);
1466
1467         }
1468
1469         public Either<Service, ResponseFormat> generateVfModuleArtifacts(Service service, User modifier, boolean shouldLock) {
1470                 Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = ri ->
1471                 // Only one VF Module Artifact per instance - add it to a list of one
1472                 buildArtifactGenList(service, modifier, shouldLock, ri);
1473
1474                 return generateDeploymentArtifacts(service, modifier, artifactTaskGeneratorCreator);
1475
1476         }
1477
1478         private List<ArtifactGenerator<ArtifactDefinition>> buildArtifactGenList(Service service, User modifier, boolean shouldLock, ComponentInstance ri) {
1479                 List<ArtifactGenerator<ArtifactDefinition>> asList = new ArrayList<ArtifactGenerator<ArtifactDefinition>>();
1480
1481                 if (ri.getOriginType() == OriginTypeEnum.VF) {
1482                         asList = Arrays.asList(new VfModuleArtifacGenerator(modifier, ri, service, shouldLock));
1483                 }
1484                 return asList;
1485         }
1486
1487         private List<GroupInstance> collectGroupsInstanceForCompInstance(ComponentInstance currVF, Wrapper<ResponseFormat> responseWrapper) {
1488
1489                 return currVF.getGroupInstances();
1490         }
1491
1492         private ArtifactDefinition getVfModuleInstArtifactForCompInstance(ComponentInstance currVF, Service service, User modifier, List<GroupInstance> groupsForCurrVF, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper) {
1493                 ArtifactDefinition vfModuleAertifact = null;
1494                 if (MapUtils.isNotEmpty(currVF.getDeploymentArtifacts())) {
1495                         Optional<ArtifactDefinition> optionalVfModuleArtifact = currVF.getDeploymentArtifacts().values().stream().filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.VF_MODULES_METADATA.name())).findAny();
1496                         if (optionalVfModuleArtifact.isPresent()) {
1497                                 vfModuleAertifact = optionalVfModuleArtifact.get();
1498                         }
1499                 }
1500                 if (vfModuleAertifact == null) {
1501                         Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact = createVfModuleArtifact(modifier, currVF, service, payloadWrapper.getInnerElement());
1502                         if (createVfModuleArtifact.isLeft()) {
1503                                 vfModuleAertifact = createVfModuleArtifact.left().value();
1504                         } else {
1505                                 responseWrapper.setInnerElement(createVfModuleArtifact.right().value());
1506                         }
1507                 }
1508                 return vfModuleAertifact;
1509         }
1510
1511         private void fillVfModuleInstHeatEnvPayload(List<GroupInstance> groupsForCurrVF, ComponentInstance currVFInstance, Wrapper<String> payloadWrapper) {
1512                 // Converts GroupDefinition to VfModuleArtifactPayload which is the
1513                 // format used in the payload
1514
1515                 // List<VfModuleArtifactPayload> vfModulePayloadForCurrVF = groupsForCurrVF.stream().map(group -> new VfModuleArtifactPayload(group)).collect(Collectors.toList());
1516                 List<VfModuleArtifactPayload> vfModulePayloadForCurrVF = new ArrayList<VfModuleArtifactPayload>();
1517                 if (groupsForCurrVF != null) {
1518                         for (GroupInstance groupInstance : groupsForCurrVF) {
1519                                 VfModuleArtifactPayload modulePayload = new VfModuleArtifactPayload(groupInstance);
1520                                 vfModulePayloadForCurrVF.add(modulePayload);
1521                         }
1522                         Collections.sort(vfModulePayloadForCurrVF, (art1, art2) -> VfModuleArtifactPayload.compareByGroupName(art1, art2));
1523                         // Update Payload With Heat Env
1524 //                      vfModulePayloadForCurrVF.stream().forEach(e -> addHeatEnvArtifactsToVFModulePayload(e, currVFInstance));
1525
1526                         final Gson gson = new GsonBuilder().setPrettyPrinting().create();
1527
1528                         String vfModulePayloadString = gson.toJson(vfModulePayloadForCurrVF);
1529                         payloadWrapper.setInnerElement(vfModulePayloadString);
1530                 }
1531
1532         }
1533
1534         private void addHeatEnvArtifactsToVFModulePayload(VfModuleArtifactPayload vfModulePayload, ComponentInstance currVFInstance) {
1535                 List<String> originalModuleArtifacts = vfModulePayload.getArtifacts();
1536                 if (!MapUtils.isEmpty(currVFInstance.getDeploymentArtifacts()) && !CollectionUtils.isEmpty(originalModuleArtifacts)) {
1537
1538                         // EVG : fix now for patch. remove null from list. Need to be fixed later : remove VF HEAT ENV uuid from the list??
1539                         List<String> filteredUUIDFromModule = originalModuleArtifacts.stream().filter(uuid -> uuid != null).collect(Collectors.toList());
1540
1541                         final Collection<ArtifactDefinition> depInsArtifacts = currVFInstance.getDeploymentArtifacts().values();
1542                         // All Heat_ENV
1543                         List<ArtifactDefinition> heatEnvArtifacts = depInsArtifacts.stream().filter(art -> art.getArtifactType().equals(ArtifactTypeEnum.HEAT_ENV.getType())).collect(Collectors.toList());
1544                         // Unique Id Of Artifacts In the vf module
1545                         List<String> moduleArtUniqueId = depInsArtifacts.stream().filter(art -> originalModuleArtifacts.contains(art.getArtifactUUID())).map(art -> art.getUniqueId()).collect(Collectors.toList());
1546                         // Collect Only Heat Artifatcs that are Generated from artifacts in
1547                         // the module
1548                         List<String> relevantHeatEnvUUID = heatEnvArtifacts.stream().filter(heatEnv -> moduleArtUniqueId.contains(heatEnv.getGeneratedFromId())).map(heatEnv -> heatEnv.getArtifactUUID()).collect(Collectors.toList());
1549
1550                         List<String> fullArtifactList = new ArrayList<>();
1551                         fullArtifactList.addAll(filteredUUIDFromModule);
1552                         fullArtifactList.addAll(relevantHeatEnvUUID);
1553
1554                         vfModulePayload.setArtifacts(fullArtifactList);
1555                 }
1556         }
1557
1558         private Either<ArtifactDefinition, ResponseFormat> generateVfModuleInstanceArtifact(User modifier, ComponentInstance currVFInstance, Service service, boolean shouldLock) {
1559                 ArtifactDefinition vfModuleAertifact = null;
1560                 Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
1561                 Wrapper<String> payloadWrapper = new Wrapper<>();
1562                 List<GroupInstance> groupsForCurrVF = collectGroupsInstanceForCompInstance(currVFInstance, responseWrapper);
1563                 if (responseWrapper.isEmpty()) {
1564                         fillVfModuleInstHeatEnvPayload(groupsForCurrVF, currVFInstance, payloadWrapper);
1565                 }
1566                 if (responseWrapper.isEmpty() && payloadWrapper.getInnerElement() != null) {
1567                         vfModuleAertifact = getVfModuleInstArtifactForCompInstance(currVFInstance, service, modifier, groupsForCurrVF, payloadWrapper, responseWrapper);
1568                 }
1569                 if (responseWrapper.isEmpty() && vfModuleAertifact != null) {
1570                         vfModuleAertifact = fillVfModulePayload(modifier, currVFInstance, vfModuleAertifact, shouldLock, payloadWrapper, responseWrapper, service);
1571                 }
1572
1573                 Either<ArtifactDefinition, ResponseFormat> result;
1574                 if (responseWrapper.isEmpty()) {
1575                         result = Either.left(vfModuleAertifact);
1576                 } else {
1577                         result = Either.right(responseWrapper.getInnerElement());
1578                 }
1579
1580                 return result;
1581         }
1582
1583         private ArtifactDefinition fillVfModulePayload(User modifier, ComponentInstance currVF, ArtifactDefinition vfModuleArtifact, boolean shouldLock, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper, Service service) {
1584                 ArtifactDefinition result = null;
1585 //              final Either<Resource, StorageOperationStatus> eitherResource = toscaOperationFacade.getToscaElement(currVF.getComponentUid());
1586 //              if (eitherResource.isRight()) {
1587 //                      responseWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(eitherResource.right().value())));
1588 //              } else if (!payloadWrapper.isEmpty()) {
1589 //                      Resource resource = eitherResource.left().value();
1590                         Either<ArtifactDefinition, ResponseFormat> eitherPayload = artifactsBusinessLogic.generateArtifactPayload(vfModuleArtifact, ComponentTypeEnum.RESOURCE_INSTANCE, service, currVF.getName(), modifier, shouldLock, () -> System.currentTimeMillis(),
1591                                         () -> Either.left(artifactsBusinessLogic.createEsArtifactData(vfModuleArtifact, payloadWrapper.getInnerElement().getBytes(StandardCharsets.UTF_8))), currVF.getUniqueId());
1592                         if (eitherPayload.isLeft()) {
1593                                 result = eitherPayload.left().value();
1594                         } else {
1595                                 responseWrapper.setInnerElement(eitherPayload.right().value());
1596                         }
1597 //              }
1598                 if (result == null) {
1599                         result = vfModuleArtifact;
1600                 }
1601
1602                 return result;
1603         }
1604
1605         private Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact(User modifier, ComponentInstance currVF, Service service, String vfModulePayloadString) {
1606
1607                 ArtifactDefinition vfModuleArtifactDefinition = new ArtifactDefinition();
1608                 String newCheckSum = null;
1609
1610                 vfModuleArtifactDefinition.setDescription("Auto-generated VF Modules information artifact");
1611                 vfModuleArtifactDefinition.setArtifactDisplayName("Vf Modules Metadata");
1612                 vfModuleArtifactDefinition.setArtifactType(ArtifactTypeEnum.VF_MODULES_METADATA.getType());
1613                 vfModuleArtifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT);
1614                 vfModuleArtifactDefinition.setArtifactLabel("vfModulesMetadata");
1615                 vfModuleArtifactDefinition.setTimeout(0);
1616                 vfModuleArtifactDefinition.setArtifactName(currVF.getNormalizedName() + "_modules.json");
1617                 vfModuleArtifactDefinition.setPayloadData(vfModulePayloadString);
1618                 if (vfModulePayloadString != null) {
1619                         newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(vfModulePayloadString.getBytes());
1620                 }
1621                 vfModuleArtifactDefinition.setArtifactChecksum(newCheckSum);
1622
1623                 Either<ArtifactDefinition, StorageOperationStatus> addArifactToComponent = artifactToscaOperation.addArifactToComponent(vfModuleArtifactDefinition, service.getUniqueId(), NodeTypeEnum.ResourceInstance, true, currVF.getUniqueId());
1624
1625                 Either<ArtifactDefinition, ResponseFormat> result;
1626                 if (addArifactToComponent.isLeft()) {
1627                         result = Either.left(addArifactToComponent.left().value());
1628                 } else {
1629                         result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(addArifactToComponent.right().value())));
1630                 }
1631
1632                 return result;
1633         }
1634
1635         public Either<Service, ResponseFormat> generateHeatEnvArtifacts(Service service, User modifier, boolean shouldLock) {
1636
1637                 Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = resourceInstance ->
1638                 // Get All Deployment Artifacts
1639                 service.getComponentInstances().stream().filter(ri -> ri != null && ri == resourceInstance).filter(ri -> ri.getDeploymentArtifacts() != null).flatMap(ri -> ri.getDeploymentArtifacts().values().stream()).
1640                 // Filter in Only Heat Env
1641                                 filter(depArtifact -> ArtifactTypeEnum.HEAT_ENV.getType().equals(depArtifact.getArtifactType())).
1642                                 // Create ArtifactGenerator from those Artifacts
1643                                 map(depArtifact -> new HeatEnvArtifactGenerator(depArtifact, service, resourceInstance.getName(), modifier, shouldLock, resourceInstance.getUniqueId())).collect(Collectors.toList());
1644
1645                 return generateDeploymentArtifacts(service, modifier, artifactTaskGeneratorCreator);
1646
1647         }
1648
1649         private <CallVal> Either<Service, ResponseFormat> generateDeploymentArtifacts(Service service, User modifier, Function<ComponentInstance, List<ArtifactGenerator<CallVal>>> artifactTaskGeneratorCreator) {
1650
1651                 // Get Flat List of (Callable) ArtifactGenerator for all the RI in the
1652                 // service
1653                 if (service.getComponentInstances() != null) {
1654                         List<ArtifactGenerator<CallVal>> artifactGenList = service.getComponentInstances().stream().flatMap(ri -> artifactTaskGeneratorCreator.apply(ri).stream()).collect(Collectors.toList());
1655                         if (artifactGenList != null && !artifactGenList.isEmpty()) {
1656                                 for (ArtifactGenerator<CallVal> entry : artifactGenList) {
1657                                         Either<CallVal, ResponseFormat> callRes;
1658                                         try {
1659                                                 callRes = entry.call();
1660                                                 if (callRes.isRight()) {
1661                                                         log.debug("Failed to generate artifact error : {}", callRes.right().value());
1662                                                         return Either.right(callRes.right().value());
1663                                                 }
1664                                         } catch (Exception e) {
1665                                                 log.debug("Failed to generate artifact exception : {}", e);
1666                                                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1667                                         }
1668                                 }
1669                         }
1670                 }
1671                 return Either.left(service);
1672         }
1673
1674         abstract class ArtifactGenerator<CallVal> implements Callable<Either<CallVal, ResponseFormat>> {
1675
1676         }
1677
1678         class HeatEnvArtifactGenerator extends ArtifactGenerator<ArtifactDefinition> {
1679                 ArtifactDefinition artifactDefinition;
1680                 Service service;
1681                 String resourceInstanceName;
1682                 User modifier;
1683                 String instanceId;
1684                 boolean shouldLock;
1685
1686                 HeatEnvArtifactGenerator(ArtifactDefinition artifactDefinition, Service service, String resourceInstanceName, User modifier, boolean shouldLock, String instanceId) {
1687                         this.artifactDefinition = artifactDefinition;
1688                         this.service = service;
1689                         this.resourceInstanceName = resourceInstanceName;
1690                         this.modifier = modifier;
1691                         this.shouldLock = shouldLock;
1692                         this.instanceId = instanceId;
1693                 }
1694
1695                 @Override
1696                 public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
1697                         return artifactsBusinessLogic.generateHeatEnvArtifact(artifactDefinition, ComponentTypeEnum.RESOURCE_INSTANCE, service, resourceInstanceName, modifier, shouldLock, instanceId);
1698                 }
1699
1700                 public ArtifactDefinition getArtifactDefinition() {
1701                         return artifactDefinition;
1702                 }
1703
1704         }
1705
1706         class VfModuleArtifacGenerator extends ArtifactGenerator<ArtifactDefinition> {
1707                 private User user;
1708                 private ComponentInstance componentInstance;
1709                 private Service service;
1710                 boolean shouldLock;
1711
1712                 @Override
1713                 public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
1714                         return generateVfModuleInstanceArtifact(user, componentInstance, service, shouldLock);// generateVfModuleArtifact(user, componentInstance, service, shouldLock);
1715                 }
1716
1717                 private VfModuleArtifacGenerator(User user, ComponentInstance componentInstance, Service service, boolean shouldLock) {
1718                         super();
1719                         this.user = user;
1720                         this.componentInstance = componentInstance;
1721                         this.service = service;
1722                         this.shouldLock = shouldLock;
1723                 }
1724
1725         }
1726
1727         private synchronized Either<Service, ResponseFormat> checkDistributionAndDeploy(String did, User user, AuditingActionEnum auditAction, Service service) {
1728                 boolean isDeployed = isDistributionDeployed(did, service);
1729                 if (isDeployed) {
1730                         return Either.left(service);
1731                 }
1732                 Either<Boolean, ResponseFormat> distributionSuccess = checkDistributionSuccess(did, user, auditAction, service);
1733                 if (distributionSuccess.isRight()) {
1734                         return Either.right(distributionSuccess.right().value());
1735                 }
1736
1737                 log.debug("mark distribution {} as deployed - success", did);
1738                 componentsUtils.auditServiceDistributionDeployed(auditAction, service.getName(), service.getVersion(), service.getUUID(), did, STATUS_DEPLOYED, "OK", user);
1739                 return Either.left(service);
1740         }
1741
1742         private boolean isDistributionDeployed(String did, Service service) {
1743                 Either<List<DistributionDeployEvent>, ActionStatus> alreadyDeployed = auditCassandraDao.getDistributionDeployByStatus(did, AuditingActionEnum.DISTRIBUTION_DEPLOY.getName(), STATUS_DEPLOYED);
1744
1745                 boolean isDeployed = false;
1746                 if (alreadyDeployed.isLeft() && !alreadyDeployed.left().value().isEmpty()) {
1747                         // already deployed
1748                         log.debug("distribution {} is already deployed", did);
1749                         isDeployed = true;
1750                 }
1751                 return isDeployed;
1752         }
1753
1754         protected Either<Boolean, ResponseFormat> checkDistributionSuccess(String did, User user, AuditingActionEnum auditAction, Service service) {
1755
1756                 log.trace("checkDistributionSuccess");
1757                 // get all "DRequest" records for this distribution
1758                 // Either<List<ESTimeBasedEvent>, ActionStatus> distRequestsResponse =
1759                 // auditingDao.getListOfDistributionByAction(did,
1760                 // AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST.getName(), "",
1761                 // ResourceAdminEvent.class);
1762                 Either<List<ResourceAdminEvent>, ActionStatus> distRequestsResponse = auditCassandraDao.getDistributionRequest(did, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST.getName());
1763                 if (distRequestsResponse.isRight()) {
1764                         ResponseFormat error = auditDeployError(did, user, auditAction, service, distRequestsResponse.right().value());
1765                         return Either.right(error);
1766                 }
1767
1768                 List<ResourceAdminEvent> distributionRequests = distRequestsResponse.left().value();
1769                 if (distributionRequests.isEmpty()) {
1770                         BeEcompErrorManager.getInstance().logBeDistributionMissingError("markDistributionAsDeployed", did);
1771                         log.info("distribution {} is not found", did);
1772                         ResponseFormat error = auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_NOT_FOUND);
1773                         return Either.right(error);
1774                 }
1775                 boolean isRequestSucceeded = false;
1776                 for (ResourceAdminEvent event : distributionRequests) {
1777                         String eventStatus = event.getStatus();
1778                         if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
1779                                 isRequestSucceeded = true;
1780                                 break;
1781                         }
1782                 }
1783
1784                 // get all "DNotify" records for this distribution
1785                 // Either<List<ESTimeBasedEvent>, ActionStatus>
1786                 // distNotificationsResponse =
1787                 // auditingDao.getListOfDistributionByAction(did,
1788                 // AuditingActionEnum.DISTRIBUTION_NOTIFY.getName(), "",
1789                 // DistributionNotificationEvent.class);
1790                 Either<List<DistributionNotificationEvent>, ActionStatus> distNotificationsResponse = auditCassandraDao.getDistributionNotify(did, AuditingActionEnum.DISTRIBUTION_NOTIFY.getName());
1791                 if (distNotificationsResponse.isRight()) {
1792                         ResponseFormat error = auditDeployError(did, user, auditAction, service, distNotificationsResponse.right().value());
1793                         return Either.right(error);
1794                 }
1795
1796                 List<DistributionNotificationEvent> distributionNotifications = distNotificationsResponse.left().value();
1797                 boolean isNotificationsSucceeded = false;
1798                 for (DistributionNotificationEvent event : distributionNotifications) {
1799                         String eventStatus = event.getStatus();
1800                         if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
1801                                 isNotificationsSucceeded = true;
1802                                 break;
1803                         }
1804                 }
1805
1806                 // if request failed OR there are notifications that failed
1807                 if (!(isRequestSucceeded && isNotificationsSucceeded)) {
1808
1809                         log.info("distribution {} has failed", did);
1810                         ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
1811                         auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
1812                         return Either.right(error);
1813                 }
1814                 return Either.left(true);
1815         }
1816
1817         private ResponseFormat auditDeployError(String did, User user, AuditingActionEnum auditAction, Service service, ActionStatus status, String... params) {
1818
1819                 ResponseFormat error = componentsUtils.getResponseFormat(status, params);
1820                 String message = "";
1821                 if (error.getMessageId() != null) {
1822                         message = error.getMessageId() + ": ";
1823                 }
1824                 message += error.getFormattedMessage();
1825
1826                 if (service != null) {
1827                         componentsUtils.auditServiceDistributionDeployed(auditAction, service.getName(), service.getVersion(), service.getUUID(), did, error.getStatus().toString(), message, user);
1828                 } else {
1829                         componentsUtils.auditServiceDistributionDeployed(auditAction, "", "", "", did, error.getStatus().toString(), message, user);
1830                 }
1831                 return error;
1832         }
1833
1834         private Either<User, ResponseFormat> validateRoleForDeploy(String did, User user, AuditingActionEnum auditAction, Service service) {
1835                 Either<User, ActionStatus> eitherCreator = userAdmin.getUser(user.getUserId(), false);
1836                 if (eitherCreator.isRight() || eitherCreator.left().value() == null) {
1837                         BeEcompErrorManager.getInstance().logBeUserMissingError("Deploy Service", user.getUserId());
1838                         log.debug("validateRoleForDeploy method - user is not listed. userId= {}", user.getUserId());
1839                         ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.USER_NOT_FOUND, user.getUserId());
1840                         auditDeployError(did, user, auditAction, service, ActionStatus.USER_NOT_FOUND);
1841                         return Either.right(responseFormat);
1842                 }
1843                 user = eitherCreator.left().value();
1844                 log.debug("validate user role");
1845                 List<Role> roles = new ArrayList<>();
1846                 roles.add(Role.ADMIN);
1847                 roles.add(Role.OPS);
1848                 Either<Boolean, ResponseFormat> validateRes = validateUserRole(user, service, roles, auditAction, null);
1849                 if (validateRes.isRight()) {
1850                         log.info("role {} is not allowed to perform this action", user.getRole());
1851                         ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
1852                         auditDeployError(did, user, auditAction, service, ActionStatus.RESTRICTED_OPERATION);
1853                         return Either.right(responseFormat);
1854                 }
1855                 return Either.left(user);
1856
1857         }
1858
1859         @Override
1860         public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
1861
1862         }
1863
1864         @Override
1865         public Either<List<String>, ResponseFormat> deleteMarkedComponents() {
1866                 return deleteMarkedComponents(ComponentTypeEnum.SERVICE);
1867         }
1868
1869         private HealthCheckBusinessLogic getHealthCheckBL(ServletContext context) {
1870                 WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
1871                 WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
1872                 HealthCheckBusinessLogic healthCheckBl = webApplicationContext.getBean(HealthCheckBusinessLogic.class);
1873                 return healthCheckBl;
1874         }
1875
1876         @Override
1877         public ComponentInstanceBusinessLogic getComponentInstanceBL() {
1878                 return serviceComponentInstanceBusinessLogic;
1879         }
1880
1881         @Override
1882         public Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, ComponentTypeEnum componentTypeEnum, String userId, String searchText) {
1883
1884                 Either<User, ResponseFormat> resp = validateUserExists(userId, "Get Component Instances", false);
1885                 if (resp.isRight()) {
1886                         return Either.right(resp.right().value());
1887                 }
1888                 Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
1889                 if (getComponentRes.isRight()) {
1890                         ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(getComponentRes.right().value()));
1891                         return Either.right(responseFormat);
1892                 }
1893
1894                 List<ComponentInstance> componentInstances = getComponentRes.left().value().getComponentInstances();
1895                 // componentInstances = componentInstances.stream().filter(instance -> instance.getOriginType().equals(OriginTypeEnum.VF)).collect(Collectors.toList());
1896
1897                 return Either.left(componentInstances);
1898         }
1899
1900         public ICacheMangerOperation getCacheManagerOperation() {
1901                 return cacheManagerOperation;
1902         }
1903
1904         public void setCacheManagerOperation(ICacheMangerOperation cacheManagerOperation) {
1905                 this.cacheManagerOperation = cacheManagerOperation;
1906         }
1907
1908         /**
1909          * updates group instance with new property values in case of successful update of group instance related component instance will be updated with new modification time and related service will be updated with new last update date
1910          * 
1911          * @param modifier
1912          * @param serviceId
1913          * @param componentInstanceId
1914          * @param groupInstanceId
1915          * @param newProperties
1916          * @return
1917          */
1918         public Either<List<GroupInstanceProperty>, ResponseFormat> updateGroupInstancePropertyValues(User modifier, String serviceId, String componentInstanceId, String groupInstanceId, List<GroupInstanceProperty> newProperties) {
1919
1920                 Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
1921                 Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponentRes;
1922                 Component component = null;
1923                 Either<Boolean, ResponseFormat> lockResult = null;
1924                 log.debug("Going to update group instance {} of service {} with new property values. ", groupInstanceId, serviceId);
1925                 try {
1926                         validateUserAndComponentRes = validateUserAndComponent(serviceId, modifier);
1927                         if (validateUserAndComponentRes.isRight()) {
1928                                 log.debug("Cannot update group instance {} of service {} with new property values. Validation failed.  ", groupInstanceId, serviceId);
1929                                 actionResult = Either.right(validateUserAndComponentRes.right().value());
1930                         }
1931                         if (actionResult == null) {
1932                                 component = validateUserAndComponentRes.left().value().getKey();
1933                                 lockResult = lockComponentByName(component.getSystemName(), component, "Update Group Instance on Service");
1934                                 if (lockResult.isRight()) {
1935                                         log.debug("Failed to lock service {}. Response is {}. ", component.getName(), lockResult.right().value().getFormattedMessage());
1936                                         actionResult = Either.right(lockResult.right().value());
1937                                 } else {
1938                                         log.debug("The service with system name {} locked. ", component.getSystemName());
1939                                 }
1940                         }
1941                         if (actionResult == null) {
1942                                 actionResult = validateAndUpdateGroupInstancePropertyValuesAndContainingParents(component, componentInstanceId, groupInstanceId, newProperties);
1943                                 if (actionResult.isRight()) {
1944                                         log.debug("Failed to validate and update group instance {} property values and containing parents. The message is {}. ", groupInstanceId, actionResult.right().value().getFormattedMessage());
1945                                 }
1946                         }
1947                 } catch (Exception e) {
1948                         log.error("Exception occured during update Group Instance property values: {}", e.getMessage(), e);
1949                         actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1950                 } finally {
1951                         if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
1952                                 graphLockOperation.unlockComponentByName(component.getSystemName(), component.getUniqueId(), NodeTypeEnum.Service);
1953                         }
1954                 }
1955                 return actionResult;
1956         }
1957
1958         private Either<List<GroupInstanceProperty>, ResponseFormat> validateAndUpdateGroupInstancePropertyValuesAndContainingParents(Component component, String componentInstanceId, String groupInstanceId, List<GroupInstanceProperty> newProperties) {
1959
1960                 Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
1961                 Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceRes;
1962                 Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeRes;
1963                 ComponentInstance relatedComponentInstance = null;
1964                 GroupInstance oldGroupInstance = null;
1965                 Either<GroupInstance, ResponseFormat> updateGroupInstanceResult = null;
1966                 GroupInstance updatedGroupInstance = null;
1967                 boolean inTransaction = true;
1968                 boolean shouldCloseTransaction = true;
1969                 findGroupInstanceRes = findGroupInstanceOnRelatedComponentInstance(component, componentInstanceId, groupInstanceId);
1970                 if (findGroupInstanceRes.isRight()) {
1971                         log.debug("Group instance {} not found. ", groupInstanceId);
1972                         actionResult = Either.right(findGroupInstanceRes.right().value());
1973                 }
1974                 if (actionResult == null) {
1975                         oldGroupInstance = findGroupInstanceRes.left().value().getValue();
1976                         relatedComponentInstance = findGroupInstanceRes.left().value().getKey();
1977                         updateGroupInstanceResult = groupBusinessLogic.validateAndUpdateGroupInstancePropertyValues(component.getUniqueId(), componentInstanceId, oldGroupInstance, newProperties, inTransaction);
1978                         if (updateGroupInstanceResult.isRight()) {
1979                                 log.debug("Failed to update group instance {} property values. ", oldGroupInstance.getName());
1980                                 actionResult = Either.right(updateGroupInstanceResult.right().value());
1981                         }
1982                 }
1983                 if (actionResult == null) {
1984                         updatedGroupInstance = updateGroupInstanceResult.left().value();
1985                         if (!oldGroupInstance.getModificationTime().equals(updatedGroupInstance.getModificationTime())) {
1986                                 updateParentsModificationTimeRes = updateParentsModificationTimeAndCustomizationUuid(component, relatedComponentInstance, updatedGroupInstance, inTransaction, shouldCloseTransaction);
1987                                 if (updateParentsModificationTimeRes.isRight()) {
1988                                         log.debug("Failed to update modification time. ", oldGroupInstance.getName());
1989                                         actionResult = Either.right(updateParentsModificationTimeRes.right().value());
1990                                 }
1991                         }
1992                 }
1993                 if (actionResult == null) {
1994                         actionResult = Either.left(updatedGroupInstance.convertToGroupInstancesProperties());
1995                 }
1996                 return actionResult;
1997         }
1998
1999         private Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeAndCustomizationUuid(Component component, ComponentInstance relatedComponentInstance, GroupInstance updatedGroupInstance,
2000                         boolean inTranscation, boolean shouldCloseTransaction) {
2001
2002                 Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> actionResult;
2003                 Either<ComponentMetadataData, StorageOperationStatus> serviceMetadataUpdateResult;
2004                 Either<ComponentInstanceData, ResponseFormat> updateComponentInstanceRes = serviceComponentInstanceBusinessLogic.updateComponentInstanceModificationTimeAndCustomizationUuid(relatedComponentInstance, NodeTypeEnum.ResourceInstance,
2005                                 updatedGroupInstance.getModificationTime(), inTranscation);
2006                 if (updateComponentInstanceRes.isRight()) {
2007                         log.debug("Failed to update component instance {} after update of group instance {}. ", relatedComponentInstance.getName(), updatedGroupInstance.getName());
2008                         actionResult = Either.right(updateComponentInstanceRes.right().value());
2009                 } else {
2010                         serviceMetadataUpdateResult = toscaOperationFacade.updateComponentLastUpdateDateOnGraph(component, updatedGroupInstance.getModificationTime());
2011                         if (serviceMetadataUpdateResult.isRight()) {
2012                                 log.debug("Failed to update service {} after update of component instance {} with new property values of group instance {}. ", component.getName(), relatedComponentInstance.getName(), updatedGroupInstance.getName());
2013                                 actionResult = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceMetadataUpdateResult.right().value())));
2014                         } else {
2015                                 actionResult = Either.left(new ImmutablePair<>(serviceMetadataUpdateResult.left().value(), updateComponentInstanceRes.left().value()));
2016                         }
2017                 }
2018                 return actionResult;
2019         }
2020
2021         private Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponent(String serviceId, User modifier) {
2022
2023                 Either<ImmutablePair<Component, User>, ResponseFormat> result = null;
2024                 Either<Component, ResponseFormat> validateComponentExistsRes = null;
2025                 User currUser = null;
2026                 Component component = null;
2027                 Either<User, ResponseFormat> validationUserResult = validateUserIgnoreAudit(modifier, "updateGroupInstancePropertyValues");
2028                 if (validationUserResult.isRight()) {
2029                         log.debug("Failed to validate user with userId for update service {}. ", modifier.getUserId(), serviceId);
2030                         result = Either.right(validationUserResult.right().value());
2031                 }
2032                 if (result == null) {
2033                         currUser = validationUserResult.left().value();
2034                         validateComponentExistsRes = validateComponentExists(serviceId, ComponentTypeEnum.SERVICE, null);
2035                         if (validateComponentExistsRes.isRight()) {
2036                                 log.debug("Failed to validate service existing {}. ", serviceId);
2037                                 result = Either.right(validateComponentExistsRes.right().value());
2038                         }
2039                 }
2040                 if (result == null) {
2041                         component = validateComponentExistsRes.left().value();
2042                         if (!ComponentValidationUtils.canWorkOnComponent(component, currUser.getUserId())) {
2043                                 log.info("Restricted operation for user: {}, on service: {}", currUser.getUserId(), component.getCreatorUserId());
2044                                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
2045                         }
2046                 }
2047                 if (result == null) {
2048                         result = Either.left(new ImmutablePair<>(component, currUser));
2049                 }
2050                 return result;
2051         }
2052
2053         private Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceOnRelatedComponentInstance(Component component, String componentInstanceId, String groupInstanceId) {
2054
2055                 Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> actionResult = null;
2056                 GroupInstance groupInstance = null;
2057                 ComponentInstance foundComponentInstance = findRelatedComponentInstance(component, componentInstanceId);
2058                 if (foundComponentInstance == null) {
2059                         log.debug("Component instance {} not found on service {}. ", componentInstanceId, component.getName());
2060                         actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentInstanceId, "resource instance", "service", component.getName()));
2061                 } else if (!CollectionUtils.isEmpty(foundComponentInstance.getGroupInstances())) {
2062                         groupInstance = foundComponentInstance.getGroupInstances().stream().filter(gi -> gi.getUniqueId().equals(groupInstanceId)).findFirst().orElse(null);
2063                         if (groupInstance == null) {
2064                                 log.debug("Group instance {} not found on component instance {}. ", groupInstanceId, foundComponentInstance.getName());
2065                                 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_INSTANCE_NOT_FOUND_ON_COMPONENT_INSTANCE, groupInstanceId, foundComponentInstance.getName()));
2066                         }
2067                 }
2068                 if (actionResult == null) {
2069                         actionResult = Either.left(new ImmutablePair<>(foundComponentInstance, groupInstance));
2070                 }
2071                 return actionResult;
2072         }
2073
2074         private ComponentInstance findRelatedComponentInstance(Component component, String componentInstanceId) {
2075                 ComponentInstance componentInstance = null;
2076                 if (!CollectionUtils.isEmpty(component.getComponentInstances())) {
2077                         componentInstance = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(componentInstanceId)).findFirst().orElse(null);
2078                 }
2079                 return componentInstance;
2080         }
2081
2082         private Either<User, ResponseFormat> validateUserIgnoreAudit(User modifier, String ecompErrorContext) {
2083                 Either<User, ResponseFormat> result = validateUser(modifier, ecompErrorContext, null, null, false);
2084                 if (result.isLeft()) {
2085                         List<Role> roles = new ArrayList<>();
2086                         roles.add(Role.ADMIN);
2087                         roles.add(Role.DESIGNER);
2088                         Either<Boolean, ResponseFormat> validationRoleRes = validateUserRole(result.left().value(), roles);
2089                         if (validationRoleRes.isRight()) {
2090                                 result = Either.right(validationRoleRes.right().value());
2091                         }
2092                 }
2093                 return result;
2094         }
2095
2096         public Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String serviceId, List<String> dataParamsToReturn) {
2097
2098                 ComponentParametersView paramsToRetuen = new ComponentParametersView(dataParamsToReturn);
2099                 Either<Service, StorageOperationStatus> serviceResultEither = toscaOperationFacade.getToscaElement(serviceId, paramsToRetuen);
2100
2101                 if (serviceResultEither.isRight()) {
2102                         if(serviceResultEither.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
2103                                 log.debug("Failed to found service with id {} ", serviceId);
2104                                 Either.right(componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId));
2105                         }
2106                         
2107                         log.debug("failed to get service by id {} with filters {}", serviceId, dataParamsToReturn.toString());
2108                         return Either.right(componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(serviceResultEither.right().value()), ""));
2109                 }
2110
2111                 Service service = serviceResultEither.left().value();
2112                 UiComponentDataTransfer dataTransfer = UiComponentDataConverter.getUiDataTransferFromServiceByParams(service, dataParamsToReturn);
2113                 return Either.left(dataTransfer);
2114         }
2115 }