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 fj.data.Either;
24 import org.openecomp.sdc.be.components.distribution.engine.ServiceDistributionArtifactsBuilder;
25 import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic;
26 import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic;
27 import org.openecomp.sdc.be.components.impl.ProductBusinessLogic;
28 import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic;
29 import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic;
30 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction.LifecycleChanceActionEnum;
31 import org.openecomp.sdc.be.dao.api.ActionStatus;
32 import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
33 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
34 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
35 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
36 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
37 import org.openecomp.sdc.be.impl.ComponentsUtils;
38 import org.openecomp.sdc.be.model.Component;
39 import org.openecomp.sdc.be.model.LifeCycleTransitionEnum;
40 import org.openecomp.sdc.be.model.LifecycleStateEnum;
41 import org.openecomp.sdc.be.model.Resource;
42 import org.openecomp.sdc.be.model.Service;
43 import org.openecomp.sdc.be.model.User;
44 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElement;
45 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaElementLifecycleOperation;
46 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
47 import org.openecomp.sdc.be.model.jsontitan.utils.ModelConverter;
48 import org.openecomp.sdc.be.model.operations.api.ICacheMangerOperation;
49 import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation;
50 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
51 import org.openecomp.sdc.be.model.operations.impl.CapabilityOperation;
52 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
53 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceAuditData;
54 import org.openecomp.sdc.be.tosca.ToscaExportHandler;
55 import org.openecomp.sdc.common.api.Constants;
56 import org.openecomp.sdc.common.util.ValidationUtils;
57 import org.openecomp.sdc.exception.ResponseFormat;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
60 import org.springframework.beans.factory.annotation.Autowired;
62 import javax.annotation.PostConstruct;
63 import java.util.HashMap;
66 @org.springframework.stereotype.Component("lifecycleBusinessLogic")
67 public class LifecycleBusinessLogic {
69 private static final String COMMENT = "comment";
72 private IGraphLockOperation graphLockOperation = null;
75 private ArtifactsBusinessLogic artifactsBusinessLogic;
78 private TitanDao titanDao;
81 private CapabilityOperation capabilityOperation;
83 private static final Logger log = LoggerFactory.getLogger(LifecycleBusinessLogic.class);
85 @javax.annotation.Resource
86 private ComponentsUtils componentUtils;
88 @javax.annotation.Resource
89 private ToscaElementLifecycleOperation lifecycleOperation;
90 @javax.annotation.Resource
91 ArtifactsBusinessLogic artifactsManager;
93 @javax.annotation.Resource
94 private ServiceDistributionArtifactsBuilder serviceDistributionArtifactsBuilder;
96 @javax.annotation.Resource
97 private ServiceBusinessLogic serviceBusinessLogic;
99 @javax.annotation.Resource
100 private ResourceBusinessLogic resourceBusinessLogic;
102 @javax.annotation.Resource
103 private ProductBusinessLogic productBusinessLogic;
106 private ToscaExportHandler toscaExportUtils;
109 ICacheMangerOperation cacheManagerOperation;
112 ToscaOperationFacade toscaOperationFacade;
114 private Map<String, LifeCycleTransition> stateTransitions;
115 private static volatile boolean isInitialized = false;
120 if (!isInitialized) {
121 synchronized (this) {
122 if (!isInitialized) {
123 initStateOperations();
124 isInitialized = true;
130 private void initStateOperations() {
131 stateTransitions = new HashMap<String, LifeCycleTransition>();
133 LifeCycleTransition checkoutOp = new CheckoutTransition(componentUtils, lifecycleOperation, toscaOperationFacade, titanDao);
134 stateTransitions.put(checkoutOp.getName().name(), checkoutOp);
136 UndoCheckoutTransition undoCheckoutOp = new UndoCheckoutTransition(componentUtils, lifecycleOperation, toscaOperationFacade, titanDao);
137 undoCheckoutOp.setArtifactsBusinessLogic(artifactsBusinessLogic);
138 stateTransitions.put(undoCheckoutOp.getName().name(), undoCheckoutOp);
140 LifeCycleTransition checkinOp = new CheckinTransition(componentUtils, lifecycleOperation, toscaOperationFacade, titanDao);
141 stateTransitions.put(checkinOp.getName().name(), checkinOp);
143 LifeCycleTransition certificationRequest = new CertificationRequestTransition(componentUtils, lifecycleOperation, serviceDistributionArtifactsBuilder, serviceBusinessLogic, capabilityOperation, toscaExportUtils, toscaOperationFacade, titanDao);
144 stateTransitions.put(certificationRequest.getName().name(), certificationRequest);
146 LifeCycleTransition startCertification = new StartCertificationTransition(componentUtils, lifecycleOperation, toscaOperationFacade, titanDao);
147 stateTransitions.put(startCertification.getName().name(), startCertification);
149 LifeCycleTransition failCertification = new CertificationChangeTransition(LifeCycleTransitionEnum.FAIL_CERTIFICATION, componentUtils, lifecycleOperation, toscaOperationFacade, titanDao);
150 stateTransitions.put(failCertification.getName().name(), failCertification);
152 LifeCycleTransition cancelCertification = new CertificationChangeTransition(LifeCycleTransitionEnum.CANCEL_CERTIFICATION, componentUtils, lifecycleOperation, toscaOperationFacade, titanDao);
153 stateTransitions.put(cancelCertification.getName().name(), cancelCertification);
155 CertificationChangeTransition successCertification = new CertificationChangeTransition(LifeCycleTransitionEnum.CERTIFY, componentUtils, lifecycleOperation, toscaOperationFacade, titanDao);
156 successCertification.setArtifactsManager(artifactsBusinessLogic);
157 stateTransitions.put(successCertification.getName().name(), successCertification);
160 public LifeCycleTransition getLifecycleTransition(LifeCycleTransitionEnum transitionEnum) {
161 return stateTransitions.get(transitionEnum.name());
164 public Either<Service, ResponseFormat> changeServiceState(String serviceId, User modifier, LifeCycleTransitionEnum transitionEnum, LifecycleChangeInfoWithAction changeInfo, boolean inTransaction, boolean needLock) {
165 return (Either<Service, ResponseFormat>) changeComponentState(ComponentTypeEnum.SERVICE, serviceId, modifier, transitionEnum, changeInfo, inTransaction, needLock);
168 // TODO: rhalili - should use changeComponentState when possible
169 public Either<Resource, ResponseFormat> changeState(String resourceId, User modifier, LifeCycleTransitionEnum transitionEnum, LifecycleChangeInfoWithAction changeInfo, boolean inTransaction, boolean needLock) {
170 return (Either<Resource, ResponseFormat>) changeComponentState(ComponentTypeEnum.RESOURCE, resourceId, modifier, transitionEnum, changeInfo, inTransaction, needLock);
173 private boolean isComponentVFCMT(Component component, ComponentTypeEnum componentType){
174 if (componentType.equals(ComponentTypeEnum.RESOURCE)){
175 ResourceTypeEnum resourceType = ((ResourceMetadataDataDefinition)component.getComponentMetadataDefinition().getMetadataDataDefinition()).getResourceType();
176 if (resourceType.equals(ResourceTypeEnum.VFCMT)){
183 public Either<? extends Component, ResponseFormat> changeComponentState(ComponentTypeEnum componentType, String componentId, User modifier, LifeCycleTransitionEnum transitionEnum, LifecycleChangeInfoWithAction changeInfo, boolean inTransaction,
186 LifeCycleTransition lifeCycleTransition = stateTransitions.get(transitionEnum.name());
187 if (lifeCycleTransition == null) {
188 log.debug("state operation is not valid. operations allowed are: {}", LifeCycleTransitionEnum.valuesAsString());
189 ResponseFormat error = componentUtils.getInvalidContentErrorAndAudit(modifier,componentId, AuditingActionEnum.CHECKOUT_RESOURCE);
190 return Either.right(error);
192 Component component = null;
193 log.info("get resource from graph");
194 ResponseFormat errorResponse;
196 Either<? extends Component, ResponseFormat> eitherResourceResponse = getComponentForChange(componentType, componentId, modifier, lifeCycleTransition, changeInfo);
197 if (eitherResourceResponse.isRight()) {
198 return eitherResourceResponse;
200 component = eitherResourceResponse.left().value();
201 String resourceCurrVersion = component.getVersion();
202 LifecycleStateEnum resourceCurrState = component.getLifecycleState();
205 if (!inTransaction && needLock) {
206 log.info("lock component {}", componentId);
207 Either<Boolean, ResponseFormat> eitherLockResource = lockComponent(componentType, component);
208 if (eitherLockResource.isRight()) {
209 errorResponse = eitherLockResource.right().value();
210 componentUtils.auditComponent(errorResponse, modifier, component, lifeCycleTransition.getAuditingAction(), componentType,
211 ResourceAuditData.newBuilder().state(resourceCurrState.name()).version(resourceCurrVersion).build());
213 log.error("lock component {} failed", componentId);
214 return Either.right(errorResponse);
216 log.debug("after lock component {}", componentId);
219 Either<String, ResponseFormat> commentValidationResult = validateComment(changeInfo, transitionEnum);
220 if (commentValidationResult.isRight()) {
221 errorResponse = commentValidationResult.right().value();
222 componentUtils.auditComponent(errorResponse, modifier, component, lifeCycleTransition.getAuditingAction(), componentType,
223 ResourceAuditData.newBuilder()
224 .state(resourceCurrState.name()).version(resourceCurrVersion).build(), changeInfo.getUserRemarks());
225 return Either.right(errorResponse);
227 changeInfo.setUserRemarks(commentValidationResult.left().value());
228 log.debug("after validate component");
229 Either<Boolean, ResponseFormat> validateHighestVersion = validateHighestVersion(modifier, lifeCycleTransition, component, resourceCurrVersion, componentType);
230 if (validateHighestVersion.isRight()) {
231 return Either.right(validateHighestVersion.right().value());
233 log.debug("after validate Highest Version");
234 if (isComponentVFCMT(component,componentType)){
235 Either<? extends Component, ResponseFormat> changeVFCMTStateResponse = changeVFCMTState(componentType, modifier, transitionEnum, changeInfo, true, component);
236 if (changeVFCMTStateResponse.isRight()){
237 return changeVFCMTStateResponse;
239 component = changeVFCMTStateResponse.left().value();
241 return changeState(component, lifeCycleTransition, componentType, modifier, changeInfo, inTransaction);
243 component.setUniqueId(componentId);
244 if (!inTransaction && needLock) {
245 log.info("unlock component {}", componentId);
246 NodeTypeEnum nodeType = componentType.getNodeType();
247 log.info("During change state, another component {} has been created/updated", componentId);
248 graphLockOperation.unlockComponent(componentId, nodeType);
256 * special case for certification of VFCMT - VFCMT can be certified by Designer or Tester right after checkin
257 * in case the operation "submit for test" / "start testing" is done to "VFCMT" - please return error 400
259 private Either<? extends Component, ResponseFormat> changeVFCMTState(ComponentTypeEnum componentType, User modifier,
260 LifeCycleTransitionEnum transitionEnum, LifecycleChangeInfoWithAction changeInfo, boolean inTransaction,
261 Component component) {
262 LifecycleStateEnum oldState = component.getLifecycleState();
263 Component updatedComponent = component;
264 if (transitionEnum.equals(LifeCycleTransitionEnum.START_CERTIFICATION) ||
265 transitionEnum.equals(LifeCycleTransitionEnum.CERTIFICATION_REQUEST)){
266 return Either.right(componentUtils.getResponseFormat(
267 ActionStatus.RESOURCE_VFCMT_LIFECYCLE_STATE_NOT_VALID, transitionEnum.getDisplayName()));
268 } //certify is done directly from checkin
269 else if (transitionEnum.equals(LifeCycleTransitionEnum.CERTIFY) && oldState.equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN)){
270 //we will call for submit for testing first and then for certify
271 Either<? extends Component, ResponseFormat> actionResponse = changeState(component,
272 stateTransitions.get(LifeCycleTransitionEnum.CERTIFICATION_REQUEST.name()),
273 componentType, modifier, changeInfo, inTransaction);
274 if (actionResponse.isRight()) {
275 return actionResponse;
277 updatedComponent = actionResponse.left().value();
278 actionResponse = changeState(updatedComponent,
279 stateTransitions.get(LifeCycleTransitionEnum.START_CERTIFICATION.name()),
280 componentType, modifier, changeInfo, inTransaction);
281 if (actionResponse.isRight()) {
282 return actionResponse;
284 updatedComponent = actionResponse.left().value();
287 return Either.left(updatedComponent);
290 private Either<? extends Component, ResponseFormat> changeState(Component component, LifeCycleTransition lifeCycleTransition,
291 ComponentTypeEnum componentType, User modifier, LifecycleChangeInfoWithAction changeInfo,boolean inTransaction){
292 ResponseFormat errorResponse;
294 LifecycleStateEnum oldState = component.getLifecycleState();
295 String resourceCurrVersion = component.getVersion();
296 ComponentBusinessLogic bl = getComponentBL(componentType);
298 Either<User, ResponseFormat> ownerResult = lifeCycleTransition.getComponentOwner(component, componentType, inTransaction);
299 if (ownerResult.isRight()) {
300 return Either.right(ownerResult.right().value());
302 User owner = ownerResult.left().value();
303 log.info("owner of resource {} is {}", component.getUniqueId(), owner.getUserId());
305 Either<Boolean, ResponseFormat> stateValidationResult = lifeCycleTransition.validateBeforeTransition(component, componentType, modifier, owner, oldState, changeInfo);
306 if (stateValidationResult.isRight()) {
307 log.error("Failed to validateBeforeTransition");
308 errorResponse = stateValidationResult.right().value();
309 componentUtils.auditComponent(errorResponse, modifier, component, lifeCycleTransition.getAuditingAction(), componentType,
310 ResourceAuditData.newBuilder().version(resourceCurrVersion).state(oldState.name()).build(), changeInfo.getUserRemarks());
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, lifeCycleTransition.getAuditingAction(), componentType,
320 ResourceAuditData.newBuilder().state(oldState.name()).version(resourceCurrVersion).build());
322 return Either.right(errorResponse);
324 Component resourceAfterOperation = operationResult.left().value();
325 componentUtils.auditComponent(componentUtils.getResponseFormat(ActionStatus.OK), modifier, resourceAfterOperation, lifeCycleTransition.getAuditingAction(), componentType,
326 ResourceAuditData.newBuilder().state(oldState.name()).version(resourceCurrVersion).build(), changeInfo.getUserRemarks());
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 componentUtils.auditComponent(errorResponse, modifier, lifeCycleTransition.getAuditingAction(), componentId, componentType, changeInfo.getUserRemarks());
342 return Either.right(errorResponse);
344 return Either.left(eitherResourceResponse.left().value());
347 private Either<Boolean, ResponseFormat> validateHighestVersion(User modifier, LifeCycleTransition lifeCycleTransition, Resource resource, String resourceCurrVersion) {
348 ResponseFormat errorResponse;
349 if (!resource.isHighestVersion()) {
350 log.debug("resource version {} is not the last version of resource {}", resource.getVersion(), resource.getName());
351 errorResponse = componentUtils.getResponseFormat(ActionStatus.COMPONENT_HAS_NEWER_VERSION, resource.getName(), ComponentTypeEnum.RESOURCE.name().toLowerCase());
352 componentUtils.auditResource(errorResponse, modifier, resource, lifeCycleTransition.getAuditingAction(), ResourceAuditData.newBuilder()
353 .state(resource.getLifecycleState().name()).version(resourceCurrVersion).build());
354 return Either.right(errorResponse);
356 return Either.left(true);
359 private Either<Boolean, ResponseFormat> validateHighestVersion(User modifier, LifeCycleTransition lifeCycleTransition, Component component, String resourceCurrVersion, ComponentTypeEnum componentType) {
360 ResponseFormat errorResponse;
361 if (!component.isHighestVersion()) {
362 log.debug("Component version {} is not the last version of component {}", component.getComponentMetadataDefinition().getMetadataDataDefinition().getVersion(),
363 component.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
364 errorResponse = componentUtils.getResponseFormat(ActionStatus.COMPONENT_HAS_NEWER_VERSION, component.getComponentMetadataDefinition().getMetadataDataDefinition().getName(), componentType.getValue().toLowerCase());
365 componentUtils.auditComponentAdmin(errorResponse, modifier, component,lifeCycleTransition.getAuditingAction(), componentType,
366 ResourceAuditData.newBuilder().state(component.getLifecycleState().name()).version(resourceCurrVersion).build());
367 return Either.right(errorResponse);
369 return Either.left(true);
372 private Either<Boolean, ResponseFormat> lockComponent(ComponentTypeEnum componentType, Component component) {
373 NodeTypeEnum nodeType = componentType.getNodeType();
374 StorageOperationStatus lockResourceStatus = graphLockOperation.lockComponent(component.getUniqueId(), nodeType);
376 if (lockResourceStatus.equals(StorageOperationStatus.OK)) {
377 return Either.left(true);
379 ActionStatus actionStatus = componentUtils.convertFromStorageResponse(lockResourceStatus);
380 ResponseFormat responseFormat = componentUtils.getResponseFormat(actionStatus, component.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
381 return Either.right(responseFormat);
386 private Either<String, ResponseFormat> validateComment(LifecycleChangeInfoWithAction changeInfo, LifeCycleTransitionEnum transitionEnum) {
387 String comment = changeInfo.getUserRemarks();
388 if (LifeCycleTransitionEnum.CANCEL_CERTIFICATION == transitionEnum || LifeCycleTransitionEnum.CERTIFY == transitionEnum || LifeCycleTransitionEnum.FAIL_CERTIFICATION == transitionEnum || LifeCycleTransitionEnum.CHECKIN == transitionEnum
389 || LifeCycleTransitionEnum.CERTIFICATION_REQUEST == transitionEnum
393 if (!ValidationUtils.validateStringNotEmpty(comment)) {
394 log.debug("user comment cannot be empty or null.");
395 ResponseFormat errorResponse = componentUtils.getResponseFormat(ActionStatus.MISSING_DATA, COMMENT);
396 return Either.right(errorResponse);
399 comment = ValidationUtils.removeNoneUtf8Chars(comment);
400 comment = ValidationUtils.removeHtmlTags(comment);
401 comment = ValidationUtils.normaliseWhitespace(comment);
402 comment = ValidationUtils.stripOctets(comment);
404 if (!ValidationUtils.validateLength(comment, ValidationUtils.COMMENT_MAX_LENGTH)) {
405 log.debug("user comment exceeds limit.");
406 return Either.right(componentUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, COMMENT, String.valueOf(ValidationUtils.COMMENT_MAX_LENGTH)));
408 if (!ValidationUtils.validateIsEnglish(comment)) {
409 return Either.right(componentUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
412 return Either.left(comment);
415 private ComponentBusinessLogic getComponentBL(ComponentTypeEnum componentTypeEnum) {
416 ComponentBusinessLogic businessLogic;
417 switch (componentTypeEnum) {
419 businessLogic = this.resourceBusinessLogic;
422 businessLogic = this.serviceBusinessLogic;
425 businessLogic = this.productBusinessLogic;
428 throw new IllegalArgumentException("Illegal component type:" + componentTypeEnum.getValue());
430 return businessLogic;
433 public Either<Component, ResponseFormat> getLatestComponentByUuid(ComponentTypeEnum componentTypeEnum, String uuid) {
435 Either<Component, StorageOperationStatus> latestVersionEither = toscaOperationFacade.getLatestComponentByUuid(uuid);
437 if (latestVersionEither.isRight()) {
439 return Either.right(componentUtils.getResponseFormat(componentUtils.convertFromStorageResponse(latestVersionEither.right().value(), componentTypeEnum), uuid));
442 Component latestComponent = latestVersionEither.left().value();
444 return Either.left(latestComponent);
447 * Performs Force certification.
448 * Note that a Force certification is allowed for the first certification only,
449 * as only a state and a version is promoted due a Force certification,
450 * skipping other actions required if a previous certified version exists.
453 * @param lifecycleChangeInfo
454 * @param inTransaction
458 public Either<Resource, ResponseFormat> forceResourceCertification(Resource resource, User user, LifecycleChangeInfoWithAction lifecycleChangeInfo, boolean inTransaction, boolean needLock) {
459 Either<Resource, ResponseFormat> result = null;
460 Either<ToscaElement, StorageOperationStatus> certifyResourceRes = null;
461 if(lifecycleChangeInfo.getAction() != LifecycleChanceActionEnum.CREATE_FROM_CSAR){
462 log.debug("Force certification is not allowed for the action {}. ", lifecycleChangeInfo.getAction());
463 result = Either.right(componentUtils.getResponseFormat(ActionStatus.NOT_ALLOWED));
465 if(!isFirstCertification(resource.getVersion())){
466 log.debug("Failed to perform a force certification of resource{}. Force certification is allowed for the first certification only. ", resource.getName());
467 result = Either.right(componentUtils.getResponseFormat(ActionStatus.NOT_ALLOWED));
470 if(result == null && !inTransaction && needLock){
471 log.info("lock component {}", resource.getUniqueId());
472 Either<Boolean, ResponseFormat> eitherLockResource = lockComponent(resource.getComponentType(), resource);
473 if (eitherLockResource.isRight()) {
474 log.error("lock component {} failed", resource.getUniqueId());
475 result = Either.right(eitherLockResource.right().value());
477 log.info("after lock component {}", resource.getUniqueId());
481 certifyResourceRes = lifecycleOperation.forceCerificationOfToscaElement(resource.getUniqueId(), user.getUserId(), user.getUserId(), resource.getVersion());
482 if (certifyResourceRes.isRight()) {
483 StorageOperationStatus status = certifyResourceRes.right().value();
484 log.debug("Failed to perform a force certification of resource {}. The status is {}. ", resource.getName(), status);
485 result = Either.right(componentUtils.getResponseFormatByResource(componentUtils.convertFromStorageResponse(status), resource));
489 result = Either.left(ModelConverter.convertFromToscaElement(certifyResourceRes.left().value()));
492 log.info("unlock component {}", resource.getUniqueId());
493 if (!inTransaction) {
500 NodeTypeEnum nodeType = resource.getComponentType().getNodeType();
501 log.info("During change state, another component {} has been created/updated", resource.getUniqueId());
502 graphLockOperation.unlockComponent(resource.getUniqueId(), nodeType);
509 public boolean isFirstCertification(String previousVersion) {
510 return previousVersion.split("\\.")[0].equals("0");