2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.openecomp.sdc.be.components.lifecycle;
23 import java.util.EnumMap;
24 import java.util.HashMap;
27 import javax.annotation.PostConstruct;
29 import org.openecomp.sdc.be.components.distribution.engine.ServiceDistributionArtifactsBuilder;
30 import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic;
31 import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic;
32 import org.openecomp.sdc.be.components.impl.ProductBusinessLogic;
33 import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic;
34 import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic;
35 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction.LifecycleChanceActionEnum;
36 import org.openecomp.sdc.be.config.BeEcompErrorManager;
37 import org.openecomp.sdc.be.dao.api.ActionStatus;
38 import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
39 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
40 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
41 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
42 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
43 import org.openecomp.sdc.be.impl.ComponentsUtils;
44 import org.openecomp.sdc.be.model.Component;
45 import org.openecomp.sdc.be.model.LifeCycleTransitionEnum;
46 import org.openecomp.sdc.be.model.LifecycleStateEnum;
47 import org.openecomp.sdc.be.model.Resource;
48 import org.openecomp.sdc.be.model.Service;
49 import org.openecomp.sdc.be.model.User;
50 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElement;
51 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaElementLifecycleOperation;
52 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
53 import org.openecomp.sdc.be.model.jsontitan.utils.ModelConverter;
54 import org.openecomp.sdc.be.model.operations.api.ICacheMangerOperation;
55 import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation;
56 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
57 import org.openecomp.sdc.be.model.operations.impl.CapabilityOperation;
58 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
59 import org.openecomp.sdc.be.tosca.ToscaExportHandler;
60 import org.openecomp.sdc.common.api.Constants;
61 import org.openecomp.sdc.common.config.EcompErrorName;
62 import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum;
63 import org.openecomp.sdc.common.util.ValidationUtils;
64 import org.openecomp.sdc.exception.ResponseFormat;
65 import org.slf4j.Logger;
66 import org.slf4j.LoggerFactory;
67 import org.springframework.beans.factory.annotation.Autowired;
69 import fj.data.Either;
71 @org.springframework.stereotype.Component("lifecycleBusinessLogic")
72 public class LifecycleBusinessLogic {
74 private static final String COMMENT = "comment";
77 private IGraphLockOperation graphLockOperation = null;
80 private ArtifactsBusinessLogic artifactsBusinessLogic;
83 private TitanDao titanDao;
86 private CapabilityOperation capabilityOperation;
88 private static Logger log = LoggerFactory.getLogger(LifecycleBusinessLogic.class.getName());
90 @javax.annotation.Resource
91 private ComponentsUtils componentUtils;
93 @javax.annotation.Resource
94 private ToscaElementLifecycleOperation lifecycleOperation;
95 @javax.annotation.Resource
96 ArtifactsBusinessLogic artifactsManager;
98 @javax.annotation.Resource
99 private ServiceDistributionArtifactsBuilder serviceDistributionArtifactsBuilder;
101 @javax.annotation.Resource
102 private ServiceBusinessLogic serviceBusinessLogic;
104 @javax.annotation.Resource
105 private ResourceBusinessLogic resourceBusinessLogic;
107 @javax.annotation.Resource
108 private ProductBusinessLogic productBusinessLogic;
111 private ToscaExportHandler toscaExportUtils;
114 ICacheMangerOperation cacheManagerOperation;
117 ToscaOperationFacade toscaOperationFacade;
119 private Map<String, LifeCycleTransition> stateTransitions;
120 private static volatile boolean isInitialized = false;
125 if (!isInitialized) {
126 synchronized (this) {
127 if (!isInitialized) {
128 initStateOperations();
129 isInitialized = true;
135 private void initStateOperations() {
136 stateTransitions = new HashMap<String, LifeCycleTransition>();
138 LifeCycleTransition checkoutOp = new CheckoutTransition(componentUtils, lifecycleOperation, toscaOperationFacade, titanDao);
139 stateTransitions.put(checkoutOp.getName().name(), checkoutOp);
141 UndoCheckoutTransition undoCheckoutOp = new UndoCheckoutTransition(componentUtils, lifecycleOperation, toscaOperationFacade, titanDao);
142 undoCheckoutOp.setArtifactsBusinessLogic(artifactsBusinessLogic);
143 stateTransitions.put(undoCheckoutOp.getName().name(), undoCheckoutOp);
145 LifeCycleTransition checkinOp = new CheckinTransition(componentUtils, lifecycleOperation, toscaOperationFacade, titanDao);
146 stateTransitions.put(checkinOp.getName().name(), checkinOp);
148 LifeCycleTransition certificationRequest = new CertificationRequestTransition(componentUtils, lifecycleOperation, serviceDistributionArtifactsBuilder, serviceBusinessLogic, capabilityOperation, toscaExportUtils, toscaOperationFacade, titanDao);
149 stateTransitions.put(certificationRequest.getName().name(), certificationRequest);
151 LifeCycleTransition startCertification = new StartCertificationTransition(componentUtils, lifecycleOperation, toscaOperationFacade, titanDao);
152 stateTransitions.put(startCertification.getName().name(), startCertification);
154 LifeCycleTransition failCertification = new CertificationChangeTransition(LifeCycleTransitionEnum.FAIL_CERTIFICATION, componentUtils, lifecycleOperation, toscaOperationFacade, titanDao);
155 stateTransitions.put(failCertification.getName().name(), failCertification);
157 LifeCycleTransition cancelCertification = new CertificationChangeTransition(LifeCycleTransitionEnum.CANCEL_CERTIFICATION, componentUtils, lifecycleOperation, toscaOperationFacade, titanDao);
158 stateTransitions.put(cancelCertification.getName().name(), cancelCertification);
160 CertificationChangeTransition successCertification = new CertificationChangeTransition(LifeCycleTransitionEnum.CERTIFY, componentUtils, lifecycleOperation, toscaOperationFacade, titanDao);
161 successCertification.setArtifactsManager(artifactsBusinessLogic);
162 stateTransitions.put(successCertification.getName().name(), successCertification);
165 public LifeCycleTransition getLifecycleTransition(LifeCycleTransitionEnum transitionEnum) {
166 return stateTransitions.get(transitionEnum.name());
169 public Either<Service, ResponseFormat> changeServiceState(String serviceId, User modifier, LifeCycleTransitionEnum transitionEnum, LifecycleChangeInfoWithAction changeInfo, boolean inTransaction, boolean needLock) {
170 return (Either<Service, ResponseFormat>) changeComponentState(ComponentTypeEnum.SERVICE, serviceId, modifier, transitionEnum, changeInfo, inTransaction, needLock);
173 // TODO: rhalili - should use changeComponentState when possible
174 public Either<Resource, ResponseFormat> changeState(String resourceId, User modifier, LifeCycleTransitionEnum transitionEnum, LifecycleChangeInfoWithAction changeInfo, boolean inTransaction, boolean needLock) {
175 return (Either<Resource, ResponseFormat>) changeComponentState(ComponentTypeEnum.RESOURCE, resourceId, modifier, transitionEnum, changeInfo, inTransaction, needLock);
178 private boolean isComponentVFCMT(Component component, ComponentTypeEnum componentType){
179 if (componentType.equals(ComponentTypeEnum.RESOURCE)){
180 ResourceTypeEnum resourceType = ((ResourceMetadataDataDefinition)component.getComponentMetadataDefinition().getMetadataDataDefinition()).getResourceType();
181 if (resourceType.equals(ResourceTypeEnum.VFCMT)){
188 public Either<? extends Component, ResponseFormat> changeComponentState(ComponentTypeEnum componentType, String componentId, User modifier, LifeCycleTransitionEnum transitionEnum, LifecycleChangeInfoWithAction changeInfo, boolean inTransaction,
191 LifeCycleTransition lifeCycleTransition = stateTransitions.get(transitionEnum.name());
192 if (lifeCycleTransition == null) {
193 log.debug("state operation is not valid. operations allowed are: {}", LifeCycleTransitionEnum.valuesAsString());
194 ResponseFormat error = componentUtils.getInvalidContentErrorAndAudit(modifier, AuditingActionEnum.CHECKOUT_RESOURCE);
195 return Either.right(error);
197 Component component = null;
198 log.info("get resource from graph");
199 ResponseFormat errorResponse;
201 Either<? extends Component, ResponseFormat> eitherResourceResponse = getComponentForChange(componentType, componentId, modifier, lifeCycleTransition, changeInfo);
202 if (eitherResourceResponse.isRight()) {
203 return eitherResourceResponse;
205 component = eitherResourceResponse.left().value();
206 String resourceCurrVersion = component.getVersion();
207 LifecycleStateEnum resourceCurrState = component.getLifecycleState();
210 if (inTransaction == false && needLock) {
211 log.info("lock component {}", componentId);
212 Either<Boolean, ResponseFormat> eitherLockResource = lockComponent(componentType, component);
213 if (eitherLockResource.isRight()) {
214 errorResponse = eitherLockResource.right().value();
215 componentUtils.auditComponent(errorResponse, modifier, component, resourceCurrState.name(), resourceCurrVersion, lifeCycleTransition.getAuditingAction(), componentType, null);
216 log.error("lock component {} failed", componentId);
217 return Either.right(errorResponse);
219 log.info("after lock component {}", componentId);
222 Either<String, ResponseFormat> commentValidationResult = validateComment(changeInfo, transitionEnum);
223 if (commentValidationResult.isRight()) {
224 errorResponse = commentValidationResult.right().value();
225 EnumMap<AuditingFieldsKeysEnum, Object> auditingFields = new EnumMap<>(AuditingFieldsKeysEnum.class);
226 auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_COMMENT, changeInfo.getUserRemarks());
227 componentUtils.auditComponent(errorResponse, modifier, component, resourceCurrState.name(), resourceCurrVersion, lifeCycleTransition.getAuditingAction(), componentType, auditingFields);
228 return Either.right(errorResponse);
230 changeInfo.setUserRemarks(commentValidationResult.left().value());
231 log.info("after validate component");
232 Either<Boolean, ResponseFormat> validateHighestVersion = validateHighestVersion(modifier, lifeCycleTransition, component, resourceCurrVersion, componentType);
233 if (validateHighestVersion.isRight()) {
234 return Either.right(validateHighestVersion.right().value());
236 log.info("after validate Highest Version");
237 if (isComponentVFCMT(component,componentType)){
238 Either<? extends Component, ResponseFormat> changeVFCMTStateResponse = changeVFCMTState(componentType, modifier, transitionEnum, changeInfo, inTransaction, component);
239 if (changeVFCMTStateResponse.isRight()){
240 return changeVFCMTStateResponse;
244 return changeState(component, lifeCycleTransition, componentType, modifier, changeInfo, inTransaction);
246 log.info("unlock component {}", componentId);
247 if (inTransaction == false && needLock && component != null) {
248 component.setUniqueId(componentId);
249 NodeTypeEnum nodeType = componentType.getNodeType();
250 log.info("During change state, another component {} has been created/updated", componentId);
251 graphLockOperation.unlockComponent(componentId, nodeType);
259 * special case for certification of VFCMT - VFCMT can be certified by Designer or Tester right after checkin
260 * in case the operation "submit for test" / "start testing" is done to "VFCMT" - please return error 400
262 private Either<? extends Component, ResponseFormat> changeVFCMTState(ComponentTypeEnum componentType, User modifier,
263 LifeCycleTransitionEnum transitionEnum, LifecycleChangeInfoWithAction changeInfo, boolean inTransaction,
264 Component component) {
265 LifecycleStateEnum oldState = component.getLifecycleState();
266 if (transitionEnum.equals(LifeCycleTransitionEnum.START_CERTIFICATION) ||
267 transitionEnum.equals(LifeCycleTransitionEnum.CERTIFICATION_REQUEST)){
268 return Either.right(componentUtils.getResponseFormat(
269 ActionStatus.RESOURCE_VFCMT_LIFECYCLE_STATE_NOT_VALID, transitionEnum.getDisplayName()));
270 } //certify is done directly from checkin
271 else if (transitionEnum.equals(LifeCycleTransitionEnum.CERTIFY) && oldState.equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN)){
272 //we will call for submit for testing first and then for certify
273 Either<? extends Component, ResponseFormat> actionResponse = changeState(component,
274 stateTransitions.get(LifeCycleTransitionEnum.CERTIFICATION_REQUEST.name()),
275 componentType, modifier, changeInfo, inTransaction);
276 if (actionResponse.isRight()) {
277 return actionResponse;
279 actionResponse = changeState(component,
280 stateTransitions.get(LifeCycleTransitionEnum.START_CERTIFICATION.name()),
281 componentType, modifier, changeInfo, inTransaction);
282 if (actionResponse.isRight()) {
283 return actionResponse;
286 return Either.left(null);
289 private Either<? extends Component, ResponseFormat> changeState(Component component, LifeCycleTransition lifeCycleTransition,
290 ComponentTypeEnum componentType, User modifier, LifecycleChangeInfoWithAction changeInfo,boolean inTransaction){
291 ResponseFormat errorResponse;
293 LifecycleStateEnum oldState = component.getLifecycleState();
294 String resourceCurrVersion = component.getVersion();
295 ComponentBusinessLogic bl = getComponentBL(componentType);
297 Either<User, ResponseFormat> ownerResult = lifeCycleTransition.getComponentOwner(component, componentType, inTransaction);
298 if (ownerResult.isRight()) {
299 return Either.right(ownerResult.right().value());
301 User owner = ownerResult.left().value();
302 log.info("owner of resource {} is {}", component.getUniqueId(), owner.getUserId());
304 Either<Boolean, ResponseFormat> stateValidationResult = lifeCycleTransition.validateBeforeTransition(component, componentType, modifier, owner, oldState, changeInfo);
305 if (stateValidationResult.isRight()) {
306 log.error("Failed to validateBeforeTransition");
307 errorResponse = stateValidationResult.right().value();
308 EnumMap<AuditingFieldsKeysEnum, Object> auditingFields = new EnumMap<>(AuditingFieldsKeysEnum.class);
309 auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_COMMENT, changeInfo.getUserRemarks());
310 componentUtils.auditComponent(errorResponse, modifier, component, oldState.name(), resourceCurrVersion, lifeCycleTransition.getAuditingAction(), componentType, auditingFields);
311 return Either.right(errorResponse);
314 Either<? extends Component, ResponseFormat> operationResult = lifeCycleTransition.changeState(componentType, component, bl, modifier, owner, false, inTransaction);
316 if (operationResult.isRight()) {
317 errorResponse = operationResult.right().value();
318 log.info("audit before sending error response");
319 componentUtils.auditComponentAdmin(errorResponse, modifier, component, oldState.name(), resourceCurrVersion, lifeCycleTransition.getAuditingAction(), componentType);
321 return Either.right(errorResponse);
323 Component resourceAfterOperation = operationResult.left().value();
324 EnumMap<AuditingFieldsKeysEnum, Object> auditingFields = new EnumMap<AuditingFieldsKeysEnum, Object>(AuditingFieldsKeysEnum.class);
325 auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_COMMENT, changeInfo.getUserRemarks());
326 componentUtils.auditComponent(componentUtils.getResponseFormat(ActionStatus.OK), modifier, resourceAfterOperation, oldState.name(), resourceCurrVersion, lifeCycleTransition.getAuditingAction(), componentType, auditingFields);
327 return operationResult;
331 private Either<? extends Component, ResponseFormat> getComponentForChange(ComponentTypeEnum componentType, String componentId, User modifier, LifeCycleTransition lifeCycleTransition, LifecycleChangeInfoWithAction changeInfo) {
333 Either<? extends Component, StorageOperationStatus> eitherResourceResponse = toscaOperationFacade.getToscaElement(componentId);
335 ResponseFormat errorResponse;
336 if (eitherResourceResponse.isRight()) {
337 ActionStatus actionStatus = componentUtils.convertFromStorageResponse(eitherResourceResponse.right().value(), componentType);
338 errorResponse = componentUtils.getResponseFormat(actionStatus, Constants.EMPTY_STRING);
339 log.debug("audit before sending response");
340 EnumMap<AuditingFieldsKeysEnum, Object> auditingFields = new EnumMap<AuditingFieldsKeysEnum, Object>(AuditingFieldsKeysEnum.class);
341 auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_COMMENT, changeInfo.getUserRemarks());
342 auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, componentId);
343 componentUtils.auditComponent(errorResponse, modifier, null, Constants.EMPTY_STRING, Constants.EMPTY_STRING, lifeCycleTransition.getAuditingAction(), componentType, auditingFields);
345 return Either.right(errorResponse);
347 return Either.left(eitherResourceResponse.left().value());
350 private Either<Boolean, ResponseFormat> validateHighestVersion(User modifier, LifeCycleTransition lifeCycleTransition, Resource resource, String resourceCurrVersion) {
351 ResponseFormat errorResponse;
352 if (!resource.isHighestVersion()) {
353 log.debug("resource version {} is not the last version of resource {}", resource.getVersion(), resource.getName());
354 errorResponse = componentUtils.getResponseFormat(ActionStatus.COMPONENT_HAS_NEWER_VERSION, resource.getName(), ComponentTypeEnum.RESOURCE.name().toLowerCase());
355 componentUtils.auditResource(errorResponse, modifier, resource, resource.getLifecycleState().name(), resourceCurrVersion, lifeCycleTransition.getAuditingAction(), null);
356 return Either.right(errorResponse);
358 return Either.left(true);
361 private Either<Boolean, ResponseFormat> validateResourceNotDeleted(User modifier, LifeCycleTransition lifeCycleTransition, Resource resource, String resourceCurrVersion) {
363 ResponseFormat errorResponse;
364 if ((resource.getIsDeleted() != null) && (resource.getIsDeleted() == true)) {
365 ActionStatus actionStatus = ActionStatus.RESOURCE_NOT_FOUND;
366 errorResponse = componentUtils.getResponseFormatByResource(actionStatus, resource.getName());
367 log.debug("resource {} {} is marked for delete", resource.getName(), resource.getVersion());
368 componentUtils.auditResource(errorResponse, modifier, null, "", "", lifeCycleTransition.getAuditingAction(), null);
370 return Either.right(errorResponse);
372 return Either.left(true);
375 private Either<Boolean, ResponseFormat> validateHighestVersion(User modifier, LifeCycleTransition lifeCycleTransition, Component component, String resourceCurrVersion, ComponentTypeEnum componentType) {
376 ResponseFormat errorResponse;
377 if (!component.isHighestVersion()) {
378 log.debug("Component version {} is not the last version of component {}", component.getComponentMetadataDefinition().getMetadataDataDefinition().getVersion(),
379 component.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
380 errorResponse = componentUtils.getResponseFormat(ActionStatus.COMPONENT_HAS_NEWER_VERSION, component.getComponentMetadataDefinition().getMetadataDataDefinition().getName(), componentType.getValue().toLowerCase());
381 componentUtils.auditComponentAdmin(errorResponse, modifier, component, component.getLifecycleState().name(), resourceCurrVersion, lifeCycleTransition.getAuditingAction(), componentType);
382 return Either.right(errorResponse);
384 return Either.left(true);
387 private Either<Boolean, ResponseFormat> lockComponent(ComponentTypeEnum componentType, Component component) {
388 NodeTypeEnum nodeType = componentType.getNodeType();
389 StorageOperationStatus lockResourceStatus = graphLockOperation.lockComponent(component.getUniqueId(), nodeType);
391 if (lockResourceStatus.equals(StorageOperationStatus.OK)) {
392 return Either.left(true);
394 ActionStatus actionStatus = componentUtils.convertFromStorageResponse(lockResourceStatus);
395 ResponseFormat responseFormat = componentUtils.getResponseFormat(actionStatus, component.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
396 return Either.right(responseFormat);
401 private Either<String, ResponseFormat> validateComment(LifecycleChangeInfoWithAction changeInfo, LifeCycleTransitionEnum transitionEnum) {
402 String comment = changeInfo.getUserRemarks();
403 if (LifeCycleTransitionEnum.CANCEL_CERTIFICATION == transitionEnum || LifeCycleTransitionEnum.CERTIFY == transitionEnum || LifeCycleTransitionEnum.FAIL_CERTIFICATION == transitionEnum || LifeCycleTransitionEnum.CHECKIN == transitionEnum
404 || LifeCycleTransitionEnum.CERTIFICATION_REQUEST == transitionEnum
408 if (!ValidationUtils.validateStringNotEmpty(comment)) {
409 log.debug("user comment cannot be empty or null.");
410 ResponseFormat errorResponse = componentUtils.getResponseFormat(ActionStatus.MISSING_DATA, COMMENT);
411 return Either.right(errorResponse);
414 comment = ValidationUtils.removeNoneUtf8Chars(comment);
415 comment = ValidationUtils.removeHtmlTags(comment);
416 comment = ValidationUtils.normaliseWhitespace(comment);
417 comment = ValidationUtils.stripOctets(comment);
419 if (!ValidationUtils.validateLength(comment, ValidationUtils.COMMENT_MAX_LENGTH)) {
420 log.debug("user comment exceeds limit.");
421 return Either.right(componentUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, COMMENT, String.valueOf(ValidationUtils.COMMENT_MAX_LENGTH)));
423 if (!ValidationUtils.validateIsEnglish(comment)) {
424 return Either.right(componentUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
427 return Either.left(comment);
430 private ComponentBusinessLogic getComponentBL(ComponentTypeEnum componentTypeEnum) {
431 ComponentBusinessLogic businessLogic;
432 switch (componentTypeEnum) {
434 businessLogic = this.resourceBusinessLogic;
438 businessLogic = this.serviceBusinessLogic;
442 businessLogic = this.productBusinessLogic;
447 BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "getComponentBL");
448 throw new IllegalArgumentException("Illegal component type:" + componentTypeEnum.getValue());
451 return businessLogic;
454 public Either<Component, ResponseFormat> getLatestComponentByUuid(ComponentTypeEnum componentTypeEnum, String uuid) {
456 Either<Component, StorageOperationStatus> latestVersionEither = toscaOperationFacade.getLatestComponentByUuid(uuid);
458 if (latestVersionEither.isRight()) {
460 return Either.right(componentUtils.getResponseFormat(componentUtils.convertFromStorageResponse(latestVersionEither.right().value(), componentTypeEnum), uuid));
463 Component latestComponent = latestVersionEither.left().value();
465 return Either.left(latestComponent);
468 public Either<Resource, ResponseFormat> forceResourceCertification(Resource resource, User user, LifecycleChangeInfoWithAction lifecycleChangeInfo, boolean inTransaction, boolean needLock) {
469 Either<Resource, ResponseFormat> result = null;
470 Either<ToscaElement, StorageOperationStatus> certifyResourceRes = null;
471 if(lifecycleChangeInfo.getAction() != LifecycleChanceActionEnum.CREATE_FROM_CSAR){
472 log.debug("Force certification is not allowed for the action {}. ", lifecycleChangeInfo.getAction().name());
473 result = Either.right(componentUtils.getResponseFormat(ActionStatus.NOT_ALLOWED));
476 if(result == null && !inTransaction && needLock){
477 log.info("lock component {}", resource.getUniqueId());
478 Either<Boolean, ResponseFormat> eitherLockResource = lockComponent(resource.getComponentType(), resource);
479 if (eitherLockResource.isRight()) {
480 log.error("lock component {} failed", resource.getUniqueId());
481 result = Either.right(eitherLockResource.right().value());
483 log.info("after lock component {}", resource.getUniqueId());
487 certifyResourceRes = lifecycleOperation.forceCerificationOfToscaElement(resource.getUniqueId(), user.getUserId(), user.getUserId(), resource.getVersion());
488 if (certifyResourceRes.isRight()) {
489 StorageOperationStatus status = certifyResourceRes.right().value();
490 log.debug("Failed to perform a force certification of resource {}. The status is {}. ", resource.getName(), status);
491 result = Either.right(componentUtils.getResponseFormatByResource(componentUtils.convertFromStorageResponse(status), resource));
495 result = Either.left(ModelConverter.convertFromToscaElement(certifyResourceRes.left().value()));
498 log.info("unlock component {}", resource.getUniqueId());
499 if (!inTransaction) {
506 NodeTypeEnum nodeType = resource.getComponentType().getNodeType();
507 log.info("During change state, another component {} has been created/updated", resource.getUniqueId());
508 graphLockOperation.unlockComponent(resource.getUniqueId(), nodeType);