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