Final commit to master merge from
[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 java.util.ArrayList;
4 import java.util.EnumMap;
5 import java.util.HashMap;
6 import java.util.List;
7 import java.util.Map;
8 import java.util.Optional;
9 import java.util.stream.Collectors;
10
11 import org.apache.commons.collections.CollectionUtils;
12 import org.apache.commons.lang3.StringUtils;
13 import org.openecomp.sdc.asdctool.migration.core.task.MigrationResult;
14 import org.openecomp.sdc.asdctool.migration.core.task.PostMigration;
15 import org.openecomp.sdc.asdctool.migration.tasks.handlers.XlsOutputHandler;
16 import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic;
17 import org.openecomp.sdc.be.components.impl.ServiceComponentInstanceBusinessLogic;
18 import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic;
19 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction;
20 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction.LifecycleChanceActionEnum;
21 import org.openecomp.sdc.be.config.ConfigurationManager;
22 import org.openecomp.sdc.be.dao.api.ActionStatus;
23 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
24 import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
25 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
26 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
27 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
28 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
29 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
30 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
31 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
32 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
33 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
34 import org.openecomp.sdc.be.impl.ComponentsUtils;
35 import org.openecomp.sdc.be.model.ComponentInstance;
36 import org.openecomp.sdc.be.model.LifeCycleTransitionEnum;
37 import org.openecomp.sdc.be.model.LifecycleStateEnum;
38 import org.openecomp.sdc.be.model.Resource;
39 import org.openecomp.sdc.be.model.User;
40 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
41 import org.openecomp.sdc.be.model.jsontitan.utils.ModelConverter;
42 import org.openecomp.sdc.be.model.operations.api.IUserAdminOperation;
43 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
44 import org.openecomp.sdc.be.model.operations.impl.CsarOperation;
45 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
46 import org.openecomp.sdc.exception.ResponseFormat;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49 import org.springframework.beans.factory.annotation.Autowired;
50 import org.springframework.stereotype.Component;
51
52 import fj.data.Either;
53
54 @Component
55 public class UpgradeMigration1710 implements PostMigration {
56
57     private static final String UNKNOWN = "UNKNOWN";
58
59     private static final String CHECKOUT_MESSAGE = "checkout upon upgrade migration";
60
61     private static final String FAILED_TO_CHANGE_STATE_OF_COMPONENT = "Failed to change state of component with name {}, invariantUUID {}, version {} to {}. ";
62
63     private static final String FAILED_TO_UPGRADE_COMPONENT = "Failed to upgrade {} with name {}, invariantUUID {}, version {}. Operation {}. The reason for failure: {}. ";
64
65     private static final String UPGRADE_COMPONENT_SUCCEEDED = "Upgrade of {} with name {}, invariantUUID {}, version {} finished successfully. ";
66
67     private static final String UPGRADE_VFS_FAILED = "Upgrade VFs upon upgrade migration 1710 process failed. ";
68
69     private static final Logger LOGGER = LoggerFactory.getLogger(UpgradeMigration1710.class);
70
71     @Autowired
72     private TitanDao titanDao;
73     
74     @Autowired
75     private ToscaOperationFacade toscaOperationFacade;
76     
77     @Autowired
78     private LifecycleBusinessLogic lifecycleBusinessLogic;
79     
80     @Autowired
81     private IUserAdminOperation userAdminOperation;
82
83     @Autowired
84     private ResourceBusinessLogic resourceBusinessLogic;
85     
86     @Autowired
87     private CsarOperation csarOperation;
88     
89     @Autowired
90     private ServiceComponentInstanceBusinessLogic componentInstanceBusinessLogic;
91
92     @Autowired
93     private ComponentsUtils componentsUtils;
94
95     private final XlsOutputHandler outputHandler = new XlsOutputHandler("COMPONENT TYPE", "COMPONENT NAME", "COMPONENT UUID", "COMPONENT UNIQUE_ID", "UPGRADE STATUS", "DESCRIPTION");
96
97     private User user = null;
98
99     private final LifecycleChangeInfoWithAction changeInfo = new  LifecycleChangeInfoWithAction(CHECKOUT_MESSAGE, LifecycleChanceActionEnum.UPGRADE_MIGRATION);
100
101     private final Map<String,GraphVertex> latestGenericTypes = new HashMap<>();
102
103     private boolean isVfcUpgradeRequired = false;
104
105     private boolean skipIfUpgradeVfFailed = true;
106
107     /** below methods is defined on package level for testing
108      * where Spring object injection is not used  **/
109     void setUserAdminOperation(IUserAdminOperation userAdminOperation) { this.userAdminOperation = userAdminOperation; }
110
111     void setTitanDao(TitanDao titanDao) { this.titanDao = titanDao; }
112
113     void setTosckaOperationFacade(ToscaOperationFacade toscaOperationFacade) { this.toscaOperationFacade = toscaOperationFacade; }
114
115     void setLifecycleBusinessLogic(LifecycleBusinessLogic lifecycleBusinessLogic) { this.lifecycleBusinessLogic = lifecycleBusinessLogic; }
116
117     void setComponentsUtils(ComponentsUtils componentsUtils) { this.componentsUtils = componentsUtils; }
118
119
120     /***********************************************/
121
122     @Override
123     public String description() {
124         return "Upgrade migration 1710 - post migration task, which is dedicated to upgrade all latest certified (and not checked out) Node types, VFs and Services. ";
125     }
126
127     private enum UpgradeStatus{
128         UPGRADED,
129         NOT_UPGRADED
130     }
131
132     @Override
133     public MigrationResult migrate() {
134         LOGGER.info("Starting upgrade migration 1710 process. ");
135         MigrationResult migrationResult = new MigrationResult();
136
137         try{
138             boolean result = true;
139
140             isVfcUpgradeRequired = !ConfigurationManager.getConfigurationManager().getConfiguration().getSkipUpgradeVSPsFlag();
141             skipIfUpgradeVfFailed = ConfigurationManager.getConfigurationManager().getConfiguration().getSkipUpgradeFailedVfs();
142             final String userId = ConfigurationManager.getConfigurationManager().getConfiguration().getAutoHealingOwner();
143
144             Either<User, ActionStatus> userReq = userAdminOperation.getUserData(userId, false);
145             if (userReq.isRight()) {
146                 result = false;
147                 LOGGER.error("Upgrade migration was failed. User {} resolve failed: {} ", userId, userReq.right().value());
148             }
149             else {
150                 user = userReq.left().value();
151                 LOGGER.info("User {} will perform upgrade operation", user.toString());
152             }
153
154             if(result){
155                 result = upgradeNodeTypes();
156             }
157             if(result){
158                 result = upgradeVFs();
159             }
160             if(result){
161                 upgradeServices();
162             }
163             if(result){
164                 LOGGER.info("Upgrade migration 1710 has been successfully finished. ");
165                 titanDao.commit();
166                 migrationResult.setMigrationStatus(MigrationResult.MigrationStatus.COMPLETED);
167             } else {
168                 LOGGER.info("Upgrade migration 1710 was failed. ");
169                 titanDao.rollback();
170                 migrationResult.setMigrationStatus(MigrationResult.MigrationStatus.FAILED);
171             }
172         } catch(Exception e){
173             LOGGER.error("Upgrade migration 1710 was failed. ", e);
174             titanDao.rollback();
175             migrationResult.setMigrationStatus(MigrationResult.MigrationStatus.FAILED);
176         } finally {
177             outputHandler.writeOutput();
178         }
179         return migrationResult;
180     }
181
182     private StorageOperationStatus upgradeServices() {
183         LOGGER.info("Starting upgrade services upon upgrade migration 1710 process. ");
184         Map<String, String> latestOriginResourceVersions = new HashMap<>();
185         Either<List<String>, TitanOperationStatus> getServicesRes = getAllLatestCertifiedComponentUids(VertexTypeEnum.TOPOLOGY_TEMPLATE, ComponentTypeEnum.SERVICE);
186         if(getServicesRes.isRight()){
187             return StorageOperationStatus.GENERAL_ERROR;
188         }
189         for(String currUid : getServicesRes.left().value()){
190             try{
191                 if(handleService(currUid, latestOriginResourceVersions)){
192                     titanDao.commit();
193                 } else {
194                     processComponentUpgradeFailure(ComponentTypeEnum.SERVICE.name(), currUid, "");
195                 }
196             } catch(Exception e){
197                 processComponentUpgradeFailure(ComponentTypeEnum.SERVICE.name(), currUid, e.getMessage());
198             }
199         }
200         return StorageOperationStatus.OK;
201     }
202
203     private void processComponentUpgradeFailure(final String name, final String currUid, final String reason) {
204         LOGGER.error("Failed to upgrade {} with uniqueId {} due to a reason {}. ", name, currUid, reason);
205         titanDao.rollback();
206     }
207
208     private boolean handleService(String uniqueId, Map<String, String> latestOriginResourceVersions) {
209         LOGGER.info("Starting upgrade Service with uniqueId {} upon upgrade migration 1710 process. ", uniqueId);
210         Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getServiceRes = toscaOperationFacade.getToscaElement(uniqueId);
211         if(getServiceRes.isRight()){
212             LOGGER.error("Failed to upgrade service with uniqueId {} due to {}. ", uniqueId, getServiceRes.right().value());
213             outputHandler.addRecord(ComponentTypeEnum.SERVICE.name(), UNKNOWN, UNKNOWN, uniqueId, MigrationResult.MigrationStatus.FAILED.name(), getServiceRes.right().value());
214             return false;
215         }
216         String derivedFromGenericType =  getServiceRes.left().value().getDerivedFromGenericType();
217         LOGGER.debug("derivedFromGenericType: {}", derivedFromGenericType );
218         if (derivedFromGenericType == null) {
219             //malformed field value, upgrade required
220             return upgradeService(getServiceRes.left().value());
221         }
222         if(!latestGenericTypes.containsKey(derivedFromGenericType)){
223             Either<List<GraphVertex>, TitanOperationStatus> getDerivedRes = findDerivedResources(derivedFromGenericType);
224             if(getDerivedRes.isRight()){
225                 LOGGER.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());
226                 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());
227                 return false;
228             }
229             latestGenericTypes.put(derivedFromGenericType, getDerivedRes.left().value().get(0));
230         }
231         if(latestVersionExists(latestGenericTypes.get(derivedFromGenericType), getServiceRes.left().value().getDerivedFromGenericVersion())){
232             return upgradeService(getServiceRes.left().value());
233         }
234         if(!collectLatestOriginResourceVersions(getServiceRes.left().value(), latestOriginResourceVersions)){
235             return false;
236         }
237         if(shouldUpgrade(getServiceRes.left().value(), latestOriginResourceVersions)){
238             return upgradeService(getServiceRes.left().value());
239         }
240         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);
241         return true;
242     }
243
244     private boolean collectLatestOriginResourceVersions(org.openecomp.sdc.be.model.Component component, Map<String, String> latestOriginResourceVersions) {
245         if(CollectionUtils.isNotEmpty(component.getComponentInstances())){
246             for(ComponentInstance instance : component.getComponentInstances()){
247                 if(instance.getOriginType() != OriginTypeEnum.ServiceProxy && !latestOriginResourceVersions.containsKey(instance.getToscaComponentName())){
248                     VertexTypeEnum vertexType = ModelConverter.getVertexType(instance.getOriginType().name());
249                     Either<Resource, StorageOperationStatus> getOriginRes = toscaOperationFacade.getLatestCertifiedByToscaResourceName(instance.getToscaComponentName(), vertexType, JsonParseFlagEnum.ParseMetadata);
250                     if(getOriginRes.isRight()){
251                         LOGGER.error(FAILED_TO_UPGRADE_COMPONENT, component.getComponentType().getValue(), component.getName(), component.getInvariantUUID(), component.getVersion(), "toscaOperationFacade.getLatestCertifiedByToscaResourceName", getOriginRes.right().value());
252                         outputHandler.addRecord( component.getComponentType().name(), component.getName(), component.getInvariantUUID(), component.getUniqueId(), MigrationResult.MigrationStatus.FAILED.name(), getOriginRes.right().value());
253                         return false;
254                     }
255                     latestOriginResourceVersions.put(instance.getToscaComponentName(), getOriginRes.left().value().getVersion());
256                 }
257             }
258         }
259         return true;
260     }
261
262     private boolean shouldUpgrade(org.openecomp.sdc.be.model.Component component, Map<String, String> latestOriginResources) {
263         boolean shouldUpgrade = false;
264         if(CollectionUtils.isNotEmpty(component.getComponentInstances())){
265             for(ComponentInstance instance : component.getComponentInstances()){
266                 if(instance.getOriginType() == OriginTypeEnum.ServiceProxy){
267                     LOGGER.info("The service with name {}, invariantUUID {}, version {}, contains Service proxy instance {}, than the service should be upgraded. ", component.getName(), component.getInvariantUUID(), component.getVersion(), instance.getName());
268                     shouldUpgrade = true;
269                 }
270                 if(isGreater(latestOriginResources.get(instance.getToscaComponentName()), instance.getComponentVersion())){
271                     LOGGER.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());
272                     shouldUpgrade = true;
273                 }
274             }
275         }
276         return shouldUpgrade;
277     }
278
279     private boolean upgradeService(org.openecomp.sdc.be.model.Component service) {
280         String serviceName = service.getName();
281         String serviceUuid = service.getUUID();
282         LOGGER.info("Starting upgrade Service with name {}, invariantUUID {}, version {} upon upgrade migration 1710 process. ", serviceName, service.getInvariantUUID(), service.getVersion());
283         LOGGER.info("Starting to perform check out of service {}. ", serviceName);
284         Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> checkouRes = lifecycleBusinessLogic.changeComponentState(service.getComponentType(), service.getUniqueId(), user, LifeCycleTransitionEnum.CHECKOUT, changeInfo, true, false);
285         if(checkouRes.isRight()){
286             LOGGER.error(FAILED_TO_UPGRADE_COMPONENT, service.getComponentType().getValue(), serviceName, service.getInvariantUUID(), service.getVersion(), "lifecycleBusinessLogic.changeComponentState", checkouRes.right().value().getFormattedMessage());
287             outputHandler.addRecord(service.getComponentType().name(), serviceName, serviceUuid, service.getUniqueId(), MigrationResult.MigrationStatus.FAILED.name(), checkouRes.right().value().getFormattedMessage());
288             return false;
289         }
290         Either<org.openecomp.sdc.be.model.Component, ResponseFormat>  updateCompositionRes = updateComposition(checkouRes.left().value());
291         if(updateCompositionRes.isRight()){
292             LOGGER.error(FAILED_TO_UPGRADE_COMPONENT, service.getComponentType().getValue(), serviceName, service.getInvariantUUID(), service.getVersion(), "updateComposition", updateCompositionRes.right().value().getFormattedMessage());
293             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());
294             return false;
295         }
296         Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat>  certifyRes = performFullCertification(checkouRes.left().value());
297         if(certifyRes.isRight()){
298             LOGGER.error(FAILED_TO_UPGRADE_COMPONENT, service.getComponentType().getValue(), serviceName, service.getInvariantUUID(), service.getVersion(), "performFullCertification", certifyRes.right().value().getFormattedMessage());
299             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());
300             return false;
301         }
302         outputHandler.addRecord(checkouRes.left().value().getComponentType().name(), checkouRes.left().value().getName(), serviceUuid, checkouRes.left().value().getUniqueId(), MigrationResult.MigrationStatus.COMPLETED.name(), UpgradeStatus.UPGRADED);
303         return true;
304     }
305
306     private Either<org.openecomp.sdc.be.model.Component, ResponseFormat> updateComposition(org.openecomp.sdc.be.model.Component component) {
307         Either<ComponentInstance, ResponseFormat> upgradeInstanceRes;
308         for(ComponentInstance instance : component.getComponentInstances()){
309             upgradeInstanceRes = upgradeInstance(component, instance);
310             if(upgradeInstanceRes.isRight()) {
311                 LOGGER.error(FAILED_TO_UPGRADE_COMPONENT, component.getComponentType().getValue(), component.getName(), component.getInvariantUUID(), component.getVersion(), "upgradeInstance", upgradeInstanceRes.right().value().getFormattedMessage());
312                 outputHandler.addRecord(component.getComponentType().name(), component.getName(), component.getUUID(), component.getUniqueId(), MigrationResult.MigrationStatus.FAILED.name(), upgradeInstanceRes.right().value().getFormattedMessage());
313                 return Either.right(upgradeInstanceRes.right().value());
314             }
315         }
316         return Either.left(component);
317     }
318
319     private Either<ComponentInstance, ResponseFormat> upgradeInstance(org.openecomp.sdc.be.model.Component component, ComponentInstance instance) {
320         LOGGER.info("Starting upgrade {} instance {} upon upgrade migration 1710 process. ", component.getComponentType().getValue(), instance.getName());
321         ComponentInstance newComponentInstance = new ComponentInstance(instance);
322         if(instance.getOriginType() == OriginTypeEnum.ServiceProxy){
323             return upgradeServiceProxyInstance(component, instance, newComponentInstance);
324         }
325         return upgradeResourceInstance(component, instance, newComponentInstance);
326     }
327
328     private Either<ComponentInstance, ResponseFormat> upgradeResourceInstance(org.openecomp.sdc.be.model.Component component,
329                                                             ComponentInstance instance, ComponentInstance newComponentInstance) {
330         LOGGER.info("Starting upgrade {} instance {} upon upgrade migration 1710 process. ", component.getComponentType().getValue(), instance.getName());
331         VertexTypeEnum vertexType = ModelConverter.getVertexType(instance.getOriginType().name());
332         Either<Resource, StorageOperationStatus> getOriginRes = toscaOperationFacade.getLatestCertifiedByToscaResourceName(instance.getToscaComponentName(), vertexType, JsonParseFlagEnum.ParseMetadata);
333         if(getOriginRes.isRight()){
334             LOGGER.info("Upgrade of {} instance {} upon upgrade migration 1710 process failed due to a reason {}. ",
335                     component.getComponentType().getValue(), instance.getName(), getOriginRes.right().value());
336             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(getOriginRes.right().value(), instance.getOriginType().getComponentType())));
337         }
338         newComponentInstance.setComponentName(getOriginRes.left().value().getName());
339         newComponentInstance.setComponentUid(getOriginRes.left().value().getUniqueId());
340         newComponentInstance.setComponentVersion(getOriginRes.left().value().getVersion());
341         newComponentInstance.setToscaComponentName(((Resource)getOriginRes.left().value()).getToscaResourceName());
342         if(isGreater(getOriginRes.left().value().getVersion(), instance.getComponentVersion())){
343             return changeAssetVersion(component, instance, newComponentInstance);
344         }
345
346         //upgrade nodes contained by CVFC
347         if(isVfcUpgradeRequired && newComponentInstance.getOriginType() == OriginTypeEnum.CVFC &&
348                                                     !upgradeVf(getOriginRes.left().value().getUniqueId())) {
349             return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
350         }
351         LOGGER.info("Upgrade of {} instance {} upon upgrade migration 1710 process finished successfully. ",
352                                                                     component.getComponentType().getValue(), instance.getName());
353         return Either.left(instance);
354     }
355
356     private Either<ComponentInstance, ResponseFormat> upgradeServiceProxyInstance(org.openecomp.sdc.be.model.Component component, ComponentInstance instance, ComponentInstance newComponentInstance) {
357         Either<List<GraphVertex>, TitanOperationStatus> getLatestOriginServiceRes = getLatestCertifiedService(instance.getSourceModelInvariant());
358         if(getLatestOriginServiceRes.isRight()){
359             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertTitanStatusToStorageStatus(getLatestOriginServiceRes.right().value()), instance.getOriginType().getComponentType())));
360         }
361         newComponentInstance.setComponentVersion((String) getLatestOriginServiceRes.left().value().get(0).getJsonMetadataField(JsonPresentationFields.VERSION));
362         newComponentInstance.setSourceModelUid((String) getLatestOriginServiceRes.left().value().get(0).getJsonMetadataField(JsonPresentationFields.UNIQUE_ID));
363         newComponentInstance.setSourceModelName((String) getLatestOriginServiceRes.left().value().get(0).getJsonMetadataField(JsonPresentationFields.NAME));
364         newComponentInstance.setSourceModelUuid((String) getLatestOriginServiceRes.left().value().get(0).getJsonMetadataField(JsonPresentationFields.UUID));
365         return changeAssetVersion(component, instance, newComponentInstance);
366     }
367
368     private Either<List<GraphVertex>, TitanOperationStatus> getLatestCertifiedService(String invariantUUID) {
369
370         Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
371         propertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.SERVICE.name());
372         propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
373         propertiesToMatch.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
374         propertiesToMatch.put(GraphPropertyEnum.INVARIANT_UUID, invariantUUID);
375         Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
376         propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
377         return titanDao.getByCriteria(VertexTypeEnum.TOPOLOGY_TEMPLATE, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseMetadata);
378     }
379
380     private Either<ComponentInstance, ResponseFormat> changeAssetVersion(org.openecomp.sdc.be.model.Component containerComponent, ComponentInstance instance, ComponentInstance newComponentInstance) {
381         return componentInstanceBusinessLogic.changeComponentInstanceVersion(ComponentTypeEnum.SERVICE_PARAM_NAME, containerComponent.getUniqueId(), instance.getUniqueId(), user.getUserId(), newComponentInstance);
382     }
383
384     private boolean upgradeNodeTypes() {
385         LOGGER.info("Starting upgrade node types upon upgrade migration 1710 process. ");
386         String toscaConformanceLevel = ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel();
387         Map<String, List<String>> resourcesForUpgrade = ConfigurationManager.getConfigurationManager().getConfiguration().getResourcesForUpgrade();
388         Map<String, org.openecomp.sdc.be.model.Component> upgradedNodeTypesMap = new HashMap<> ();
389         List<String> nodeTypes;
390         if(resourcesForUpgrade.containsKey(toscaConformanceLevel)){
391              nodeTypes = resourcesForUpgrade.get(toscaConformanceLevel);
392             if(nodeTypes !=null && !nodeTypes.isEmpty()){
393                 Either<List<String>, TitanOperationStatus> getRes = getAllLatestCertifiedComponentUids(VertexTypeEnum.NODE_TYPE, ComponentTypeEnum.RESOURCE);
394                 if(getRes.isRight()){
395                     return false;
396                 }
397                 List<String> allNodeTypes = getRes.left().value();
398
399                 for(String toscaResourceName: nodeTypes){
400                     Either<List<GraphVertex>, StorageOperationStatus> status = getLatestByName(GraphPropertyEnum.TOSCA_RESOURCE_NAME, toscaResourceName);
401                     if (status.isRight()) {
402                         LOGGER.error("Failed to find node type {} ", toscaResourceName);
403                         return false;
404                     }
405                     List<GraphVertex> vList = status.left().value();
406                     for (GraphVertex vertex : vList) {
407                         StorageOperationStatus updateRes = upgradeNodeType(vertex, upgradedNodeTypesMap, allNodeTypes, nodeTypes);
408                         if (updateRes != StorageOperationStatus.OK) {
409                             return false;
410                         }
411                     }
412                 }
413             }
414         }
415         return true;
416     }
417
418     private boolean upgradeVFs() {
419         LOGGER.info("Starting upgrade VFs upon upgrade migration 1710 process. ");
420         Either<List<String>, TitanOperationStatus> getVfsRes = getAllLatestCertifiedComponentUids(VertexTypeEnum.TOPOLOGY_TEMPLATE, ComponentTypeEnum.RESOURCE);
421         if(getVfsRes.isRight()){
422             LOGGER.info(UPGRADE_VFS_FAILED);
423             return false;
424         }
425         for (String currUid : getVfsRes.left().value()) {
426             try {
427                 if (!upgradeVf(currUid)) {
428                     processComponentUpgradeFailure(ComponentTypeEnum.RESOURCE.name(), currUid, "");
429                     if (!skipIfUpgradeVfFailed) {
430                         LOGGER.info(UPGRADE_VFS_FAILED);
431                         return false;
432                     }
433                 }
434                 titanDao.commit();
435             } catch (Exception e) {
436                 processComponentUpgradeFailure(ComponentTypeEnum.RESOURCE.name(), currUid, e.getMessage());
437                 if (!skipIfUpgradeVfFailed) {
438                     LOGGER.info(UPGRADE_VFS_FAILED);
439                     return false;
440                 }
441             }
442         }
443         LOGGER.info("Upgrade VFs upon upgrade migration 1710 process finished successfully. ");
444         return true;
445     }
446
447     private boolean upgradeVf(String uniqueId) {
448         LOGGER.info("Starting upgrade VF with uniqueId {} upon upgrade migration 1710 process. ", uniqueId);
449         Either<String, StorageOperationStatus> latestVersionRes;
450         Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getRes = toscaOperationFacade.getToscaElement(uniqueId);
451         if(getRes.isRight()){
452             LOGGER.debug("Failed to fetch VF with uniqueId {} upon upgrade migration 1710 process. ", uniqueId);
453             outputHandler.addRecord(ComponentTypeEnum.RESOURCE.name(), UNKNOWN, UNKNOWN, uniqueId, MigrationResult.MigrationStatus.FAILED.name(), getRes.right().value());
454             return false;
455         }
456         if(StringUtils.isNotEmpty(getRes.left().value().getCsarUUID())){
457             LOGGER.info("Going to fetch the latest version of VSP with csarUUID {} upon upgrade migration 1710 process. ", getRes.left().value().getCsarUUID());
458             latestVersionRes = csarOperation.getCsarLatestVersion(getRes.left().value().getCsarUUID(), user);
459             if(latestVersionRes.isRight()){
460                 LOGGER.debug("Failed to fetch the latest version of VSP with csarUUID {} upon upgrade migration 1710 process. ", getRes.left().value().getCsarUUID());
461                 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());
462                 return false;
463             }
464             if(isGreater(latestVersionRes.left().value(), getRes.left().value().getCsarVersion())){
465                 return upgradeVfWithLatestVsp(getRes.left().value(), latestVersionRes);
466             }
467             if (!isVfcUpgradeRequired){
468                 LOGGER.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());
469             }
470         }
471         return upgradeComponentWithLatestGeneric(getRes.left().value());
472     }
473
474     private boolean upgradeVfWithLatestVsp(org.openecomp.sdc.be.model.Component vf, Either<String, StorageOperationStatus> latestVersionRes) {
475         LOGGER.info("Starting upgrade vf with name {}, invariantUUID {}, version {} and latest VSP version {} upon upgrade migration 1710 process. ", vf.getName(), vf.getInvariantUUID(), vf.getVersion(), latestVersionRes.left().value());
476         LOGGER.info("Starting to perform check out of vf with name {}, invariantUUID {}, version {}. ", vf.getName(),vf.getInvariantUUID(), vf.getVersion());
477         Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> checkouRes = lifecycleBusinessLogic.changeComponentState(vf.getComponentType(), vf.getUniqueId(), user, LifeCycleTransitionEnum.CHECKOUT, changeInfo, true, false);
478         if(checkouRes.isRight()){
479             outputHandler.addRecord(vf.getComponentType().name(), vf.getName(), vf.getUUID(), vf.getUniqueId(), MigrationResult.MigrationStatus.FAILED.name(), checkouRes.right().value().getFormattedMessage());
480             return false;
481         }
482         LOGGER.info("Starting update vf with name {}, invariantUUID {}, version {} and latest VSP {}. ", vf.getName(), vf.getInvariantUUID(), vf.getVersion(), latestVersionRes.left().value());
483         Resource resourceToUpdate = new Resource(((Resource) checkouRes.left().value()).getComponentMetadataDefinition());
484         resourceToUpdate.setDerivedFromGenericType(((Resource) checkouRes.left().value()).getDerivedFromGenericType());
485         resourceToUpdate.setDerivedFromGenericVersion(((Resource) checkouRes.left().value()).getDerivedFromGenericVersion());
486         resourceToUpdate.setCsarVersion(Double.toString(Double.parseDouble(latestVersionRes.left().value())));
487         Either<Resource, ResponseFormat> updateResourceFromCsarRes = resourceBusinessLogic.validateAndUpdateResourceFromCsar(resourceToUpdate, user, null, null, resourceToUpdate.getUniqueId());
488         if(updateResourceFromCsarRes.isRight()){
489             outputHandler.addRecord(resourceToUpdate.getComponentType().name(), resourceToUpdate.getName(), resourceToUpdate.getUUID(), resourceToUpdate.getUniqueId(), MigrationResult.MigrationStatus.FAILED.name(), updateResourceFromCsarRes.right().value().getFormattedMessage());
490             LOGGER.info("Failed to update vf with name {}, invariantUUID {}, version {} and latest VSP {}. ", vf.getName(), vf.getInvariantUUID(), vf.getVersion(), latestVersionRes.left().value());
491             return false;
492         }
493         Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> certifyRes =  performFullCertification(checkouRes.left().value());
494         if(certifyRes.isRight()){
495             LOGGER.info(FAILED_TO_CHANGE_STATE_OF_COMPONENT, checkouRes.left().value().getName(), checkouRes.left().value().getInvariantUUID(), checkouRes.left().value().getVersion(), LifeCycleTransitionEnum.CERTIFY);
496             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());
497             return false;
498         }
499         LOGGER.info("Full certification of vf with name {}, invariantUUID {}, version {} finished . ", vf.getName(), vf.getInvariantUUID(), vf.getVersion(), latestVersionRes.left().value());
500         outputHandler.addRecord(certifyRes.left().value().getComponentType().name(), certifyRes.left().value().getName(), certifyRes.left().value().getUUID(), certifyRes.left().value().getUniqueId(), MigrationResult.MigrationStatus.COMPLETED.name(), UpgradeStatus.UPGRADED);
501         return true;
502     }
503
504     private boolean upgradeComponentWithLatestGeneric(org.openecomp.sdc.be.model.Component component) {
505         String derivedFromGenericType =  component.getDerivedFromGenericType();
506         String derivedFromGenericVersion = component.getDerivedFromGenericVersion();
507         org.openecomp.sdc.be.model.Component updatedComponent = component;
508         if(StringUtils.isNotEmpty(derivedFromGenericType) && !latestGenericTypes.containsKey(derivedFromGenericType)){
509             LOGGER.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);
510             LOGGER.info("Starting to fetch latest generic node type {}. ", derivedFromGenericType);
511             Either<List<GraphVertex>, TitanOperationStatus> getDerivedRes = findDerivedResources(derivedFromGenericType);
512             if(getDerivedRes.isRight()){
513                 outputHandler.addRecord(component.getComponentType().name(), component.getName(), component.getInvariantUUID(), component.getUniqueId(), MigrationResult.MigrationStatus.FAILED.name(), getDerivedRes.right().value());
514                 LOGGER.info("Failed to upgrade component with name {}, invariantUUID {}, version {} and latest generic. Status is {}. ", component.getName(), component.getInvariantUUID(), component.getVersion(), derivedFromGenericType);
515                 return false;
516             }
517             latestGenericTypes.put(derivedFromGenericType, getDerivedRes.left().value().get(0));
518         }
519         if(StringUtils.isEmpty(derivedFromGenericType) ||
520                 latestVersionExists(latestGenericTypes.get(derivedFromGenericType), derivedFromGenericVersion) ||
521                 isVfcUpgradeRequired){
522             if(StringUtils.isNotEmpty(derivedFromGenericType))
523                 LOGGER.info("Newer version {} of derived from generic type {} exists. ", latestGenericTypes.get(derivedFromGenericType).getJsonMetadataField(JsonPresentationFields.VERSION), derivedFromGenericType);
524             else
525                 LOGGER.info("The vf resource with name {}, invariantUUID {}, version {},  has an empty derivedFromGenericType field. ", component.getName(), component.getInvariantUUID(), component.getVersion());
526
527             LOGGER.info("Starting to perform check out of vf with name {}, invariantUUID {}, version {}. ", component.getName(), component.getInvariantUUID(), component.getVersion());
528             Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> checkouRes = lifecycleBusinessLogic.changeComponentState(component.getComponentType(), component.getUniqueId(), user, LifeCycleTransitionEnum.CHECKOUT, changeInfo, true, false);
529             if(checkouRes.isRight()){
530                 LOGGER.info(FAILED_TO_CHANGE_STATE_OF_COMPONENT, component.getName(), component.getInvariantUUID(), component.getVersion(), LifeCycleTransitionEnum.CHECKOUT);
531                 outputHandler.addRecord(component.getComponentType().name(), component.getName(), component.getInvariantUUID(), component.getUniqueId(), MigrationResult.MigrationStatus.FAILED.name(), checkouRes.right().value().getFormattedMessage());
532                 return false;
533             }
534             //update included VFCs, if it is required as per configuration
535             if(isVfcUpgradeRequired && CollectionUtils.isNotEmpty(checkouRes.left().value().getComponentInstances())){
536                 LOGGER.info("VFC upgrade is required: updating components of vf with name {}, invariantUUID {}, version {}. ", component.getName(), component.getInvariantUUID(), component.getVersion());
537                 Either<org.openecomp.sdc.be.model.Component, ResponseFormat>  updateCompositionRes =
538                                                 updateComposition(checkouRes.left().value());
539                 if(updateCompositionRes.isRight()){
540                     LOGGER.error(FAILED_TO_UPGRADE_COMPONENT, checkouRes.left().value().getComponentType().name(), checkouRes.left().value().getName(), checkouRes.left().value().getInvariantUUID(), checkouRes.left().value().getVersion(), "updateComposition", updateCompositionRes.right().value().getFormattedMessage());
541                     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());
542                     return false;
543                 }
544             }
545             Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> certifyRes = performFullCertification(checkouRes.left().value());
546             if(certifyRes.isRight()){
547                 LOGGER.info(FAILED_TO_CHANGE_STATE_OF_COMPONENT, component.getName(), component.getInvariantUUID(), component.getVersion(), LifeCycleTransitionEnum.CERTIFY);
548                 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());
549                 return false;
550             }
551             updatedComponent = certifyRes.left().value();
552         } else {
553             LOGGER.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());
554         }
555         LOGGER.info(UPGRADE_COMPONENT_SUCCEEDED, component.getComponentType().getValue(), component.getName(), component.getInvariantUUID(), component.getVersion());
556         outputHandler.addRecord(updatedComponent.getComponentType().name(), updatedComponent.getName(), updatedComponent.getUUID(), updatedComponent.getUniqueId(), MigrationResult.MigrationStatus.COMPLETED.name(), updatedComponent.equals(component) ? UpgradeStatus.NOT_UPGRADED : UpgradeStatus.UPGRADED);
557         return true;
558     }
559
560     private StorageOperationStatus upgradeNodeType(GraphVertex nodeTypeV, Map<String, org.openecomp.sdc.be.model.Component> upgradedNodeTypesMap, List<String> allCertifiedUids, List<String> nodeTypes) {
561         StorageOperationStatus result = StorageOperationStatus.OK;
562         LOGGER.info("Starting upgrade node type with name {}, invariantUUID {}, version{}. ", nodeTypeV.getMetadataProperty(GraphPropertyEnum.NAME), nodeTypeV.getMetadataProperty(GraphPropertyEnum.INVARIANT_UUID), nodeTypeV.getMetadataProperty(GraphPropertyEnum.VERSION));
563         LOGGER.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));
564         Either<List<GraphVertex>, TitanOperationStatus> parentResourceRes = titanDao.getParentVertecies(nodeTypeV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.ParseMetadata);
565         if(parentResourceRes.isRight() && parentResourceRes.right().value() != TitanOperationStatus.NOT_FOUND ){
566             return DaoStatusConverter.convertTitanStatusToStorageStatus(parentResourceRes.right().value());
567
568         }
569         List<GraphVertex> derivedResourcesUid = new ArrayList<>();
570         if(parentResourceRes.isLeft()){
571             for(GraphVertex chV: parentResourceRes.left().value()){
572                 Optional<String> op = allCertifiedUids.stream().filter(id -> id.equals((String)chV.getJsonMetadataField(JsonPresentationFields.UNIQUE_ID))).findAny();
573                 if(op.isPresent()){
574                     derivedResourcesUid.add(chV);
575                 }
576             }
577         }
578         String uniqueId = (String)nodeTypeV.getJsonMetadataField(JsonPresentationFields.UNIQUE_ID);
579         Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getRes = toscaOperationFacade.getToscaElement(uniqueId);
580         if(getRes.isRight()){
581             LOGGER.info("failed to fetch element with uniqueId {} ", uniqueId);
582             return getRes.right().value();
583         }
584
585         org.openecomp.sdc.be.model.Resource nt = (Resource)getRes.left().value();
586         boolean isNeedToUpgrade = true;
587         if(upgradedNodeTypesMap.containsKey(nt.getToscaResourceName()) || nodeTypes.stream().filter( p -> p.equals(nt.getToscaResourceName())).findAny().isPresent()){
588             isNeedToUpgrade = false;
589         }
590         if(isNeedToUpgrade){
591             LOGGER.info("Starting to perform check out of node type with name {}, invariantUUID {}, version {}. ", nt.getName(), nt.getInvariantUUID(), nt.getVersion());
592             Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> checkouRes = lifecycleBusinessLogic.changeComponentState(nt.getComponentType(), nt.getUniqueId(), user, LifeCycleTransitionEnum.CHECKOUT, changeInfo, true, false);
593             if(checkouRes.isRight()){
594                 return StorageOperationStatus.GENERAL_ERROR;
595             }
596             org.openecomp.sdc.be.model.Component upgradetComp = checkouRes.left().value();
597             boolean res = performFullCertification(upgradetComp).isLeft();
598             if(!res){
599                 return StorageOperationStatus.GENERAL_ERROR;
600             }
601             upgradedNodeTypesMap.put(nt.getToscaResourceName(), upgradetComp);
602             titanDao.commit();
603         }
604         for(GraphVertex chV: derivedResourcesUid){
605             result = upgradeNodeType(chV, upgradedNodeTypesMap, allCertifiedUids, nodeTypes);
606             LOGGER.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);
607         }
608         return result;
609     }
610
611     private Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> performFullCertification(org.openecomp.sdc.be.model.Component component) {
612         LOGGER.info("Starting to perform full certification of {} with name {}, invariantUUID {}, version {}. ",
613                                             component.getComponentType().getValue(), component.getName(), component.getInvariantUUID(), component.getVersion());
614
615         Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat>  changeStateEither = lifecycleBusinessLogic.changeComponentState(component.getComponentType(), component.getUniqueId(), user, LifeCycleTransitionEnum.CERTIFICATION_REQUEST, changeInfo, true, false);
616         if(changeStateEither.isRight()){
617             LOGGER.info(FAILED_TO_CHANGE_STATE_OF_COMPONENT, component.getName(), component.getInvariantUUID(), component.getVersion(), LifeCycleTransitionEnum.CERTIFICATION_REQUEST);
618             return changeStateEither;
619         }
620         changeStateEither = lifecycleBusinessLogic.changeComponentState(component.getComponentType(), changeStateEither.left().value().getUniqueId(), user, LifeCycleTransitionEnum.START_CERTIFICATION, changeInfo, true, false);
621         if(changeStateEither.isRight()){
622             LOGGER.info(FAILED_TO_CHANGE_STATE_OF_COMPONENT, component.getName(), component.getInvariantUUID(), component.getVersion(), LifeCycleTransitionEnum.START_CERTIFICATION);
623             return changeStateEither;
624         }
625         changeStateEither = lifecycleBusinessLogic.changeComponentState(component.getComponentType(), changeStateEither.left().value().getUniqueId(), user, LifeCycleTransitionEnum.CERTIFY, changeInfo, true, false);
626         if(changeStateEither.isRight()){
627             LOGGER.info(FAILED_TO_CHANGE_STATE_OF_COMPONENT, component.getName(), component.getInvariantUUID(), component.getVersion(), LifeCycleTransitionEnum.CERTIFY);
628         }
629         else {
630             LOGGER.info("Full certification of {} with name {}, invariantUUID {}, version {} finished successfully",
631                     changeStateEither.left().value().getComponentType().getValue(), changeStateEither.left().value().getName(),
632                     changeStateEither.left().value().getInvariantUUID(), changeStateEither.left().value().getVersion());
633         }
634         return changeStateEither;
635     }
636
637     private Either<List<GraphVertex>, TitanOperationStatus> findDerivedResources(String parentResource) {
638         Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
639         propertiesToMatch.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
640
641         propertiesToMatch.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, parentResource);
642         propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
643
644         return titanDao.getByCriteria(VertexTypeEnum.NODE_TYPE, propertiesToMatch, JsonParseFlagEnum.ParseMetadata);
645     }
646
647     private boolean latestVersionExists(GraphVertex latestDerivedFrom, String currentVersion) {
648         return isGreater((String)latestDerivedFrom.getJsonMetadataField(JsonPresentationFields.VERSION), currentVersion);
649     }
650
651     private boolean isGreater(String latestVersion, String currentVersion) {
652         if(latestVersion != null && currentVersion == null)
653             return true;
654         if(latestVersion == null)
655             return false;
656         return Double.parseDouble(latestVersion) > Double.parseDouble(currentVersion);
657     }
658
659     private Either<List<String>, TitanOperationStatus> getAllLatestCertifiedComponentUids(VertexTypeEnum vertexType, ComponentTypeEnum componentType) {
660         LOGGER.info("Starting to fetch all latest certified not checked out components with type {} upon upgrade migration 1710 process", componentType);
661         Either<List<String>, TitanOperationStatus> result = null;
662         Map<String, String> latestCertifiedMap = new HashMap<>();
663         Map<String, String> latestNotCertifiedMap = new HashMap<>();
664         
665         Either<List<GraphVertex>, TitanOperationStatus> getComponentsRes = getAllLatestCertifiedComponents(vertexType, componentType);
666         if(getComponentsRes.isRight() && getComponentsRes.right().value() != TitanOperationStatus.NOT_FOUND){
667             LOGGER.error("Failed to fetch all latest certified not checked out components with type {}. Status is {}. ", componentType, getComponentsRes.right().value());
668             result = Either.right(getComponentsRes.right().value());
669         }
670         if(getComponentsRes.isRight()){
671             result = Either.left(new ArrayList<>());
672         }
673         if(result == null){
674             for(GraphVertex component : getComponentsRes.left().value()){
675                 String invariantUUID = (String)component.getJsonMetadataField(JsonPresentationFields.INVARIANT_UUID);
676                 if(((String)component.getJsonMetadataField(JsonPresentationFields.LIFECYCLE_STATE)).equals(LifecycleStateEnum.CERTIFIED.name())){
677                     latestCertifiedMap.put(invariantUUID, (String)component.getJsonMetadataField(JsonPresentationFields.UNIQUE_ID));
678                 } else {
679                     latestNotCertifiedMap.put(invariantUUID, (String)component.getJsonMetadataField(JsonPresentationFields.UNIQUE_ID));
680                 }
681             }
682             result = Either.left(latestCertifiedMap.entrySet().stream().filter(e->!latestNotCertifiedMap.containsKey(e.getKey())).map(e->e.getValue()).collect(Collectors.toList()));
683         }
684         return result;
685     }
686
687     private Either<List<GraphVertex>, TitanOperationStatus> getAllLatestCertifiedComponents(VertexTypeEnum vertexType, ComponentTypeEnum componentType){
688
689         Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
690         propertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
691         propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
692         
693         Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
694         propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
695         if(vertexType == VertexTypeEnum.TOPOLOGY_TEMPLATE && componentType == ComponentTypeEnum.RESOURCE)
696             propertiesNotToMatch.put(GraphPropertyEnum.RESOURCE_TYPE, ResourceTypeEnum.CVFC.name());
697         return titanDao.getByCriteria(vertexType, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseMetadata);
698     }
699
700     protected Either<List<String>, TitanOperationStatus> findResourcesPathRecursively(GraphVertex nodeTypeV, List<String> allCertifiedUids) {
701         Either<List<GraphVertex>, TitanOperationStatus> parentResourceRes = titanDao.getParentVertecies(nodeTypeV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.ParseMetadata);
702         if(parentResourceRes.isRight()){
703             return Either.right(parentResourceRes.right().value());
704         }
705         List<GraphVertex> derivedResourcesUid = new ArrayList<>();
706         for(GraphVertex chV: parentResourceRes.left().value()){
707             Optional<String> op = allCertifiedUids.stream().filter(id -> id.equals((String)chV.getJsonMetadataField(JsonPresentationFields.UNIQUE_ID))).findAny();
708             if(op.isPresent()){
709                 derivedResourcesUid.add(chV);
710             }
711         }
712         return null;
713     }
714
715     private  Either<List<GraphVertex>,  StorageOperationStatus> getLatestByName(GraphPropertyEnum property, String nodeName){
716
717         Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
718         Map<GraphPropertyEnum, Object> propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class);
719
720         propertiesToMatch.put(property, nodeName);
721         propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
722
723         Either<List<GraphVertex>, TitanOperationStatus> highestResources = titanDao.getByCriteria(null, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseMetadata);
724         if (highestResources.isRight()) {
725             TitanOperationStatus status = highestResources.right().value();
726             LOGGER.debug("Failed to fetch resource with name {}. Status is {} ", nodeName, status);
727             return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
728         }
729         List<GraphVertex> resources = highestResources.left().value();
730         List<GraphVertex> result = new ArrayList<>();
731         for(GraphVertex component:resources){
732             if(((String)component.getJsonMetadataField(JsonPresentationFields.LIFECYCLE_STATE)).equals(LifecycleStateEnum.CERTIFIED.name())){
733                 result.add(component);
734             }
735         }
736         return Either.left(result);
737     }
738
739 }