Upgrade SDC from Titan to Janus Graph
[sdc.git] / asdctool / src / main / java / org / openecomp / sdc / asdctool / migration / tasks / mig1710 / UpgradeMigration1710.java
1 package org.openecomp.sdc.asdctool.migration.tasks.mig1710;
2
3 import com.google.common.annotations.VisibleForTesting;
4 import com.google.common.collect.Lists;
5 import fj.data.Either;
6 import org.apache.commons.collections.CollectionUtils;
7 import org.apache.commons.collections.MapUtils;
8 import org.apache.commons.lang3.StringUtils;
9 import org.openecomp.sdc.asdctool.migration.core.task.MigrationResult;
10 import org.openecomp.sdc.asdctool.migration.core.task.PostMigration;
11 import org.openecomp.sdc.asdctool.migration.tasks.handlers.XlsOutputHandler;
12 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
13 import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic;
14 import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic;
15 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
16 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
17 import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic;
18 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction;
19 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction.LifecycleChanceActionEnum;
20 import org.openecomp.sdc.be.components.scheduledtasks.ComponentsCleanBusinessLogic;
21 import org.openecomp.sdc.be.config.Configuration;
22 import org.openecomp.sdc.be.config.ConfigurationManager;
23 import org.openecomp.sdc.be.dao.api.ActionStatus;
24 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
25 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
26 import org.openecomp.sdc.be.dao.jsongraph.JanusGraphDao;
27 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
28 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
29 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
30 import org.openecomp.sdc.be.datatypes.enums.*;
31 import org.openecomp.sdc.be.impl.ComponentsUtils;
32 import org.openecomp.sdc.be.model.*;
33 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
34 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
35 import org.openecomp.sdc.be.model.operations.api.IUserAdminOperation;
36 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
37 import org.openecomp.sdc.be.model.operations.impl.CsarOperation;
38 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
39 import org.openecomp.sdc.common.log.wrappers.Logger;
40 import org.openecomp.sdc.exception.ResponseFormat;
41 import org.springframework.beans.factory.annotation.Autowired;
42 import org.springframework.stereotype.Component;
43
44 import javax.annotation.PostConstruct;
45 import java.util.*;
46 import java.util.function.Predicate;
47 import java.util.stream.Collectors;
48
49 @Component
50 public class UpgradeMigration1710 implements PostMigration {
51
52     private static final String SERVICE_UUID_RPOPERTY = "providing_service_uuid";
53
54     private static final String SERVICE_INVARIANT_UUID_RPOPERTY = "providing_service_invariant_uuid";
55
56     private static final String UNKNOWN = "UNKNOWN";
57
58     private static final String CHECKOUT_MESSAGE = "checkout upon upgrade migration";
59
60     private static final String FAILED_TO_CHANGE_STATE_OF_COMPONENT = "Failed to change state of component with name {}, invariantUUID {}, version {} to {}. ";
61
62     private static final String FAILED_TO_UPGRADE_COMPONENT = "Failed to upgrade {} with name {}, invariantUUID {}, version {}. Operation {}. The reason for failure: {}. ";
63
64     private static final String UPGRADE_COMPONENT_SUCCEEDED = "Upgrade of {} with name {}, invariantUUID {}, version {} finished successfully. ";
65
66     private static final String UPGRADE_VFS_FAILED = "Upgrade VFs upon upgrade migration 1710 process failed. ";
67
68     private static final Logger log = Logger.getLogger(UpgradeMigration1710.class);
69
70     private static final String ALLOTTED_RESOURCE_NAME = "Allotted Resource";
71
72     //as per US 397775, only node type upgrade should be enabled,
73     // to support resource and service upgrade, this flag should be reverted
74     private boolean isNodeTypesSupportOnly = true;
75
76     @Autowired
77     private JanusGraphDao janusGraphDao;
78
79     @Autowired
80     private ToscaOperationFacade toscaOperationFacade;
81
82     @Autowired
83     private LifecycleBusinessLogic lifecycleBusinessLogic;
84
85     @Autowired
86     private IUserAdminOperation userAdminOperation;
87
88     @Autowired
89     private ResourceBusinessLogic resourceBusinessLogic;
90
91     @Autowired
92     private ServiceBusinessLogic serviceBusinessLogic;
93
94     @Autowired
95     private CsarOperation csarOperation;
96
97     @Autowired
98     private ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
99
100     @Autowired
101     private ComponentsUtils componentsUtils;
102
103     @Autowired
104     private ComponentsCleanBusinessLogic componentsCleanBusinessLogic;
105
106     private XlsOutputHandler outputHandler = new XlsOutputHandler(null, "UpgradeMigration1710report","COMPONENT TYPE", "COMPONENT NAME", "COMPONENT UUID", "COMPONENT UNIQUE_ID", "UPGRADE STATUS", "DESCRIPTION");
107
108     private User user = null;
109
110     private final LifecycleChangeInfoWithAction changeInfo = new LifecycleChangeInfoWithAction(CHECKOUT_MESSAGE, LifecycleChanceActionEnum.UPGRADE_MIGRATION);
111
112     private final Map<String, GraphVertex> latestGenericTypes = new HashMap<>();
113
114     private final Map<String, String> latestOriginResourceVersions = new HashMap<>();
115
116     private final Map<String, org.openecomp.sdc.be.model.Component> upgradedNodeTypesMap = new HashMap<>();
117
118     private List<String> nodeTypes;
119
120     private List<String> proxyServiceContainers = new ArrayList<>();
121
122     private List<String> vfAllottedResources = new ArrayList<>();
123
124     private List<String> allottedVfContainers = new ArrayList<>();
125
126     private boolean isVfcUpgradeRequired = false;
127
128     private boolean skipIfUpgradeVfFailed = true;
129
130     private boolean isAllottedAndProxySupported = true;
131
132     private String userId;
133
134     private boolean isCleanupLocked = false;
135
136     private int markedAsDeletedResourcesCnt = 0;
137
138     private int markedAsDeletedServicesCnt = 0;
139
140     //how many components can be deleted once
141     private int maxDeleteComponents = 10;
142
143     private boolean enableAutoHealing = true;
144
145     //map for tracing checked out resources that keep in place after upgrade failure
146     private HashMap<String, String> certifiedToNextCheckedOutUniqueId = new HashMap<>();
147
148     private int deleteLockTimeoutInSeconds = 60;
149
150     private boolean isLockSucceeded = false;
151
152     /***********************************************/
153
154     @VisibleForTesting
155     void setNodeTypesSupportOnly(boolean nodeTypesSupportOnly) {
156         isNodeTypesSupportOnly = nodeTypesSupportOnly;
157     }
158
159     @VisibleForTesting
160     void setUser(User user) {
161         this.user = user;
162     }
163
164     @VisibleForTesting
165     void setMarkedAsDeletedResourcesCnt(int markedAsDeletedResourcesCnt) {
166         this.markedAsDeletedResourcesCnt = markedAsDeletedResourcesCnt;
167     }
168
169     @VisibleForTesting
170     void setMarkedAsDeletedServicesCnt(int markedAsDeletedServicesCnt) {
171         this.markedAsDeletedServicesCnt = markedAsDeletedServicesCnt;
172     }
173
174     @PostConstruct
175     void init() {
176         Configuration config = ConfigurationManager.getConfigurationManager().getConfiguration();
177         isVfcUpgradeRequired = !config.getSkipUpgradeVSPsFlag();
178         skipIfUpgradeVfFailed = config.getSkipUpgradeFailedVfs();
179         isAllottedAndProxySupported = config.getSupportAllottedResourcesAndProxyFlag();
180         deleteLockTimeoutInSeconds = config.getDeleteLockTimeoutInSeconds();
181         maxDeleteComponents = config.getMaxDeleteComponents();
182
183         String toscaConformanceLevel = config.getToscaConformanceLevel();
184         Map<String, List<String>> resourcesForUpgrade = config.getResourcesForUpgrade();
185         nodeTypes = resourcesForUpgrade.get(toscaConformanceLevel);
186         enableAutoHealing = config.isEnableAutoHealing();
187         userId = config.getAutoHealingOwner();
188         isNodeTypesSupportOnly = true;
189     }
190
191     @Override
192     public String description() {
193         return "Upgrade migration 1710 - post migration task, which is dedicated to upgrade all latest certified (and not checked out) Node types, VFs and Services. ";
194     }
195
196     enum UpgradeStatus {
197         UPGRADED,
198         UPGRADED_AS_INSTANCE,
199         NOT_UPGRADED
200     }
201
202     @Override
203     public MigrationResult migrate() {
204         MigrationResult migrationResult = new MigrationResult();
205         //stop the upgrade if this ask is disabled
206         if (!enableAutoHealing) {
207             log.warn("Upgrade migration 1710 task is disabled");
208             migrationResult.setMigrationStatus(MigrationResult.MigrationStatus.COMPLETED);
209             return migrationResult ;
210         }
211         log.info("Starting upgrade migration 1710 process. ");
212         boolean result = true;
213
214         try {
215             //lock cleanup node to avoid BE to delete marked components
216             //while the auto-healing process is running
217             isLockSucceeded = isNodeTypesSupportOnly ? true : isLockDeleteOperationSucceeded();
218
219             if (!isLockSucceeded) {
220                 result = false;
221                 log.error("Cleanup node can't be locked. Upgrade migration failed");
222             }
223             else {
224                 Either<User, ActionStatus> userReq = userAdminOperation.getUserData(userId, false);
225                 if (userReq.isRight()) {
226                     result = false;
227                     log.error("Upgrade migration failed. User {} resolve failed: {} ", userId, userReq.right().value());
228                 } else {
229                     user = userReq.left().value();
230                     log.info("User {} will perform upgrade operation", user.getUserId());
231                 }
232             }
233             if (result) {
234                 result = upgradeNodeTypes();
235             }
236             if (!isNodeTypesSupportOnly && result) {
237                 result = upgradeTopologyTemplates();
238             }
239         }
240         catch (Exception e) {
241             result = false;
242             log.error("Error occurred during the migration: ", e);
243         } finally {
244             MigrationResult.MigrationStatus status = result ?
245                     MigrationResult.MigrationStatus.COMPLETED : MigrationResult.MigrationStatus.FAILED;
246             cleanup(status);
247             migrationResult.setMigrationStatus(status);
248         }
249         return migrationResult;
250     }
251
252     private boolean upgradeTopologyTemplates() {
253         if (upgradeVFs()) {
254             upgradeServices();
255             upgradeProxyServiceContainers();
256             upgradeAllottedVFs();
257             upgradeAllottedVfContainers();
258             return true;
259         }
260         return false;
261     }
262
263     private void cleanup(MigrationResult.MigrationStatus status) {
264         if (status == MigrationResult.MigrationStatus.COMPLETED ) {
265             log.info("Upgrade migration 1710 has been successfully finished. ");
266             janusGraphDao.commit();
267         } else {
268             log.info("Upgrade migration 1710 was failed. ");
269             janusGraphDao.rollback();
270         }
271         outputHandler.writeOutputAndCloseFile();
272         if (!isNodeTypesSupportOnly && isLockSucceeded) {
273             //delete rest of components if their upgrade failed
274             markedAsDeletedResourcesCnt = maxDeleteComponents;
275             deleteResourcesIfLimitIsReached();
276             markedAsDeletedServicesCnt = maxDeleteComponents;
277             deleteServicesIfLimitIsReached();
278             unlockDeleteOperation();
279         }
280     }
281
282     void upgradeServices(List<String> uniqueIDs, Predicate<org.openecomp.sdc.be.model.Component> shouldUpgrade, final String containerName) {
283         log.info("Starting upgrade {} upon upgrade migration 1710 process. ", containerName);
284         for (String currUid : uniqueIDs) {
285             upgradeServiceAndCommitIfNeeded(currUid, shouldUpgrade);
286         }
287         log.info("Upgrade {} upon upgrade migration 1710 process is finished. ", containerName);
288     }
289
290     private void upgradeServiceAndCommitIfNeeded(String currUid, Predicate<org.openecomp.sdc.be.model.Component> shouldUpgrade) {
291         boolean result = true;
292         try {
293             result = handleService(currUid, shouldUpgrade);
294         } catch (Exception e) {
295             result = false;
296             log.error("Failed to upgrade service with uniqueId {} due to a reason {}. ", currUid, e.getMessage());
297             log.debug("Failed to upgrade service with uniqueId {}", currUid, e);
298         }
299         finally {
300             if (result) {
301                 log.info("Service upgrade finished successfully: uniqueId {} ", currUid);
302                 janusGraphDao.commit();
303             }
304             else {
305                 log.error("Failed to upgrade service with uniqueId {} ", currUid);
306                 janusGraphDao.rollback();
307             }
308             markCheckedOutServiceAsDeletedIfUpgradeFailed(currUid, result);
309         }
310     }
311
312     private void upgradeAllottedVfContainers() {
313         upgradeServices(allottedVfContainers, component -> true, "proxy " + allottedVfContainers.size() + " service containers");
314     }
315
316     private void upgradeServices() {
317         Either<List<String>, JanusGraphOperationStatus> getServicesRes = getAllLatestCertifiedComponentUids(VertexTypeEnum.TOPOLOGY_TEMPLATE, ComponentTypeEnum.SERVICE);
318         if (getServicesRes.isRight()) {
319             log.error("Failed to retrieve the latest certified service versions");
320             return;
321         }
322         upgradeServices(getServicesRes.left().value(), this::shouldUpgrade, "services");
323     }
324
325     private void upgradeProxyServiceContainers() {
326         upgradeServices(proxyServiceContainers, component -> true, "proxy service containers");
327     }
328
329     private boolean handleService(String uniqueId, Predicate<org.openecomp.sdc.be.model.Component> shouldUpgrade) {
330         log.info("Starting upgrade Service with uniqueId {} upon upgrade migration 1710 process. ", uniqueId);
331         Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getServiceRes = toscaOperationFacade.getToscaElement(uniqueId);
332         if(getServiceRes.isRight()){
333             log.error("Failed to upgrade service with uniqueId {} due to {}. ", uniqueId, getServiceRes.right().value());
334             outputHandler.addRecord(ComponentTypeEnum.SERVICE.name(), UNKNOWN, UNKNOWN, uniqueId, MigrationResult.MigrationStatus.FAILED.name(), getServiceRes.right().value());
335             return false;
336         }
337         String derivedFromGenericType =  getServiceRes.left().value().getDerivedFromGenericType();
338         log.debug("derivedFromGenericType: {}", derivedFromGenericType );
339         if (derivedFromGenericType == null) {
340             //malformed field value, upgrade required
341             return upgradeService(getServiceRes.left().value());
342         }
343         if(!latestGenericTypes.containsKey(derivedFromGenericType)){
344             Either<List<GraphVertex>, JanusGraphOperationStatus> getDerivedRes = findDerivedResources(derivedFromGenericType);
345             if(getDerivedRes.isRight()){
346                 log.error(FAILED_TO_UPGRADE_COMPONENT, getServiceRes.left().value().getComponentType().getValue(), getServiceRes.left().value().getName(), getServiceRes.left().value().getInvariantUUID(), getServiceRes.left().value().getVersion(), "findDerivedResources", getDerivedRes.right().value());
347                 outputHandler.addRecord( getServiceRes.left().value().getComponentType().name(),getServiceRes.left().value().getName(), getServiceRes.left().value().getInvariantUUID(), getServiceRes.left().value().getUniqueId(), MigrationResult.MigrationStatus.FAILED.name(), getDerivedRes.right().value());
348                 return false;
349             }
350             latestGenericTypes.put(derivedFromGenericType, getDerivedRes.left().value().get(0));
351         }
352         if(latestVersionExists(latestGenericTypes.get(derivedFromGenericType), getServiceRes.left().value().getDerivedFromGenericVersion())){
353             return upgradeService(getServiceRes.left().value());
354         }
355         if(!collectLatestOriginResourceVersions(getServiceRes.left().value())){
356             return false;
357         }
358         if(shouldUpgrade.test(getServiceRes.left().value())){
359             return upgradeService(getServiceRes.left().value());
360         }
361         outputHandler.addRecord(getServiceRes.left().value().getComponentType().name(), getServiceRes.left().value().getName(), getServiceRes.left().value().getInvariantUUID(), getServiceRes.left().value().getUniqueId(), MigrationResult.MigrationStatus.COMPLETED.name(), UpgradeStatus.NOT_UPGRADED);
362         return true;
363     }
364
365     private boolean collectLatestOriginResourceVersions(org.openecomp.sdc.be.model.Component component) {
366         if (CollectionUtils.isNotEmpty(component.getComponentInstances())) {
367             for (ComponentInstance instance : component.getComponentInstances()) {
368                 if (instance.getOriginType() != OriginTypeEnum.ServiceProxy && !latestOriginResourceVersions.containsKey(instance.getToscaComponentName()) && !addComponent(component, instance)) {
369                     return false;
370                 }
371             }
372         }
373         return true;
374     }
375
376     private boolean addComponent(org.openecomp.sdc.be.model.Component component, ComponentInstance instance) {
377         VertexTypeEnum vertexType = ModelConverter.getVertexType(instance.getOriginType().name());
378         Either<Resource, StorageOperationStatus> getOriginRes = toscaOperationFacade.getLatestCertifiedByToscaResourceName(instance.getToscaComponentName(), vertexType, JsonParseFlagEnum.ParseMetadata);
379         if (getOriginRes.isRight()) {
380             log.error(FAILED_TO_UPGRADE_COMPONENT, component.getComponentType().getValue(), component.getName(), component.getInvariantUUID(), component.getVersion(), "toscaOperationFacade.getLatestCertifiedByToscaResourceName", getOriginRes.right().value());
381             outputHandler.addRecord(component.getComponentType().name(), component.getName(), component.getInvariantUUID(), component.getUniqueId(), MigrationResult.MigrationStatus.FAILED.name(), getOriginRes.right().value());
382             return false;
383         }
384         latestOriginResourceVersions.put(instance.getToscaComponentName(), getOriginRes.left().value().getVersion());
385         return true;
386     }
387
388     private boolean shouldUpgrade(org.openecomp.sdc.be.model.Component component) {
389         if(CollectionUtils.isNotEmpty(component.getComponentInstances())) {
390             if (containsProxyOrAllottedVF(component)) {
391                 return false;
392             }
393             for(ComponentInstance instance : component.getComponentInstances()){
394                 if(isGreater(latestOriginResourceVersions.get(instance.getToscaComponentName()), instance.getComponentVersion())){
395                     log.info("The service with name {}, invariantUUID {}, version {}, contains instance {} from outdated version of origin {} {} , than the service should be upgraded. ", component.getName(), component.getInvariantUUID(), component.getVersion(), instance.getName(), instance.getComponentName(), instance.getComponentVersion());
396                     return true;
397                 }
398             }
399         }
400         return false;
401     }
402
403     private boolean containsProxyOrAllottedVF(org.openecomp.sdc.be.model.Component component) {
404         return !component.getComponentInstances()
405                 .stream()
406                 .filter(i->isProxyOrAllottedVF(i, component.getUniqueId()))
407                 .collect(Collectors.toList()).isEmpty();
408     }
409
410     private boolean isProxyOrAllottedVF(ComponentInstance instance, String uniqueId) {
411         if (instance.getOriginType() == OriginTypeEnum.ServiceProxy) {
412             keepProxyServiceContainerIfSupported(uniqueId);
413             return true;
414         }
415         if (isAllottedResource(instance.getActualComponentUid())) {
416             keepAllottedVfContainerIfSupported(uniqueId);
417             return true;
418         }
419         return false;
420     }
421
422     private void keepAllottedVfContainerIfSupported(final String uniqueId) {
423         if (isAllottedAndProxySupported && !allottedVfContainers.contains(uniqueId)) {
424             log.info("Add a service with uniqueId {} to allotted VF containers container list", uniqueId);
425             allottedVfContainers.add(uniqueId);
426         }
427     }
428
429     private void keepProxyServiceContainerIfSupported(final String uniqueId) {
430         if (isAllottedAndProxySupported && !proxyServiceContainers.contains(uniqueId)) {
431             log.info("Add a service with uniqueId {} to proxy service container list", uniqueId);
432             proxyServiceContainers.add(uniqueId);
433         }
434     }
435
436     private boolean upgradeService(org.openecomp.sdc.be.model.Component service) {
437         String serviceName = service.getName();
438         String serviceUuid = service.getUUID();
439         log.info("Starting upgrade Service with name {}, invariantUUID {}, version {} upon upgrade migration 1710 process. ", serviceName, service.getInvariantUUID(), service.getVersion());
440         Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> checkouRes = checkOutComponent(service);
441         if (checkouRes.isRight()) {
442             log.error(FAILED_TO_UPGRADE_COMPONENT, service.getComponentType().getValue(), serviceName, service.getInvariantUUID(), service.getVersion(), "lifecycleBusinessLogic.changeComponentState", checkouRes.right().value().getFormattedMessage());
443             outputHandler.addRecord(service.getComponentType().name(), serviceName, serviceUuid, service.getUniqueId(), MigrationResult.MigrationStatus.FAILED.name(), checkouRes.right().value().getFormattedMessage());
444             return false;
445         }
446         Either<org.openecomp.sdc.be.model.Component, ResponseFormat> updateCompositionRes = updateComposition(checkouRes.left().value());
447         if (updateCompositionRes.isRight()) {
448             log.error(FAILED_TO_UPGRADE_COMPONENT, service.getComponentType().getValue(), serviceName, service.getInvariantUUID(), service.getVersion(), "updateComposition", updateCompositionRes.right().value().getFormattedMessage());
449             outputHandler.addRecord(checkouRes.left().value().getComponentType().name(), checkouRes.left().value().getName(), checkouRes.left().value().getUUID(), checkouRes.left().value().getUniqueId(), MigrationResult.MigrationStatus.FAILED.name(), updateCompositionRes.right().value().getFormattedMessage());
450             return false;
451         }
452         Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> certifyRes = performFullCertification(checkouRes.left().value());
453         if (certifyRes.isRight()) {
454             log.error(FAILED_TO_UPGRADE_COMPONENT, service.getComponentType().getValue(), serviceName, service.getInvariantUUID(), service.getVersion(), "performFullCertification", certifyRes.right().value().getFormattedMessage());
455             outputHandler.addRecord(checkouRes.left().value().getComponentType().name(), checkouRes.left().value().getName(), checkouRes.left().value().getInvariantUUID(), checkouRes.left().value().getUniqueId(), MigrationResult.MigrationStatus.FAILED.name(), certifyRes.right().value().getFormattedMessage());
456             return false;
457         }
458         outputHandler.addRecord(checkouRes.left().value().getComponentType().name(), checkouRes.left().value().getName(), serviceUuid, checkouRes.left().value().getUniqueId(), MigrationResult.MigrationStatus.COMPLETED.name(), UpgradeStatus.UPGRADED);
459         return true;
460     }
461
462     private Either<org.openecomp.sdc.be.model.Component, ResponseFormat> updateComposition(org.openecomp.sdc.be.model.Component component) {
463         if (component != null && component.getComponentInstances() != null) {
464             Either<ComponentInstance, ResponseFormat> upgradeInstanceRes;
465             for (ComponentInstance instance : component.getComponentInstances()) {
466                 upgradeInstanceRes = upgradeInstance(component, instance);
467                 if (upgradeInstanceRes.isRight()) {
468                     log.error(FAILED_TO_UPGRADE_COMPONENT, component.getComponentType().getValue(), component.getName(), component.getInvariantUUID(), component.getVersion(), "upgradeInstance", upgradeInstanceRes.right().value().getFormattedMessage());
469                     outputHandler.addRecord(component.getComponentType().name(), component.getName(), component.getUUID(), component.getUniqueId(), MigrationResult.MigrationStatus.FAILED.name(), upgradeInstanceRes.right().value().getFormattedMessage());
470                     return Either.right(upgradeInstanceRes.right().value());
471                 }
472             }
473         }
474         return Either.left(component);
475     }
476
477     private Either<ComponentInstance, ResponseFormat> upgradeInstance(org.openecomp.sdc.be.model.Component component, ComponentInstance instance) {
478         log.info("Starting upgrade {} instance {} upon upgrade migration 1710 process. ", component.getComponentType().getValue(), instance.getName());
479         ComponentInstance newComponentInstance = new ComponentInstance(instance);
480         if (instance.getOriginType() == OriginTypeEnum.ServiceProxy) {
481             return upgradeServiceProxyInstance(component, instance, newComponentInstance);
482         }
483         return upgradeResourceInstance(component, instance, newComponentInstance);
484     }
485
486     private Either<ComponentInstance, ResponseFormat> upgradeResourceInstance(org.openecomp.sdc.be.model.Component component, ComponentInstance instance, ComponentInstance newComponentInstance) {
487
488         log.info("Starting upgrade {} instance {} upon upgrade migration 1710 process. ", component.getComponentType().getValue(), instance.getName());
489         Either<ComponentInstance, ResponseFormat> upgradeInstanceRes = null;
490         VertexTypeEnum vertexType = ModelConverter.getVertexType(instance.getOriginType().name());
491         Either<Resource, StorageOperationStatus> getOriginRes = toscaOperationFacade.getLatestCertifiedByToscaResourceName(instance.getToscaComponentName(), vertexType, JsonParseFlagEnum.ParseMetadata);
492         if(getOriginRes.isRight()){
493             log.info("Upgrade of {} instance {} upon upgrade migration 1710 process failed due to a reason {}. ",
494                     component.getComponentType().getValue(), instance.getName(), getOriginRes.right().value());
495             upgradeInstanceRes = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(getOriginRes.right().value(), instance.getOriginType().getComponentType())));
496         }
497         if(upgradeInstanceRes == null) {
498             copyComponentNameAndVersionToNewInstance(newComponentInstance, getOriginRes.left().value());
499
500             if(isGreater(getOriginRes.left().value().getVersion(), instance.getComponentVersion())){
501                 upgradeInstanceRes = changeAssetVersion(component, instance, newComponentInstance);
502             }
503             if((upgradeInstanceRes == null || upgradeInstanceRes.isLeft()) && isAllottedResource(instance.getComponentUid()) && MapUtils.isNotEmpty(component.getComponentInstancesProperties())){
504                 ComponentInstance instanceToUpdate = upgradeInstanceRes == null ? instance : upgradeInstanceRes.left().value();
505                 upgradeInstanceRes = Either.left(updateServiceUuidProperty(component, instanceToUpdate, component.getComponentInstancesProperties().get(instance.getUniqueId())));
506             }
507         }
508         //upgrade nodes contained by CVFC
509         if(upgradeInstanceRes == null && isVfcUpgradeRequired && newComponentInstance.getOriginType() == OriginTypeEnum.CVFC &&
510                 !upgradeVf(getOriginRes.left().value().getUniqueId(), false, true)) {
511             upgradeInstanceRes = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
512         }
513         if(upgradeInstanceRes == null){
514             upgradeInstanceRes = Either.left(instance);
515         }
516         log.info("Upgrade of {} instance {} upon upgrade migration 1710 process finished successfully. ",
517                 component.getComponentType().getValue(), instance.getName());
518         return upgradeInstanceRes;
519     }
520
521     private void copyComponentNameAndVersionToNewInstance(ComponentInstance newComponentInstance, Resource originResource) {
522         newComponentInstance.setComponentName(originResource.getName());
523         newComponentInstance.setComponentUid(originResource.getUniqueId());
524         newComponentInstance.setComponentVersion(originResource.getVersion());
525         newComponentInstance.setToscaComponentName(originResource.getToscaResourceName());
526     }
527
528     private ComponentInstance updateServiceUuidProperty(org.openecomp.sdc.be.model.Component component, ComponentInstance instance, List<ComponentInstanceProperty> instanceProperties){
529         if(isAllottedResource(instance.getComponentUid()) && instanceProperties != null){
530             Optional<ComponentInstanceProperty> propertyUuid = instanceProperties.stream().filter(p->p.getName().equals(SERVICE_UUID_RPOPERTY)).findFirst();
531             Optional<ComponentInstanceProperty> propertyInvariantUuid = instanceProperties.stream().filter(p->p.getName().equals(SERVICE_INVARIANT_UUID_RPOPERTY)).findFirst();
532             if(propertyUuid.isPresent() && propertyInvariantUuid.isPresent()){
533                 String serviceInvariantUUID = propertyInvariantUuid.get().getValue();
534                 Either<List<GraphVertex>, JanusGraphOperationStatus> getLatestOriginServiceRes = getLatestCertifiedService(serviceInvariantUUID);
535                 if (getLatestOriginServiceRes.isRight()) {
536                     return instance;
537                 }
538                 propertyUuid.get().setValue((String) getLatestOriginServiceRes.left().value().get(0).getJsonMetadataField(JsonPresentationFields.UUID));
539                 componentInstanceBusinessLogic.createOrUpdatePropertiesValues(component.getComponentType(), component.getUniqueId(), instance.getUniqueId(), Lists.newArrayList(propertyUuid.get()), user.getUserId())
540                         .right()
541                         .forEach(e -> log.debug("Failed to update property {} of the instance {} of the component {}. ", SERVICE_UUID_RPOPERTY, instance.getUniqueId(), component.getName()));
542             }
543         }
544         return instance;
545     }
546
547     private boolean isAllottedResource(String uniqueId){
548         ComponentParametersView filters = new ComponentParametersView(true);
549         filters.setIgnoreCategories(false);
550         Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getResourceRes = toscaOperationFacade.getToscaElement(uniqueId, filters);
551         if(getResourceRes.isRight()){
552             return false;
553         }
554         if(getResourceRes.left().value().getCategories() != null && getResourceRes.left().value().getCategories().get(0)!= null){
555             return ALLOTTED_RESOURCE_NAME.equals(getResourceRes.left().value().getCategories().get(0).getName());
556         }
557         return false;
558     }
559
560     private boolean isAllottedVf(org.openecomp.sdc.be.model.Component component){
561         if(component.getComponentType() != ComponentTypeEnum.RESOURCE || ((Resource)component).getResourceType() != ResourceTypeEnum.VF){
562             return false;
563         }
564         return isAllottedResource(component.getUniqueId());
565     }
566
567     private Either<ComponentInstance, ResponseFormat> upgradeServiceProxyInstance(org.openecomp.sdc.be.model.Component component, ComponentInstance instance, ComponentInstance newComponentInstance) {
568         Either<List<GraphVertex>, JanusGraphOperationStatus> getLatestOriginServiceRes = getLatestCertifiedService(instance.getSourceModelInvariant());
569         if (getLatestOriginServiceRes.isRight()) {
570             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getLatestOriginServiceRes.right().value()), instance.getOriginType().getComponentType())));
571         }
572         ModelConverter.getVertexType(instance.getOriginType().name());
573         Either<Resource, StorageOperationStatus> getOriginRes = toscaOperationFacade.getLatestByName(instance.getComponentName());
574         if(getOriginRes.isRight()){
575             log.info("Upgrade of {} instance {} upon upgrade migration 1710 process failed due to a reason {}. ",
576                     component.getComponentType().getValue(), instance.getName(), getOriginRes.right().value());
577             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(getOriginRes.right().value(), instance.getOriginType().getComponentType())));
578         }
579         newComponentInstance.setComponentUid((String) getLatestOriginServiceRes.left().value().get(0).getJsonMetadataField(JsonPresentationFields.UNIQUE_ID));
580         return changeAssetVersion(component, instance, newComponentInstance);
581     }
582
583     private Either<List<GraphVertex>, JanusGraphOperationStatus> getLatestCertifiedService(String invariantUUID) {
584
585         Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
586         propertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.SERVICE.name());
587         propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
588         propertiesToMatch.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
589         propertiesToMatch.put(GraphPropertyEnum.INVARIANT_UUID, invariantUUID);
590         Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
591         propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
592         return janusGraphDao
593             .getByCriteria(VertexTypeEnum.TOPOLOGY_TEMPLATE, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseMetadata);
594     }
595
596     private Either<ComponentInstance, ResponseFormat> changeAssetVersion(org.openecomp.sdc.be.model.Component containerComponent, ComponentInstance instance, ComponentInstance newComponentInstance) {
597         return componentInstanceBusinessLogic.changeComponentInstanceVersion(ComponentTypeEnum.SERVICE_PARAM_NAME, containerComponent.getUniqueId(), instance.getUniqueId(), user.getUserId(), newComponentInstance);
598     }
599
600     private boolean upgradeNodeTypes() {
601         log.info("Starting upgrade node types upon upgrade migration 1710 process. ");
602         if (nodeTypes != null && !nodeTypes.isEmpty()) {
603             Either<List<String>, JanusGraphOperationStatus> getRes = getAllLatestCertifiedComponentUids(VertexTypeEnum.NODE_TYPE, ComponentTypeEnum.RESOURCE);
604             if (getRes.isRight()) {
605                 return false;
606             }
607             for (String toscaResourceName : nodeTypes) {
608                 if (!upgradeNodeType(toscaResourceName, getRes.left().value())) {
609                     return false;
610                 }
611             }
612         }
613         else {
614             log.info("No node types for upgrade are configured");
615         }
616         return true;
617     }
618
619     private boolean upgradeNodeType(String toscaResourceName, List<String> allNodeTypes) {
620         Either<List<GraphVertex>, StorageOperationStatus> status = getLatestByName(GraphPropertyEnum.TOSCA_RESOURCE_NAME, toscaResourceName);
621         if (status.isRight()) {
622             log.error("Failed to find node type {} ", toscaResourceName);
623             return false;
624         }
625         List<GraphVertex> vList = status.left().value();
626         for (GraphVertex vertex : vList) {
627             StorageOperationStatus updateRes = upgradeNodeType(vertex, allNodeTypes);
628             if (updateRes != StorageOperationStatus.OK) {
629                 return false;
630             }
631         }
632         return true;
633     }
634
635     private boolean upgradeVFs() {
636         log.info("Starting upgrade VFs upon upgrade migration 1710 process. ");
637         Either<List<String>, JanusGraphOperationStatus> getVfsRes = getAllLatestCertifiedComponentUids(VertexTypeEnum.TOPOLOGY_TEMPLATE, ComponentTypeEnum.RESOURCE);
638         if (getVfsRes.isRight()) {
639             log.info(UPGRADE_VFS_FAILED);
640             return false;
641         }
642         return upgradeVFs(getVfsRes.left().value(), false);
643     }
644
645     private boolean upgradeAllottedVFs() {
646         log.info("Starting upgrade {} allotted Vfs with upon upgrade migration 1710 process. ", vfAllottedResources.size());
647         return upgradeVFs(vfAllottedResources, true);
648     }
649
650     boolean upgradeVFs(List<String> resourceList, boolean isAllottedVfsUpgrade) {
651         for (String currUid : resourceList) {
652             boolean result = true;
653             try {
654                 result = upgradeVf(currUid, isAllottedVfsUpgrade, false);
655                 if (!result && !skipIfUpgradeVfFailed) {
656                     return false;
657                 }
658             } catch (Exception e) {
659                 log.error("The exception {} occurred upon upgrade VFs. ", e.getMessage());
660                 log.debug("The exception occurred upon upgrade VFs:", e);
661                 result = false;
662                 if (!skipIfUpgradeVfFailed) {
663                     return false;
664                 }
665             }
666             finally {
667                 if (result) {
668                     log.info("Resource upgrade finished successfully: uniqueId {} ", currUid);
669                     janusGraphDao.commit();
670                 }
671                 else {
672                     log.error("Failed to upgrade resource with uniqueId {} ", currUid);
673                     janusGraphDao.rollback();
674                 }
675                 markCheckedOutResourceAsDeletedIfUpgradeFailed(currUid, result);
676             }
677         }
678         log.info("Upgrade VFs upon upgrade migration 1710 process finished successfully. ");
679         return true;
680     }
681
682     private boolean upgradeVf(String uniqueId, boolean allottedVfsUpgrade, boolean isInstance) {
683         log.info("Starting upgrade VF with uniqueId {} upon upgrade migration 1710 process. ", uniqueId);
684         Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getRes = toscaOperationFacade.getToscaElement(uniqueId);
685         if (getRes.isRight()) {
686             log.debug("Failed to fetch VF with uniqueId {} upon upgrade migration 1710 process. ", uniqueId);
687             outputHandler.addRecord(ComponentTypeEnum.RESOURCE.name(), UNKNOWN, UNKNOWN, uniqueId, MigrationResult.MigrationStatus.FAILED.name(), getRes.right().value());
688             return false;
689         }
690         if(!allottedVfsUpgrade && isAllottedVf(getRes.left().value())){
691             keepAllottedResourceIfSupported(uniqueId);
692             return true;
693         }
694         if (StringUtils.isNotEmpty(getRes.left().value().getCsarUUID())) {
695             log.info("Going to fetch the latest version of VSP with csarUUID {} upon upgrade migration 1710 process. ", getRes.left().value().getCsarUUID());
696             Either<String, StorageOperationStatus> latestVersionRes = csarOperation.getCsarLatestVersion(getRes.left().value().getCsarUUID(), user);
697             if (latestVersionRes.isRight()) {
698                 log.debug("Failed to fetch the latest version of VSP with csarUUID {} upon upgrade migration 1710 process. ", getRes.left().value().getCsarUUID());
699                 outputHandler.addRecord(getRes.left().value().getComponentType().name(), getRes.left().value().getName(), getRes.left().value().getUUID(), getRes.left().value().getUniqueId(), MigrationResult.MigrationStatus.FAILED.name(), latestVersionRes.right().value());
700                 return false;
701             }
702             if (isGreater(latestVersionRes.left().value(), getRes.left().value().getCsarVersion())) {
703                 return upgradeVfWithLatestVsp(getRes.left().value(), latestVersionRes.left().value(), isInstance);
704             }
705             if (isVfcUpgradeRequired) {
706                 return upgradeComponentWithLatestGeneric(getRes.left().value(), isInstance);
707             }
708             log.warn("Warning: No need to upgrade VF with name {}, invariantUUID {}, version {} and VSP version {}. No new version of VSP. ", getRes.left().value().getName(), getRes.left().value().getInvariantUUID(), getRes.left().value().getVersion(), getRes.left().value().getCsarVersion());
709             return true;
710         }
711         else {
712             return upgradeComponentWithLatestGeneric(getRes.left().value(), isInstance);
713         }
714     }
715
716     private void keepAllottedResourceIfSupported(final String uniqueId) {
717         if (isAllottedAndProxySupported && !vfAllottedResources.contains(uniqueId)) {
718             log.info("Add a resource with uniqueId {} to allotted resource list", uniqueId);
719             vfAllottedResources.add(uniqueId);
720         }
721     }
722
723     private boolean upgradeVfWithLatestVsp(org.openecomp.sdc.be.model.Component vf, String latestVersion, boolean isInstance) {
724         log.info("Starting upgrade vf with name {}, invariantUUID {}, version {} and latest VSP version {} upon upgrade migration 1710 process. ", vf.getName(), vf.getInvariantUUID(), vf.getVersion(), latestVersion);
725         Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> checkouRes = checkOutComponent(vf);
726         if (checkouRes.isRight()) {
727             outputHandler.addRecord(vf.getComponentType().name(), vf.getName(), vf.getUUID(), vf.getUniqueId(), MigrationResult.MigrationStatus.FAILED.name(), checkouRes.right().value().getFormattedMessage());
728             return false;
729         }
730         Resource resourceToUpdate = new Resource(((Resource) checkouRes.left().value()).getComponentMetadataDefinition());
731         resourceToUpdate.setDerivedFromGenericType(((Resource) checkouRes.left().value()).getDerivedFromGenericType());
732         resourceToUpdate.setDerivedFromGenericVersion(((Resource) checkouRes.left().value()).getDerivedFromGenericVersion());
733         resourceToUpdate.setCsarVersion(Double.toString(Double.parseDouble(latestVersion)));
734         resourceToUpdate.setCategories(((Resource)checkouRes.left().value()).getCategories());
735         try {
736             Resource updateResourceFromCsarRes = resourceBusinessLogic.validateAndUpdateResourceFromCsar(resourceToUpdate, user, null, null, resourceToUpdate.getUniqueId());
737         } catch(ByResponseFormatComponentException e){
738             outputHandler.addRecord(resourceToUpdate.getComponentType().name(), resourceToUpdate.getName(), resourceToUpdate.getUUID(), resourceToUpdate.getUniqueId(), MigrationResult.MigrationStatus.FAILED.name(), e.getResponseFormat().getFormattedMessage());
739             log.info("Failed to update vf with name {}, invariantUUID {}, version {} and latest VSP {}. ", vf.getName(), vf.getInvariantUUID(), vf.getVersion(), latestVersion);
740             return false;
741         }
742         Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> certifyRes = performFullCertification(checkouRes.left().value());
743         if (certifyRes.isRight()) {
744             log.info(FAILED_TO_CHANGE_STATE_OF_COMPONENT, checkouRes.left().value().getName(), checkouRes.left().value().getInvariantUUID(), checkouRes.left().value().getVersion(), LifeCycleTransitionEnum.CERTIFY);
745             outputHandler.addRecord(checkouRes.left().value().getComponentType().name(), checkouRes.left().value().getName(), checkouRes.left().value().getInvariantUUID(), checkouRes.left().value().getUniqueId(), MigrationResult.MigrationStatus.FAILED.name(), certifyRes.right().value().getFormattedMessage());
746             return false;
747         }
748         log.info("Full certification of vf with name {}, invariantUUID {}, version {} finished . ", vf.getName(), vf.getInvariantUUID(), vf.getVersion(), latestVersion);
749         outputHandler.addRecord(certifyRes.left().value().getComponentType().name(), certifyRes.left().value().getName(), certifyRes.left().value().getUUID(), certifyRes.left().value().getUniqueId(), MigrationResult.MigrationStatus.COMPLETED.name(), getVfUpgradeStatus(true, isInstance));
750         return true;
751     }
752
753     private boolean upgradeComponentWithLatestGeneric(org.openecomp.sdc.be.model.Component component, boolean isInstance) {
754         String derivedFromGenericType = component.getDerivedFromGenericType();
755         String derivedFromGenericVersion = component.getDerivedFromGenericVersion();
756         org.openecomp.sdc.be.model.Component updatedComponent = component;
757         if (failedToFindDerivedResourcesOfNodeType(component, derivedFromGenericType, derivedFromGenericVersion)) {
758             return false;
759         }
760         if (StringUtils.isEmpty(derivedFromGenericType) ||
761                 latestVersionExists(latestGenericTypes.get(derivedFromGenericType), derivedFromGenericVersion) ||
762                 isVfcUpgradeRequired ||
763                 isAllottedAndProxySupported) {
764             if (StringUtils.isNotEmpty(derivedFromGenericType)) {
765                 log.info("Newer version {} of derived from generic type {} exists. ", latestGenericTypes.get(derivedFromGenericType).getJsonMetadataField(JsonPresentationFields.VERSION), derivedFromGenericType);
766             }
767             else {
768                 log.info("The vf resource with name {}, invariantUUID {}, version {},  has an empty derivedFromGenericType field. ", component.getName(), component.getInvariantUUID(), component.getVersion());
769             }
770             updatedComponent = checkOutAndCertifyComponent(component);
771         } else {
772             log.info("The version {} of derived from generic type {} is up to date. No need to upgrade component with name {}, invariantUUID {} and version {}. ", latestGenericTypes.get(derivedFromGenericType), derivedFromGenericType, component.getName(), component.getInvariantUUID(), component.getVersion());
773         }
774         if (updatedComponent != null) {
775             log.info(UPGRADE_COMPONENT_SUCCEEDED, component.getComponentType().getValue(), component.getName(), component.getInvariantUUID(), component.getVersion());
776             outputHandler.addRecord(updatedComponent.getComponentType().name(), updatedComponent.getName(), updatedComponent.getUUID(), updatedComponent.getUniqueId(), MigrationResult.MigrationStatus.COMPLETED.name(),
777                     getVfUpgradeStatus(!updatedComponent.equals(component), isInstance));
778         }
779         return true;
780     }
781
782     private org.openecomp.sdc.be.model.Component checkOutAndCertifyComponent(org.openecomp.sdc.be.model.Component component) {
783
784         log.info("Starting to perform check out of vf with name {}, invariantUUID {}, version {}. ", component.getName(), component.getInvariantUUID(), component.getVersion());
785         Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> checkoutRes = checkOutComponent(component);
786         if (checkoutRes.isRight()) {
787             log.error(FAILED_TO_CHANGE_STATE_OF_COMPONENT, component.getName(), component.getInvariantUUID(), component.getVersion(), LifeCycleTransitionEnum.CHECKOUT);
788             outputHandler.addRecord(component.getComponentType().name(), component.getName(), component.getInvariantUUID(), component.getUniqueId(), MigrationResult.MigrationStatus.FAILED.name(), checkoutRes.right().value().getFormattedMessage());
789             return null;
790         }
791
792         if (!updateCompositionFailed(component, checkoutRes.left().value())) {
793             return null;
794         }
795         Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> certifyRes = performFullCertification(checkoutRes.left().value());
796         if (certifyRes.isRight()) {
797             log.error(FAILED_TO_UPGRADE_COMPONENT, component.getComponentType().getValue(), component.getName(), component.getInvariantUUID(), component.getVersion(), "performFullCertification", certifyRes.right().value());
798             outputHandler.addRecord(checkoutRes.left().value().getComponentType().name(), checkoutRes.left().value().getName(), checkoutRes.left().value().getInvariantUUID(), checkoutRes.left().value().getUniqueId(), MigrationResult.MigrationStatus.FAILED.name(), certifyRes.right().value().getFormattedMessage());
799             return null;
800         }
801         return certifyRes.left().value();
802     }
803
804     private boolean failedToFindDerivedResourcesOfNodeType(org.openecomp.sdc.be.model.Component component, String derivedFromGenericType, String derivedFromGenericVersion) {
805         if (StringUtils.isNotEmpty(derivedFromGenericType) && !latestGenericTypes.containsKey(derivedFromGenericType)) {
806             log.info("Starting upgrade vf with name {}, invariantUUID {}, version {}, latest derived from generic type {}, latest derived from generic version {}. ", component.getName(), component.getInvariantUUID(), component.getVersion(), derivedFromGenericType, derivedFromGenericVersion);
807             log.info("Starting to fetch latest generic node type {}. ", derivedFromGenericType);
808             Either<List<GraphVertex>, JanusGraphOperationStatus> getDerivedRes = findDerivedResources(derivedFromGenericType);
809             if (getDerivedRes.isRight()) {
810                 outputHandler.addRecord(component.getComponentType().name(), component.getName(), component.getInvariantUUID(), component.getUniqueId(), MigrationResult.MigrationStatus.FAILED.name(), getDerivedRes.right().value());
811                 log.info("Failed to upgrade component with name {}, invariantUUID {}, version {} and latest generic. Status is {}. ", component.getName(), component.getInvariantUUID(), component.getVersion(), derivedFromGenericType);
812                 return true;
813             }
814             latestGenericTypes.put(derivedFromGenericType, getDerivedRes.left().value().get(0));
815         }
816         return false;
817     }
818
819     private boolean updateCompositionFailed(org.openecomp.sdc.be.model.Component component, org.openecomp.sdc.be.model.Component checkoutResource) {
820         //try to update included VFCs, if it is either required as per configuration or an allotted resource
821         if ((isVfcUpgradeRequired && CollectionUtils.isNotEmpty(checkoutResource.getComponentInstances())) || isAllottedAndProxySupported) {
822             log.info("VFC upgrade is required: updating components of vf with name {}, invariantUUID {}, version {}. ", component.getName(), component.getInvariantUUID(), component.getVersion());
823             Either<org.openecomp.sdc.be.model.Component, ResponseFormat> updateCompositionRes = updateComposition(checkoutResource);
824             if (updateCompositionRes.isRight()) {
825                 if (log.isErrorEnabled()) {
826                     log.error(FAILED_TO_UPGRADE_COMPONENT, checkoutResource.getComponentType().name(), checkoutResource.getName(), checkoutResource.getInvariantUUID(), checkoutResource.getVersion(), "updateComposition", updateCompositionRes.right().value().getFormattedMessage());
827                 }
828                 outputHandler.addRecord(checkoutResource.getComponentType().name(), checkoutResource.getName(), checkoutResource.getUUID(), checkoutResource.getUniqueId(), MigrationResult.MigrationStatus.FAILED.name(), updateCompositionRes.right().value().getFormattedMessage());
829                 return true;
830             }
831         }
832         return false;
833     }
834
835     private StorageOperationStatus upgradeNodeType(GraphVertex nodeTypeV, List<String> allCertifiedUids) {
836         StorageOperationStatus result = StorageOperationStatus.OK;
837         log.info("Starting upgrade node type with name {}, invariantUUID {}, version{}. ", nodeTypeV.getMetadataProperty(GraphPropertyEnum.NAME), nodeTypeV.getMetadataProperty(GraphPropertyEnum.INVARIANT_UUID), nodeTypeV.getMetadataProperty(GraphPropertyEnum.VERSION));
838         log.info("Starting to find derived to for node type with name {}, invariantUUID {}, version{}. ", nodeTypeV.getMetadataProperty(GraphPropertyEnum.NAME), nodeTypeV.getMetadataProperty(GraphPropertyEnum.INVARIANT_UUID), nodeTypeV.getMetadataProperty(GraphPropertyEnum.VERSION));
839         Either<List<GraphVertex>, JanusGraphOperationStatus> parentResourceRes = janusGraphDao
840             .getParentVertecies(nodeTypeV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.ParseMetadata);
841         if (parentResourceRes.isRight() && parentResourceRes.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
842             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(parentResourceRes.right().value());
843
844         }
845         List<GraphVertex> derivedResourcesUid = getAllDerivedGraphVertices(allCertifiedUids, parentResourceRes);
846         String uniqueId = (String) nodeTypeV.getJsonMetadataField(JsonPresentationFields.UNIQUE_ID);
847
848         Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getRes = toscaOperationFacade.getToscaElement(uniqueId);
849         if (getRes.isRight()) {
850             log.info("failed to fetch element with uniqueId {} ", uniqueId);
851             return getRes.right().value();
852         }
853
854         Resource nodeType = (Resource)getRes.left().value();
855         if (!upgradedNodeTypesMap.containsKey(nodeType.getToscaResourceName()) && !nodeTypes.stream().anyMatch(p -> p.equals(nodeType.getToscaResourceName()))
856             && !isNodeTypeUpgradeSucceeded((Resource) getRes.left().value())) {
857                 return StorageOperationStatus.GENERAL_ERROR;
858         }
859         for (GraphVertex chV : derivedResourcesUid) {
860             result = upgradeNodeType(chV, allCertifiedUids);
861             log.info("Upgrade node type with name {}, invariantUUID {}, version {} has been finished with the status {}", chV.getMetadataProperty(GraphPropertyEnum.NAME), chV.getMetadataProperty(GraphPropertyEnum.INVARIANT_UUID), chV.getMetadataProperty(GraphPropertyEnum.VERSION), result);
862         }
863         return result;
864     }
865
866     private boolean isNodeTypeUpgradeSucceeded(Resource nodeType) {
867         log.info("Starting to perform check out of node type with name {}, invariantUUID {}, version {}. ", nodeType.getName(), nodeType.getInvariantUUID(), nodeType.getVersion());
868         Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> checkouRes =
869                 lifecycleBusinessLogic.changeComponentState(nodeType.getComponentType(), nodeType.getUniqueId(), user, LifeCycleTransitionEnum.CHECKOUT, changeInfo, true, false);
870         if (checkouRes.isRight()) {
871             log.info("Failed to check out node type with name {}, invariantUUID {} due to {}", nodeType.getName(), nodeType.getInvariantUUID(), checkouRes.right().value());
872             return false;
873         }
874         if (performFullCertification(checkouRes.left().value()).isLeft()) {
875             upgradedNodeTypesMap.put(nodeType.getToscaResourceName(), checkouRes.left().value());
876             janusGraphDao.commit();
877             return true;
878         }
879         return false;
880     }
881
882     private List<GraphVertex> getAllDerivedGraphVertices(List<String> allCertifiedUids, Either<List<GraphVertex>, JanusGraphOperationStatus> parentResources) {
883         List<GraphVertex> derivedResourcesUid = new ArrayList<>();
884
885         if (parentResources.isLeft()) {
886             for (GraphVertex chV : parentResources.left().value()) {
887                 Optional<String> op = allCertifiedUids.stream().filter(id -> id.equals((String) chV.getJsonMetadataField(JsonPresentationFields.UNIQUE_ID))).findAny();
888                 if (op.isPresent()) {
889                     derivedResourcesUid.add(chV);
890                 }
891             }
892         }
893         return derivedResourcesUid;
894     }
895
896     private Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> performFullCertification(org.openecomp.sdc.be.model.Component component) {
897         log.info("Starting to perform full certification of {} with name {}, invariantUUID {}, version {}. ",
898                 component.getComponentType().getValue(), component.getName(), component.getInvariantUUID(), component.getVersion());
899
900         Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> changeStateEither = lifecycleBusinessLogic.changeComponentState(component.getComponentType(), component.getUniqueId(), user, LifeCycleTransitionEnum.CERTIFICATION_REQUEST, changeInfo, true, false);
901         if (changeStateEither.isRight()) {
902             log.info(FAILED_TO_CHANGE_STATE_OF_COMPONENT, component.getName(), component.getInvariantUUID(), component.getVersion(), LifeCycleTransitionEnum.CERTIFICATION_REQUEST);
903             return changeStateEither;
904         }
905         changeStateEither = lifecycleBusinessLogic.changeComponentState(component.getComponentType(), changeStateEither.left().value().getUniqueId(), user, LifeCycleTransitionEnum.START_CERTIFICATION, changeInfo, true, false);
906         if (changeStateEither.isRight()) {
907             log.info(FAILED_TO_CHANGE_STATE_OF_COMPONENT, component.getName(), component.getInvariantUUID(), component.getVersion(), LifeCycleTransitionEnum.START_CERTIFICATION);
908             return changeStateEither;
909         }
910         changeStateEither = lifecycleBusinessLogic.changeComponentState(component.getComponentType(), changeStateEither.left().value().getUniqueId(), user, LifeCycleTransitionEnum.CERTIFY, changeInfo, true, false);
911         if (changeStateEither.isRight()) {
912             log.info(FAILED_TO_CHANGE_STATE_OF_COMPONENT, component.getName(), component.getInvariantUUID(), component.getVersion(), LifeCycleTransitionEnum.CERTIFY);
913         } else {
914             log.info("Full certification of {} with name {}, invariantUUID {}, version {} finished successfully",
915                     changeStateEither.left().value().getComponentType().getValue(), changeStateEither.left().value().getName(),
916                     changeStateEither.left().value().getInvariantUUID(), changeStateEither.left().value().getVersion());
917         }
918         return changeStateEither;
919     }
920
921     private Either<List<GraphVertex>, JanusGraphOperationStatus> findDerivedResources(String parentResource) {
922         Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
923         propertiesToMatch.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
924
925         propertiesToMatch.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, parentResource);
926         propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
927
928         return janusGraphDao
929             .getByCriteria(VertexTypeEnum.NODE_TYPE, propertiesToMatch, JsonParseFlagEnum.ParseMetadata);
930     }
931
932     private boolean latestVersionExists(GraphVertex latestDerivedFrom, String currentVersion) {
933         return isGreater((String) latestDerivedFrom.getJsonMetadataField(JsonPresentationFields.VERSION), currentVersion);
934     }
935
936     private boolean isGreater(String latestVersion, String currentVersion) {
937         if (latestVersion != null && currentVersion == null) {
938             return true;
939         }
940         if (latestVersion == null) {
941             return false;
942         }
943         return Double.parseDouble(latestVersion) > Double.parseDouble(currentVersion);
944     }
945
946     private Either<List<String>, JanusGraphOperationStatus> getAllLatestCertifiedComponentUids(VertexTypeEnum vertexType, ComponentTypeEnum componentType) {
947         log.info("Starting to fetch all latest certified not checked out components with type {} upon upgrade migration 1710 process", componentType);
948         Either<List<String>, JanusGraphOperationStatus> result = null;
949         Map<String, String> latestCertifiedMap = new HashMap<>();
950         Map<String, String> latestNotCertifiedMap = new HashMap<>();
951
952         Either<List<GraphVertex>, JanusGraphOperationStatus> getComponentsRes = getAllLatestComponents(vertexType, componentType);
953         if (getComponentsRes.isRight() && getComponentsRes.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
954             log.error("Failed to fetch all latest certified not checked out components with type {}. Status is {}. ", componentType, getComponentsRes.right().value());
955             result = Either.right(getComponentsRes.right().value());
956         }
957         if (getComponentsRes.isRight()) {
958             result = Either.left(new ArrayList<>());
959         }
960         if (result == null) {
961             for (GraphVertex component : getComponentsRes.left().value()) {
962                 String invariantUUID = (String) component.getJsonMetadataField(JsonPresentationFields.INVARIANT_UUID);
963                 if (((String) component.getJsonMetadataField(JsonPresentationFields.LIFECYCLE_STATE)).equals(LifecycleStateEnum.CERTIFIED.name())) {
964                     latestCertifiedMap.put(invariantUUID, (String) component.getJsonMetadataField(JsonPresentationFields.UNIQUE_ID));
965                 } else {
966                     latestNotCertifiedMap.put(invariantUUID, (String) component.getJsonMetadataField(JsonPresentationFields.UNIQUE_ID));
967                 }
968             }
969             result = Either.left(latestCertifiedMap.entrySet().stream().filter(e -> !latestNotCertifiedMap.containsKey(e.getKey())).map(Map.Entry::getValue).collect(Collectors.toList()));
970         }
971         return result;
972     }
973
974     private Either<List<GraphVertex>, JanusGraphOperationStatus> getAllLatestComponents(VertexTypeEnum vertexType, ComponentTypeEnum componentType) {
975
976         Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
977         propertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
978         propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
979
980         Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
981         propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
982         if (vertexType == VertexTypeEnum.TOPOLOGY_TEMPLATE && componentType == ComponentTypeEnum.RESOURCE) {
983             propertiesNotToMatch.put(GraphPropertyEnum.RESOURCE_TYPE, ResourceTypeEnum.CVFC.name());
984         }
985         return janusGraphDao
986             .getByCriteria(vertexType, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseMetadata);
987     }
988
989     private Either<List<GraphVertex>, StorageOperationStatus> getLatestByName(GraphPropertyEnum property, String nodeName) {
990
991         Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
992         Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
993
994         propertiesToMatch.put(property, nodeName);
995         propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
996
997         Either<List<GraphVertex>, JanusGraphOperationStatus> highestResources = janusGraphDao
998             .getByCriteria(null, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseMetadata);
999         if (highestResources.isRight()) {
1000             JanusGraphOperationStatus status = highestResources.right().value();
1001             log.debug("Failed to fetch resource with name {}. Status is {} ", nodeName, status);
1002             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
1003         }
1004         List<GraphVertex> resources = highestResources.left().value();
1005         List<GraphVertex> result = new ArrayList<>();
1006         for (GraphVertex component : resources) {
1007             if (((String) component.getJsonMetadataField(JsonPresentationFields.LIFECYCLE_STATE)).equals(LifecycleStateEnum.CERTIFIED.name())) {
1008                 result.add(component);
1009             }
1010         }
1011         return Either.left(result);
1012     }
1013
1014     private void deleteMarkedComponents(NodeTypeEnum componentType, int toBeDeleted) {
1015         Map<NodeTypeEnum, Either<List<String>, ResponseFormat>> cleanComponentsResult;
1016         List<NodeTypeEnum> cleanComponents = new ArrayList<>();
1017         cleanComponents.add(componentType);
1018         try {
1019             log.info("Trying to delete {} components of type {} marked as deleted", toBeDeleted, componentType);
1020             cleanComponentsResult = componentsCleanBusinessLogic.cleanComponents(cleanComponents, true);
1021             logDeleteResult(componentType, cleanComponentsResult.get(componentType));
1022         }
1023         catch (Exception e) {
1024             log.error("Exception occurred {}", e.getMessage());
1025             log.debug("Exception occurred", e);
1026         }
1027     }
1028
1029     private void logDeleteResult(NodeTypeEnum type, Either<List<String>, ResponseFormat> deleteResult) {
1030         if (deleteResult == null) {
1031             return;
1032         }
1033         if (deleteResult.isLeft()) {
1034             log.info("Checked out {} versions are deleted successfully", type.getName());
1035         }
1036         else {
1037             log.info("Cleanup of checked out {} versions failed due to the error: {}", type.getName(), deleteResult.right().value().getFormattedMessage());
1038         }
1039     }
1040
1041     private void markCheckedOutResourceAsDeletedIfUpgradeFailed(String certUid, boolean isNotFailed) {
1042         String checkedOutUniqueId = certifiedToNextCheckedOutUniqueId.remove(certUid);
1043         if (!isNotFailed && checkedOutUniqueId != null) {
1044             try {
1045                 //mark as deleted the checked out resource as this upgrade failed
1046                 ResponseFormat respFormat = resourceBusinessLogic.deleteResource(checkedOutUniqueId.toLowerCase(), user);
1047                 log.info("Checked out resource uniqueId = {} is marked as deleted, status: {}", checkedOutUniqueId, respFormat.getFormattedMessage());
1048                 deleteResourcesIfLimitIsReached();
1049             }
1050             catch (Exception e) {
1051                 log.error("Error occurred:", e);
1052             }
1053         }
1054     }
1055
1056     private void markCheckedOutServiceAsDeletedIfUpgradeFailed(String certUid, boolean isNotFailed) {
1057         String checkedOutUniqueId = certifiedToNextCheckedOutUniqueId.remove(certUid);
1058         if (!isNotFailed && checkedOutUniqueId != null) {
1059             try {
1060                 //delete the checked out resource as this upgrade failed
1061                 ResponseFormat respFormat = serviceBusinessLogic.deleteService(checkedOutUniqueId.toLowerCase(), user);
1062                 log.info("Checked out service uniqueId = {} is marked as deleted, status: {}", checkedOutUniqueId, respFormat.getFormattedMessage());
1063                 deleteServicesIfLimitIsReached();
1064             } catch (Exception e) {
1065                 log.error("Error occurred:", e);
1066             }
1067         }
1068
1069     }
1070
1071     void deleteResourcesIfLimitIsReached() {
1072         markedAsDeletedResourcesCnt++;
1073         if (markedAsDeletedResourcesCnt >= maxDeleteComponents) {
1074             deleteMarkedComponents(NodeTypeEnum.Resource, markedAsDeletedResourcesCnt);
1075             markedAsDeletedResourcesCnt = 0;
1076         }
1077     }
1078
1079     void deleteServicesIfLimitIsReached() {
1080         markedAsDeletedServicesCnt++;
1081         if (markedAsDeletedServicesCnt >= maxDeleteComponents) {
1082             deleteMarkedComponents(NodeTypeEnum.Service, markedAsDeletedServicesCnt);
1083             markedAsDeletedServicesCnt = 0;
1084         }
1085     }
1086
1087     boolean isLockDeleteOperationSucceeded() {
1088         StorageOperationStatus status = componentsCleanBusinessLogic.lockDeleteOperation();
1089
1090         switch(status) {
1091             case OK:
1092                 log.info("Lock delete operation succeeded");
1093                 isCleanupLocked = true;
1094                 break;
1095             case FAILED_TO_LOCK_ELEMENT:
1096                 log.info("Delete operation node is already locked");
1097                 isCleanupLocked = isLockRetrySucceeded();
1098                 break;
1099             default:
1100                 log.error("Lock delete operation failed due to the error: {}", status);
1101                 isCleanupLocked = false;
1102                 break;
1103         }
1104         return isCleanupLocked;
1105     }
1106
1107     private boolean isLockRetrySucceeded() {
1108         long startTime = System.currentTimeMillis();
1109         //try to lock the cleanup resource until configurable time interval is finished
1110         while (System.currentTimeMillis() - startTime <= deleteLockTimeoutInSeconds * 1000) {
1111             try {
1112                 //sleep one second and try lock again
1113                 Thread.sleep(1000);
1114                 if (componentsCleanBusinessLogic.lockDeleteOperation() == StorageOperationStatus.OK) {
1115                     return true;
1116                 }
1117             } catch (InterruptedException e) {
1118                 log.error("Error occurred: {}", e.getMessage());
1119                 Thread.currentThread().interrupt();
1120             }
1121         }
1122         return false;
1123     }
1124
1125     void unlockDeleteOperation() {
1126         if (isCleanupLocked) {
1127             try {
1128                 componentsCleanBusinessLogic.unlockDeleteOperation();
1129                 log.info("Lock delete operation is canceled");
1130                 isCleanupLocked = false;
1131             }
1132             catch (Exception e) {
1133                 log.debug("Failed to unlock delete operation", e);
1134                 log.error("Failed to unlock delete operation due to the error {}", e.getMessage());
1135             }
1136         }
1137     }
1138
1139     private Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> checkOutComponent(org.openecomp.sdc.be.model.Component component) {
1140         log.info("Starting to perform check out of {} {}, uniqueId = {}", component.getComponentType(), component.getName(), component.getUniqueId());
1141         Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> checkoutRes =
1142                 lifecycleBusinessLogic.changeComponentState(component.getComponentType(), component.getUniqueId(), user, LifeCycleTransitionEnum.CHECKOUT, changeInfo, true, false);
1143         if (checkoutRes.isLeft()) {
1144             //add the uniqueId from "upgradeVf(String uniqueId)" and checkouRes's uniqueUID to the new map
1145             certifiedToNextCheckedOutUniqueId.put(component.getUniqueId(), checkoutRes.left().value().getUniqueId());
1146             log.debug("Add checked out component uniqueId = {} produced from certified component uniqueId = {} to the checked out map", checkoutRes.left().value().getUniqueId(), component.getUniqueId());
1147         }
1148         return checkoutRes;
1149     }
1150
1151     UpgradeStatus getVfUpgradeStatus(boolean isUpgraded, boolean isInstance) {
1152         if (isUpgraded) {
1153             return isInstance ? UpgradeStatus.UPGRADED_AS_INSTANCE : UpgradeStatus.UPGRADED;
1154         }
1155         return UpgradeStatus.NOT_UPGRADED;
1156     }
1157
1158 }