1 package org.openecomp.sdc.be.components.upgrade;
4 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
5 import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic;
6 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction;
7 import org.openecomp.sdc.be.components.validation.UserValidations;
8 import org.openecomp.sdc.be.dao.api.ActionStatus;
9 import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
10 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
11 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
12 import org.openecomp.sdc.be.impl.ComponentsUtils;
13 import org.openecomp.sdc.be.model.*;
14 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
15 import org.openecomp.sdc.be.model.jsontitan.operations.UpgradeOperation;
16 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
17 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
18 import org.openecomp.sdc.be.user.Role;
19 import org.openecomp.sdc.common.log.wrappers.Logger;
20 import org.openecomp.sdc.exception.ResponseFormat;
23 import java.util.stream.Collectors;
25 @org.springframework.stereotype.Component("upgradeBusinessLogic")
26 public class UpgradeBusinessLogic {
28 private final LifecycleBusinessLogic lifecycleBusinessLogic;
29 private final ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
30 private final UserValidations userValidations;
31 private final ToscaOperationFacade toscaOperationFacade;
32 private final ComponentsUtils componentsUtils;
33 private final UpgradeOperation upgradeOperation;
34 private final TitanDao titanDao;
35 private LifecycleChangeInfoWithAction changeInfo = new LifecycleChangeInfoWithAction("automated upgrade");
37 private static final List<String> UUID_PROPS_NAMES = Arrays.asList("depending_service_uuid", "providing_service_uuid");
38 private static final List<String> INV_UUID_PROPS_NAMES = Arrays.asList("depending_service_invariant_uuid", "providing_service_invariant_uuid");
39 private static final List<String> NAME_PROPS_NAMES = Arrays.asList("depending_service_name", "providing_service_name");
41 private static final Logger LOGGER = Logger.getLogger(UpgradeBusinessLogic.class);
43 public UpgradeBusinessLogic(LifecycleBusinessLogic lifecycleBusinessLogic, ComponentInstanceBusinessLogic componentInstanceBusinessLogic, UserValidations userValidations, ToscaOperationFacade toscaOperationFacade, ComponentsUtils componentsUtils,
44 UpgradeOperation upgradeOperation, TitanDao titanDao) {
45 this.lifecycleBusinessLogic = lifecycleBusinessLogic;
46 this.componentInstanceBusinessLogic = componentInstanceBusinessLogic;
47 this.userValidations = userValidations;
48 this.toscaOperationFacade = toscaOperationFacade;
49 this.componentsUtils = componentsUtils;
50 this.upgradeOperation = upgradeOperation;
51 this.titanDao = titanDao;
61 public UpgradeStatus automatedUpgrade(String componentId, List<UpgradeRequest> upgradeRequest, String userId) {
62 UpgradeStatus status = new UpgradeStatus();
63 User user = userValidations.validateUserExists(userId, "automated upgrade", false);
65 Either<Component, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaFullElement(componentId);
66 if (storageStatus.isRight()) {
67 status.setError(componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(storageStatus.right().value()), componentId));
70 Component component = storageStatus.left().value();
71 if (!component.isHighestVersion() || component.getLifecycleState() != LifecycleStateEnum.CERTIFIED) {
72 LOGGER.debug("automated Upgrade failed - target is not higest certified component {} state {} version {} ", component.getName(), component.getLifecycleState(), component.getVersion());
73 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_IS_NOT_HIHGEST_CERTIFIED, component.getName());
74 status.setError(responseFormat);
75 componentsUtils.auditComponentAdmin(responseFormat, user, component, getAuditTypeByComponent(component), component.getComponentType());
79 if ( component.isArchived() ){
80 LOGGER.debug("automated Upgrade failed - target is archived component {} version {} ", component.getName(), component.getVersion());
81 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_IS_ARCHIVED, component.getName());
82 status.setError(responseFormat);
83 componentsUtils.auditComponentAdmin(responseFormat, user, component, getAuditTypeByComponent(component), component.getComponentType());
87 switch (component.getComponentType()) {
89 hadnleUpgradeVFInService(component, upgradeRequest, user, status);
92 hadnleUpgradeService(component, upgradeRequest, user, status);
95 LOGGER.debug("automated Upgrade failed - Not supported type {} for component {} ", component.getComponentType(), component.getName());
96 status.setError(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_ERROR));
107 public Either<List<ComponentDependency>, ResponseFormat> getComponentDependencies(String componentId, String userId) {
109 User user = userValidations.validateUserExists(userId, "get Component Dependencies for automated upgrade", false);
111 return upgradeOperation.getComponentDependencies(componentId)
113 .map(rf -> componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(rf)));
115 // all operation were read only. no commit needed
121 private UpgradeStatus hadnleUpgradeVFInService(Component component, List<UpgradeRequest> componentUids, User user, UpgradeStatus upgradeStatus) {
122 Resource vfResource = (Resource) component;
123 if (vfResource.getResourceType() != ResourceTypeEnum.VF) {
124 LOGGER.debug("automated Upgrade failed - target is not VF resource {} {} ", vfResource.getName(), vfResource.getResourceType());
125 upgradeStatus.setStatus(ActionStatus.GENERAL_ERROR);
126 componentsUtils.auditComponentAdmin(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR), user, component, getAuditTypeByComponent(component), component.getComponentType());
127 return upgradeStatus;
129 componentUids.forEach(request -> upgradeInSingleService(request, vfResource, user, upgradeStatus));
130 upgradeStatus.setStatus(ActionStatus.OK);
131 componentsUtils.auditComponentAdmin(componentsUtils.getResponseFormat(ActionStatus.OK), user, component, AuditingActionEnum.VF_UPGRADE_SERVICES, component.getComponentType());
133 return upgradeStatus;
136 private UpgradeStatus hadnleUpgradeService(Component component, List<UpgradeRequest> upgradeRequest, User user, UpgradeStatus upgradeStatus) {
137 if ( Role.TESTER.name().equals(user.getRole()) ){
138 user.setRole(Role.DESIGNER.name());
139 LOGGER.debug("Change temporary for update service reference user role from TESTER to DESINGER");
141 Service service = (Service) component;
142 upgradeRequest.forEach(request -> upgradeSingleService(request, service, user, upgradeStatus));
143 upgradeStatus.setStatus(ActionStatus.OK);
144 componentsUtils.auditComponentAdmin(componentsUtils.getResponseFormat(ActionStatus.OK), user, component, AuditingActionEnum.UPDATE_SERVICE_REFERENCE, component.getComponentType());
145 return upgradeStatus;
148 private ActionStatus upgradeSingleService(UpgradeRequest request, Service service, User user, UpgradeStatus upgradeStatus) {
149 if (request.getResourceId() == null) {
150 // upgrade proxy version
151 return upgradeInSingleService(request, service, user, upgradeStatus);
153 // upgrade allotted resource -> service
154 return upgradeChainResourceService(request, service, user, upgradeStatus);
158 private ActionStatus upgradeInSingleService(UpgradeRequest request, Component newVersionComponent, User user, UpgradeStatus upgradeStatus) {
159 String serviceId = request.getServiceId();
160 return toscaOperationFacade.getToscaFullElement(serviceId)
161 .either(l -> handleService(l, newVersionComponent, user, upgradeStatus), err -> {
162 LOGGER.debug("Failed to fetch service by id {} error {}", serviceId, err);
163 ActionStatus errS = componentsUtils.convertFromStorageResponse(err);
164 upgradeStatus.addServiceStatus(serviceId, errS);
169 private ActionStatus upgradeChainResourceService(UpgradeRequest request, Service service, User user, UpgradeStatus upgradeStatus) {
171 Either<? extends Component, ActionStatus> upgradeAllottedResource = upgradeAllottedResource(request, user, upgradeStatus, service);
172 if (upgradeAllottedResource.isRight()) {
173 return upgradeAllottedResource.right().value();
176 resource = upgradeAllottedResource.left().value();
177 // update VF instance in service
179 Either<Component, StorageOperationStatus> serviceContainer = toscaOperationFacade.getToscaFullElement(request.getServiceId());
180 if (serviceContainer.isRight()) {
181 LOGGER.debug("Failed to fetch resource by id {} error {}", request.getServiceId(), serviceContainer.right().value());
182 ActionStatus errS = componentsUtils.convertFromStorageResponse(serviceContainer.right().value());
183 upgradeStatus.addServiceStatus(request.getServiceId(), errS);
186 return handleService(serviceContainer.left().value(), resource, user, upgradeStatus);
190 private Either<? extends Component, ActionStatus> upgradeAllottedResource(UpgradeRequest request, User user, UpgradeStatus upgradeStatus, Service service) {
191 return getElement(request.getResourceId(), upgradeStatus, request)
193 .bind(l -> upgradeStateAlloted(request, user, upgradeStatus, service, l));
196 private Either<Component, ActionStatus> getElement(String id, UpgradeStatus upgradeStatus, UpgradeRequest request) {
197 return toscaOperationFacade.getToscaElement(id)
200 ActionStatus errS = componentsUtils.convertFromStorageResponse(err);
201 upgradeStatus.addServiceStatus(request.getServiceId(), errS);
206 private Either<? extends Component, ActionStatus> upgradeStateAlloted(UpgradeRequest request, User user, UpgradeStatus upgradeStatus, Service service, Component resource) {
207 if (resource.getLifecycleState() == LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT) {
208 LOGGER.debug("Automated upgrade failedd. Alloted vf {} is in state NOT_CERTIFIED_CHECKOUT", request.getResourceId());
209 upgradeStatus.addServiceStatus(request.getServiceId(), ActionStatus.RESOURCE_LIFECYCLE_STATE_NOT_VALID);
210 return Either.right(ActionStatus.RESOURCE_LIFECYCLE_STATE_NOT_VALID);
213 // update properties-reference to service in VF on VFCI
214 return changeComponentState(resource, LifeCycleTransitionEnum.CHECKOUT, user, upgradeStatus, request.getServiceId())
216 .bind(l -> updateAllottedPropsAndCertify(request, user, upgradeStatus, service, l));
219 private Either<? extends Component, ActionStatus> updateAllottedPropsAndCertify(UpgradeRequest request, User user, UpgradeStatus upgradeStatus, Service service, Component resource) {
220 Either<? extends Component, ActionStatus> result = null;
222 List<String> instanceIds = upgradeOperation.getInstanceIdFromAllottedEdge(resource.getUniqueId(), service.getInvariantUUID());
223 if (instanceIds != null) {
224 Map<String, List<ComponentInstanceProperty>> componentInstancesProperties = resource.getComponentInstancesProperties();
225 Map<String, List<ComponentInstanceProperty>> propertiesToUpdate = new HashMap<>();
227 instanceIds.forEach(id -> findPropertiesToUpdate(id, componentInstancesProperties, propertiesToUpdate, service));
229 Either<Map<String, List<ComponentInstanceProperty>>, StorageOperationStatus> updatePropsResult = toscaOperationFacade.updateComponentInstancePropsToComponent(propertiesToUpdate, resource.getUniqueId());
230 if (updatePropsResult.isRight()) {
231 LOGGER.debug("Failed to update properties in Allotted resource {} {}, Error {}. ", resource.getName(), resource.getUniqueId(), updatePropsResult.right().value());
233 result = Either.right(ActionStatus.GENERAL_ERROR);
238 result = changeComponentState(resource, LifeCycleTransitionEnum.CERTIFY, user, upgradeStatus, request.getServiceId());
241 LOGGER.debug("No Instances to update in allotted resource {} ", resource.getName());
242 result = Either.right(ActionStatus.NO_INSTANCES_TO_UPGRADE);
246 if ( result.isRight() ){
247 // undo checkout resource in case of failure
248 LOGGER.debug("Failed to update Allotted resource {} {}, Error {}. UNDOCHEKOUT our resource", resource.getName(), resource.getUniqueId(), result.right().value());
250 upgradeStatus.addServiceStatus(request.getServiceId(), ActionStatus.GENERAL_ERROR);
255 private void undocheckoutComponent(User user, Component resource) {
256 Either<? extends Component, ResponseFormat> changeComponentState = lifecycleBusinessLogic.changeComponentState(resource.getComponentType(), resource.getUniqueId(), user, LifeCycleTransitionEnum.UNDO_CHECKOUT, changeInfo, false, true);
257 if (changeComponentState.isRight()) {
258 LOGGER.debug("Failed to UNDOCHECKOUT Service {} {}, Error {}", resource.getName(), resource.getUniqueId(), changeComponentState.right().value());
262 private void findPropertiesToUpdate(String id, Map<String, List<ComponentInstanceProperty>> componentInstancesProperties, Map<String, List<ComponentInstanceProperty>> propertiesToUpdate, Service service) {
263 List<ComponentInstanceProperty> list = componentInstancesProperties.get(id);
264 List<ComponentInstanceProperty> propsPerInstance = new ArrayList<>();
266 if (UUID_PROPS_NAMES.contains(p.getName())) {
267 p.setValue(service.getUUID());
268 propsPerInstance.add(p);
270 if (INV_UUID_PROPS_NAMES.contains(p.getName())) {
271 p.setValue(service.getInvariantUUID());
272 propsPerInstance.add(p);
274 if (NAME_PROPS_NAMES.contains(p.getName())) {
275 p.setValue(service.getName());
276 propsPerInstance.add(p);
279 propertiesToUpdate.put(id, propsPerInstance);
282 private ActionStatus handleService(Component component, Component newVersionComponent, User user, UpgradeStatus upgradeStatus) {
283 if (component.getComponentType() != ComponentTypeEnum.SERVICE) {
284 LOGGER.debug("component with id {} and name {} isn't SERVICE. type{} ", component.getName(), component.getUniqueId(), component.getComponentType());
285 upgradeStatus.addServiceStatus(component, ActionStatus.GENERAL_ERROR);
286 return ActionStatus.GENERAL_ERROR;
289 Service service = (Service) component;
290 if (component.getLifecycleState() != LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT) {
291 LOGGER.debug("Service {} {} is not in CHECKOUT state . Try to checkout it", component.getName(), component.getUniqueId());
292 Either<? extends Component, ActionStatus> changeComponentState = changeComponentState(component, LifeCycleTransitionEnum.CHECKOUT, user, upgradeStatus, null);
293 if ( changeComponentState.isRight() ){
294 return changeComponentState.right().value();
296 service = (Service) changeComponentState.left().value();
297 //need to fetch service again with capability properties
298 Either<Component, StorageOperationStatus> toscaFullElement = toscaOperationFacade.getToscaFullElement(service.getUniqueId());
299 if ( toscaFullElement.isRight() ){
300 return componentsUtils.convertFromStorageResponse(toscaFullElement.right().value());
302 service = (Service) toscaFullElement.left().value();
304 LOGGER.debug("Service {} {} is in CHECKOUT state . Restricted update operation", component.getName(), component.getUniqueId());
305 upgradeStatus.addServiceStatus(component, ActionStatus.COMPONENT_IN_CHECKOUT_STATE);
306 return ActionStatus.COMPONENT_IN_CHECKOUT_STATE;
308 ActionStatus status = ActionStatus.GENERAL_ERROR;
310 status = handleInstances(newVersionComponent, user, upgradeStatus, service);
312 if (status != ActionStatus.OK) {
313 LOGGER.debug("Failed to upgrade instance for service {} status {}. Undocheckout service", service.getName(), status);
314 undocheckoutComponent(user, service);
316 upgradeStatus.addServiceStatus(component, status);
322 private Either<? extends Component,ActionStatus> changeComponentState(Component component, LifeCycleTransitionEnum nextState, User user, UpgradeStatus upgradeStatus, String idForStatus){
323 if ( component.isArchived() ){
324 LOGGER.debug("Component {} from type {} id {} is archived, Error {}", nextState, component.getName(), component.getComponentType(), component.getUniqueId());
325 setUpgradeStatus(component, upgradeStatus, idForStatus);
326 return Either.right(ActionStatus.COMPONENT_IS_ARCHIVED);
328 return lifecycleBusinessLogic.changeComponentState(component.getComponentType(), component.getUniqueId(), user, nextState, changeInfo, false, true)
331 LOGGER.debug("Failed to {} Component {} from type {} id {}, Error {}", nextState, component.getName(), component.getComponentType(), component.getUniqueId(), err);
332 setUpgradeStatus(component, upgradeStatus, idForStatus);
333 return ActionStatus.GENERAL_ERROR;
339 private void setUpgradeStatus(Component component, UpgradeStatus upgradeStatus, String idForStatus) {
340 if ( idForStatus == null ){
341 upgradeStatus.addServiceStatus(component, ActionStatus.GENERAL_ERROR);
343 upgradeStatus.addServiceStatus(idForStatus, ActionStatus.GENERAL_ERROR);
347 private ActionStatus handleInstances(Component newVersionComponent, User user, UpgradeStatus upgradeStatus, Service service) {
348 List<ComponentInstance> componentInstances = service.getComponentInstances();
349 if (componentInstances != null) {
350 List<ComponentInstance> instanceToChange = componentInstances
352 .filter(ci -> matchInstance(ci, newVersionComponent))
353 .collect(Collectors.toList());
354 if (instanceToChange != null && !instanceToChange.isEmpty()) {
355 return changeInstances(newVersionComponent, user, upgradeStatus, service, instanceToChange);
357 LOGGER.debug("No instances for change version");
358 return ActionStatus.NO_INSTANCES_TO_UPGRADE;
361 return ActionStatus.OK;
364 private ActionStatus changeInstances(Component newVersionComponent, User user, UpgradeStatus upgradeStatus, Service service, List<ComponentInstance> instanceToChange) {
365 Component serviceToUpgrade = service;
366 for (ComponentInstance ci : instanceToChange) {
367 Either<Component, ActionStatus> fetchService = fetchService(service.getUniqueId(),service.getName());
368 if ( fetchService.isRight()){
369 upgradeStatus.addServiceStatus(service, fetchService.right().value());
370 return fetchService.right().value();
372 serviceToUpgrade = fetchService.left().value();
373 ActionStatus status = changeVersionOfInstance(serviceToUpgrade, ci, newVersionComponent, user);
374 if (status != ActionStatus.OK) {
375 LOGGER.debug("Failed to change for instance {} version in service {}", ci.getName(), service.getName());
376 upgradeStatus.addServiceStatus(service, status);
380 Either<Component, ActionStatus> fetchService = fetchService(service.getUniqueId(),service.getName());
381 if ( fetchService.isRight()){
382 upgradeStatus.addServiceStatus(service, fetchService.right().value());
383 return fetchService.right().value();
385 serviceToUpgrade = fetchService.left().value();
387 Either<? extends Component, ActionStatus> changeComponentState = changeComponentState(serviceToUpgrade, LifeCycleTransitionEnum.CHECKIN, user, upgradeStatus, null);
388 if ( changeComponentState.isRight() ){
389 return changeComponentState.right().value();
391 upgradeStatus.addServiceStatus(serviceToUpgrade, ActionStatus.OK);
392 return ActionStatus.OK;
396 private Either<Component, ActionStatus> fetchService(String uniqueId, String name) {
397 return toscaOperationFacade.getToscaFullElement(uniqueId)
400 LOGGER.debug("Failed to fetch service {} id {} error {}", name, uniqueId, r);
401 return ActionStatus.GENERAL_ERROR;
405 private ActionStatus changeVersionOfInstance(Component service, ComponentInstance ci, Component newVersionComponent, User user) {
406 LOGGER.debug("In Service {} change instance version {} to version {}", service.getName(), ci.getName(), newVersionComponent.getVersion());
407 ComponentInstance newComponentInstance = new ComponentInstance();
408 newComponentInstance.setComponentUid(newVersionComponent.getUniqueId());
409 Either<ComponentInstance, ResponseFormat> changeInstanceVersion = componentInstanceBusinessLogic.changeInstanceVersion(service, ci, newComponentInstance, user, service.getComponentType());
410 if (changeInstanceVersion.isLeft()) {
411 return ActionStatus.OK;
413 return ActionStatus.GENERAL_ERROR;
417 private boolean matchInstance(ComponentInstance ci, Component newVersionComponent) {
418 Either<Component, StorageOperationStatus> toscaElement;
419 ComponentParametersView filters = new ComponentParametersView(true);
420 if (newVersionComponent.getComponentType() == ComponentTypeEnum.SERVICE) {
421 if (ci.getIsProxy()) {
422 toscaElement = toscaOperationFacade.getToscaElement(ci.getSourceModelUid(), filters);
427 toscaElement = toscaOperationFacade.getToscaElement(ci.getComponentUid(), filters);
429 if (toscaElement.isLeft()) {
430 Component origin = toscaElement.left().value();
431 if (newVersionComponent.getInvariantUUID().equals(origin.getInvariantUUID()) && !newVersionComponent.getVersion().equals(origin.getVersion())) {
432 // only for same invariant UUID (same component) but different versions
438 private AuditingActionEnum getAuditTypeByComponent(Component component){
439 if ( ComponentTypeEnum.RESOURCE == component.getComponentType()){
440 return AuditingActionEnum.VF_UPGRADE_SERVICES;
442 return AuditingActionEnum.UPDATE_SERVICE_REFERENCE;