aboutsummaryrefslogtreecommitdiffstats
path: root/asdctool/src/main/java/org/openecomp
diff options
context:
space:
mode:
Diffstat (limited to 'asdctool/src/main/java/org/openecomp')
-rw-r--r--asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/ServiceMigration.java5
-rw-r--r--asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1707/Migration1707ArtifactUuidFix.java4
-rw-r--r--asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1707/Migration1707Config.java5
-rw-r--r--asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1707/Migration1707MissingInfoFix.java220
-rw-r--r--asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1707/jsonmodel/ComponentMigration.java4
-rw-r--r--asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1707/jsonmodel/NodeTemplateMissingDataResolver.java129
-rw-r--r--asdctool/src/main/java/org/openecomp/sdc/asdctool/main/MigrationMenu.java63
-rw-r--r--asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/config/MigrationSpringConfig.java59
-rw-r--r--asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/DBVersion.java95
-rw-r--r--asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/MigrationException.java13
-rw-r--r--asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/SdcMigrationTool.java62
-rw-r--r--asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/execution/MigrationExecutionResult.java70
-rw-r--r--asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/execution/MigrationExecutor.java15
-rw-r--r--asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/execution/MigrationExecutorImpl.java47
-rw-r--r--asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/task/Migration.java14
-rw-r--r--asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/task/MigrationResult.java31
-rw-r--r--asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/main/MigrationMenu.java100
-rw-r--r--asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/resolver/MigrationResolver.java16
-rw-r--r--asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/resolver/SpringBeansMigrationResolver.java45
-rw-r--r--asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/service/SdcRepoService.java34
-rw-r--r--asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/tasks/mig1710/ExampleMigration.java27
21 files changed, 991 insertions, 67 deletions
diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/ServiceMigration.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/ServiceMigration.java
index ee5171d8ab..0ef435e1c3 100644
--- a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/ServiceMigration.java
+++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/ServiceMigration.java
@@ -706,7 +706,7 @@ public class ServiceMigration {
Either<ImmutablePair<ComponentInstanceData, GraphEdge>, TitanOperationStatus> reqInst = titanGenericDao.getParentNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.RelationshipInst), rel.getUniqueId(), GraphEdgeLabels.RELATIONSHIP_INST,
NodeTypeEnum.ResourceInstance, ComponentInstanceData.class);
if (reqInst.isRight()) {
- log.debug("updateRelations : failed to fetch capabilty component instance for relation {}, error {}", rel.getUniqueId(), reqInst.right().value());
+ log.debug("updateRelations : failed to fetch capability component instance for relation {}, error {}", rel.getUniqueId(), reqInst.right().value());
return false;
}
ComponentInstanceData requirementInstanceData = reqInst.left().value().getLeft();
@@ -917,6 +917,9 @@ public class ServiceMigration {
case CP:
originType = OriginTypeEnum.CP;
break;
+ case CVFC:
+ originType = OriginTypeEnum.CVFC;
+ break;
default:
log.debug("updateComponentInstanceType failed, no supported resource type {} for origin resource with id {}", resourceType, originId);
return false;
diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1707/Migration1707ArtifactUuidFix.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1707/Migration1707ArtifactUuidFix.java
index c14301ae5e..b3f138241e 100644
--- a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1707/Migration1707ArtifactUuidFix.java
+++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1707/Migration1707ArtifactUuidFix.java
@@ -103,10 +103,10 @@ public class Migration1707ArtifactUuidFix {
if (runMode.equals("fix") || runMode.equals("fix_only_services")) {
log.info("Mode {}. Start fix", runMode);
if (fix(vfLst, serviceList) == false) {
- log.info("Mode {}. Fix finished withh failure", runMode);
+ log.info("Mode {}. Fix finished with failure", runMode);
return false;
}
- log.info("Mode {}. Fix finished withh success", runMode);
+ log.info("Mode {}. Fix finished with success", runMode);
}
return true;
diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1707/Migration1707Config.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1707/Migration1707Config.java
index 21a6ae1416..36919d7520 100644
--- a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1707/Migration1707Config.java
+++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1707/Migration1707Config.java
@@ -271,4 +271,9 @@ public class Migration1707Config {
return new NodeTemplateMissingDataResolver<>();
}
+ @Bean(name = "migration1707MissingInfoFix")
+ public Migration1707MissingInfoFix migration1707MissingInfoFix() {
+ return new Migration1707MissingInfoFix();
+ }
+
}
diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1707/Migration1707MissingInfoFix.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1707/Migration1707MissingInfoFix.java
new file mode 100644
index 0000000000..ff41f12b8e
--- /dev/null
+++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1707/Migration1707MissingInfoFix.java
@@ -0,0 +1,220 @@
+package org.openecomp.sdc.asdctool.impl.migration.v1707;
+
+import fj.data.Either;
+import org.openecomp.sdc.asdctool.impl.migration.v1707.jsonmodel.NodeTemplateMissingDataResolver;
+import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
+import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
+import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
+import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
+import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
+import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
+import org.openecomp.sdc.be.datatypes.elements.*;
+import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
+import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
+import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
+import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
+import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
+import org.openecomp.sdc.be.model.*;
+import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElement;
+import org.openecomp.sdc.be.model.jsontitan.enums.JsonConstantKeysEnum;
+import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
+import org.openecomp.sdc.be.model.operations.api.IServiceOperation;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+@org.springframework.stereotype.Component("migration1707MissingInfoFix")
+public class Migration1707MissingInfoFix {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(Migration1707MissingInfoFix.class);
+
+ @Resource(name = "service-operation")
+ private IServiceOperation serviceOperation;
+
+ @Resource(name = "node-template-missing-data-resolver")
+ private NodeTemplateMissingDataResolver nodeTemplateMissingDataResolver;
+
+ @Resource(name = "tosca-operation-facade")
+ private ToscaOperationFacade toscaOperations;
+
+ @Resource(name = "titan-dao")
+ private TitanDao titanDao;
+
+
+ public boolean migrate(){
+ boolean res = updateVFs();
+ if(res)
+ res = updateServices();
+ return res;
+ }
+
+ private ComponentParametersView getFilter() {
+ ComponentParametersView filter = new ComponentParametersView(true);
+ filter.setIgnoreComponentInstances(false);
+ filter.setIgnoreArtifacts(false);
+ filter.setIgnoreGroups(false);
+ filter.setIgnoreComponentInstancesInputs(false);
+ return filter;
+ }
+
+ // if new service has VF instances with no groups - try to fetch them from old graph
+ private boolean oldServiceModelRequired(Component newService) {
+ Predicate<ComponentInstance> vfInstanceWithNoGroups = p -> OriginTypeEnum.VF == p.getOriginType() && (null == p.getGroupInstances() || p.getGroupInstances().isEmpty());
+ return null != newService.getComponentInstances() && newService.getComponentInstances().stream()
+ .anyMatch(vfInstanceWithNoGroups);
+ }
+
+
+
+ private List<GraphVertex> fetchVertices(Map<GraphPropertyEnum, Object> hasProps){
+ Either<List<GraphVertex>, TitanOperationStatus> componentsByCriteria = titanDao.getByCriteria(VertexTypeEnum.TOPOLOGY_TEMPLATE, hasProps, JsonParseFlagEnum.ParseAll);
+ if (componentsByCriteria.isRight()) {
+ LOGGER.debug("couldn't fetch assets from sdctitan");
+ return null;
+ }
+ return componentsByCriteria.left().value();
+ }
+
+ private boolean updateVFs() {
+
+ boolean res = true;
+ Map<GraphPropertyEnum, Object> hasProps = new HashMap<>();
+ hasProps.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.RESOURCE.name());
+ hasProps.put(GraphPropertyEnum.RESOURCE_TYPE, ResourceTypeEnum.VF.name());
+
+ List<GraphVertex> resources = fetchVertices(hasProps);
+ if(null == resources)
+ return false;
+ ComponentParametersView filter = getFilter();
+ Map<String, ToscaElement> origCompMap = new HashMap<>();
+
+ for (GraphVertex gv : resources) {
+ boolean fixed = true;
+ Either<Component, StorageOperationStatus> toscaElement = toscaOperations.getToscaElement(gv.getUniqueId(), filter);
+ if (toscaElement.isRight()) {
+ LOGGER.debug("Failed to fetch resource {} {}", gv.getUniqueId(), toscaElement.right().value());
+ return false;
+ }
+ Component resource = toscaElement.left().value();
+ Map<String, Boolean> updateMap = new HashMap<>();
+ nodeTemplateMissingDataResolver.updateVFComposition(resource, origCompMap, updateMap);
+ if(updateMap.get(JsonConstantKeysEnum.COMPOSITION.name())){
+ LOGGER.info("applying instance tosca name fix on VF {}", gv.getUniqueId());
+ fixed = toscaOperations.updateComponentInstanceMetadataOfTopologyTemplate(resource).isLeft();
+ }
+ if(updateMap.get(EdgeLabelEnum.GROUPS.name())) {
+ List<GroupDataDefinition> groups = new ArrayList<>(resource.getGroups());
+ LOGGER.info("applying groups vertex fix on VF {}", gv.getUniqueId());
+ fixed = fixed && toscaOperations.updateGroupsOnComponent(resource, ComponentTypeEnum.RESOURCE, groups).isLeft();
+ }
+
+ res = res && fixed;
+ titanDao.commit();
+ }
+ return res;
+ }
+
+ private Map<String, MapPropertiesDataDefinition> buildInstancesInputsMap(Component component){
+ Map<String, MapPropertiesDataDefinition> instanceInputsMap = new HashMap<>();
+ for (Map.Entry<String, List<ComponentInstanceInput>> entry : component.getComponentInstancesInputs().entrySet()) {
+ MapPropertiesDataDefinition inputsMap = new MapPropertiesDataDefinition();
+ inputsMap.setMapToscaDataDefinition(entry.getValue().stream().map(e -> new PropertyDataDefinition(e)).collect(Collectors.toMap(e -> e.getName(), e -> e)));
+ instanceInputsMap.put(entry.getKey(), inputsMap);
+ }
+ return instanceInputsMap;
+ }
+
+
+
+ private Map<String, MapGroupsDataDefinition> buildGroupInstanceMap(Component component) {
+ Map<String, MapGroupsDataDefinition> instGroupsMap = new HashMap<>();
+ for (ComponentInstance instance : component.getComponentInstances()) {
+ if (instance.getGroupInstances() != null) {
+ MapGroupsDataDefinition groupsMap = new MapGroupsDataDefinition();
+ groupsMap.setMapToscaDataDefinition(instance.getGroupInstances().stream().map(e -> new GroupInstanceDataDefinition(e)).collect(Collectors.toMap(e -> e.getName(), e -> e)));
+ instGroupsMap.put(instance.getUniqueId(), groupsMap);
+ }
+ }
+ return instGroupsMap;
+ }
+
+ private <T extends ToscaDataDefinition> boolean updateDataVertex(GraphVertex componentVertex, VertexTypeEnum vertexType, EdgeLabelEnum edgeLabel, Map<String, T> dataMap){
+ Either<GraphVertex, TitanOperationStatus> dataVertexEither = titanDao.getChildVertex(componentVertex, edgeLabel, JsonParseFlagEnum.ParseJson);
+ if (dataVertexEither.isRight()) {
+ if(TitanOperationStatus.NOT_FOUND != dataVertexEither.right().value())
+ return false;
+ return (nodeTemplateMissingDataResolver.topologyTemplateOperation.assosiateElementToData(componentVertex, vertexType, edgeLabel, dataMap)).isLeft();
+ }
+ GraphVertex dataVertex = dataVertexEither.left().value();
+ dataVertex.setJson(dataMap);
+ return (titanDao.updateVertex(dataVertex)).isLeft();
+
+ }
+
+
+ private boolean updateServices(){
+
+ boolean res = true;
+ Map<GraphPropertyEnum, Object> hasProps = new HashMap<>();
+ hasProps.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.SERVICE.name());
+
+ List<GraphVertex> componentsByCriteria = fetchVertices(hasProps);
+ if(null == componentsByCriteria)
+ return false;
+
+ ComponentParametersView filter = getFilter();
+ Map<String, ToscaElement> origCompMap = new HashMap<>();
+
+ Predicate<ComponentInstance> containsGroupInstances = p -> null != p.getGroupInstances() && !p.getGroupInstances().isEmpty();
+
+ for (GraphVertex gv : componentsByCriteria) {
+
+ boolean fixed = true;
+ Either<org.openecomp.sdc.be.model.Service, StorageOperationStatus> toscaElement = toscaOperations.getToscaElement(gv.getUniqueId(), filter);
+ if (toscaElement.isRight()) {
+ LOGGER.debug("Failed to fetch service {} {}", gv.getUniqueId(), toscaElement.right().value());
+ return false;
+ }
+ Component service = toscaElement.left().value();
+ Component oldService = null;
+
+ if(oldServiceModelRequired(service)){
+ Either<Service, StorageOperationStatus> oldServiceEither = serviceOperation.getService(gv.getUniqueId(), filter, false);
+ if (oldServiceEither.isRight()){
+ LOGGER.debug("couldn't fetch service {} from old titan", gv.getUniqueId());
+ }else {
+ oldService = oldServiceEither.left().value();
+ oldService = oldService.getComponentInstances().stream().anyMatch(containsGroupInstances) ? oldService : null;
+ }
+ }
+
+ Map<String, Boolean> updateMap = new HashMap<>();
+ nodeTemplateMissingDataResolver.updateServiceComposition(service, origCompMap, oldService, updateMap);
+ if(updateMap.get(JsonConstantKeysEnum.COMPOSITION.name())) {
+ LOGGER.info("applying instance tosca name fix on service {}", gv.getUniqueId());
+ fixed = (toscaOperations.updateComponentInstanceMetadataOfTopologyTemplate(service)).isLeft();
+ }
+ if(updateMap.get(EdgeLabelEnum.INST_GROUPS.name())) {
+ Map<String, MapGroupsDataDefinition> groupsMap = buildGroupInstanceMap(service);
+ LOGGER.info("applying groups instances vertex fix on service {}", gv.getUniqueId());
+ fixed = fixed && updateDataVertex(gv, VertexTypeEnum.INST_GROUPS, EdgeLabelEnum.INST_GROUPS, groupsMap);
+ }
+ if(updateMap.get(EdgeLabelEnum.INST_INPUTS.name())) {
+ Map<String, MapPropertiesDataDefinition> instInputs = buildInstancesInputsMap(service);
+ LOGGER.info("applying instances inputs vertex fix on service {}", gv.getUniqueId());
+ fixed = fixed && updateDataVertex(gv, VertexTypeEnum.INST_INPUTS, EdgeLabelEnum.INST_INPUTS, instInputs);
+ }
+ res = res && fixed;
+ titanDao.commit();
+ }
+ return res;
+ }
+}
diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1707/jsonmodel/ComponentMigration.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1707/jsonmodel/ComponentMigration.java
index d69363be89..7603a5704a 100644
--- a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1707/jsonmodel/ComponentMigration.java
+++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1707/jsonmodel/ComponentMigration.java
@@ -109,8 +109,8 @@ public abstract class ComponentMigration <T extends Component> extends JsonModel
protected void setMissingTemplateInfo(List<T> components) {
Map<String, ToscaElement> origCompMap = new HashMap<>();
for (T component : components) {
- List<ComponentInstance> instances = component.getComponentInstances();
- if(null != instances) {
+ List<ComponentInstance> instances = component.getComponentInstances();
+ if(null != instances) {
for (ComponentInstance instance : instances) {
nodeTemplateMissingDataResolver.resolveNodeTemplateInfo(instance, origCompMap, component);
nodeTemplateMissingDataResolver.fixVFGroupInstances(component, instance);
diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1707/jsonmodel/NodeTemplateMissingDataResolver.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1707/jsonmodel/NodeTemplateMissingDataResolver.java
index 01e36345e1..c83421066c 100644
--- a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1707/jsonmodel/NodeTemplateMissingDataResolver.java
+++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1707/jsonmodel/NodeTemplateMissingDataResolver.java
@@ -17,23 +17,18 @@
* limitations under the License.
* ============LICENSE_END=========================================================
*/
-
package org.openecomp.sdc.asdctool.impl.migration.v1707.jsonmodel;
-
-
+import fj.data.Either;
+import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
import fj.data.Either;
import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
-import org.openecomp.sdc.be.model.ArtifactDefinition;
-import org.openecomp.sdc.be.model.Component;
-import org.openecomp.sdc.be.model.ComponentInstance;
-import org.openecomp.sdc.be.model.ComponentInstanceInput;
-import org.openecomp.sdc.be.model.GroupDefinition;
-import org.openecomp.sdc.be.model.GroupInstance;
+import org.openecomp.sdc.be.model.*;
import org.openecomp.sdc.be.model.jsontitan.datamodel.TopologyTemplate;
import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElement;
+import org.openecomp.sdc.be.model.jsontitan.enums.JsonConstantKeysEnum;
import org.openecomp.sdc.be.model.jsontitan.operations.TopologyTemplateOperation;
import org.openecomp.sdc.be.model.jsontitan.operations.ToscaElementLifecycleOperation;
import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
@@ -45,6 +40,8 @@ import org.slf4j.LoggerFactory;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.*;
+import java.util.stream.Collectors;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -59,32 +56,98 @@ public class NodeTemplateMissingDataResolver <T extends Component> {
private ToscaElementLifecycleOperation lifecycleOperation;
@Resource(name = "topology-template-operation")
- private TopologyTemplateOperation topologyTemplateOperation;
+ public TopologyTemplateOperation topologyTemplateOperation;
public void resolveNodeTemplateInfo(ComponentInstanceDataDefinition vfInst, Map<String, ToscaElement> origCompMap, T component) {
lifecycleOperation.resolveToscaComponentName(vfInst, origCompMap);
if(OriginTypeEnum.VF == vfInst.getOriginType()) {
- Map<String, List<ComponentInstanceInput>> componentInstancesInputs = Optional.ofNullable(component.getComponentInstancesInputs()).orElse(new HashMap<>());
- collectVFInstanceInputs(componentInstancesInputs, origCompMap, vfInst);
+ collectVFInstanceInputs(component, origCompMap, vfInst);
+ }
+ }
+
+
+
+
+ public void updateServiceComposition(Component component, Map<String, ToscaElement> origCompMap, Component oldModelService, Map<String, Boolean> updateMap){
+
+ boolean composition = false;
+ boolean instInputs = false;
+ boolean instGroups = false;
+ List<ComponentInstance> instances = component.getComponentInstances();
+ if(null != instances) {
+ for (ComponentInstance instance : instances) {
+ composition = composition || lifecycleOperation.resolveToscaComponentName(instance, origCompMap);
+ if(OriginTypeEnum.VF == instance.getOriginType()) {
+ instInputs = instInputs || collectVFInstanceInputs(component, origCompMap, instance);
+ instGroups = instGroups || resolveInstGroupsFromOldTitanGraphAndApplyFix(component, instance, oldModelService);
+ }
+ }
}
+ updateMap.put(JsonConstantKeysEnum.COMPOSITION.name(), composition);
+ updateMap.put(EdgeLabelEnum.INST_INPUTS.name(), instInputs);
+ updateMap.put(EdgeLabelEnum.INST_GROUPS.name(), instGroups);
+ }
+
+
+ public void updateVFComposition(Component component, Map<String, ToscaElement> origCompMap, Map<String, Boolean> updateMap) {
+
+ boolean composition = false;
+ boolean groups = fixVFGroups(component);
+ List<ComponentInstance> instances = component.getComponentInstances();
+ if(null != instances) {
+ for (ComponentInstance instance : instances) {
+ composition = composition || lifecycleOperation.resolveToscaComponentName(instance, origCompMap);
+ }
+ }
+ updateMap.put(JsonConstantKeysEnum.COMPOSITION.name(), composition);
+ updateMap.put(EdgeLabelEnum.GROUPS.name(), groups);
+ }
+
+
+
+ private boolean resolveInstGroupsFromOldTitanGraphAndApplyFix(Component component, ComponentInstance instance, Component oldService){
+
+ boolean res = false;
+ //info already exists, apply fix if needed
+ if(null != instance.getGroupInstances() && !instance.getGroupInstances().isEmpty()) {
+ res = fixVFGroupInstances(component, instance);
+ //get group instances from old model
+ }else if(null != oldService){
+ ComponentInstance origInstance = oldService.getComponentInstances().stream()
+ .filter(p -> instance.getUniqueId().equals(p.getUniqueId()))
+ .findAny().orElse(null);
+ if(null != origInstance && null != origInstance.getGroupInstances()) {
+ fixVFGroupInstances(oldService, origInstance);
+ instance.setGroupInstances(origInstance.getGroupInstances());
+ res = true;
+ }
+ }
+ return res;
}
- private void collectVFInstanceInputs(Map<String, List<ComponentInstanceInput>> instInputs, Map<String, ToscaElement> origCompMap, ComponentInstanceDataDefinition vfInst) {
+ private boolean collectVFInstanceInputs(Component component, Map<String, ToscaElement> origCompMap, ComponentInstanceDataDefinition vfInst) {
+ boolean res = false;
String ciUid = vfInst.getUniqueId();
String origCompUid = vfInst.getComponentUid();
+ if(null == component.getComponentInstancesInputs())
+ component.setComponentInstancesInputs(new HashMap<>());
+ Map<String, List<ComponentInstanceInput>> componentInstInputs = component.getComponentInstancesInputs();
Either<ToscaElement, StorageOperationStatus> origComp = fetchToscaElement(origCompMap, vfInst, origCompUid);
if(origComp.isRight())
- return;
+ return false;
Map<String, PropertyDataDefinition> origVFInputs = ((TopologyTemplate)origComp.left().value()).getInputs();
if (origVFInputs != null && !origVFInputs.isEmpty()) {
+ res = true;
Map<String, ComponentInstanceInput> collectedVFInputs = origVFInputs.values().stream()
.collect(Collectors.toMap(PropertyDataDefinition::getName, ComponentInstanceInput::new));
- List<ComponentInstanceInput> instInputList = instInputs.get(ciUid);
+
+ List<ComponentInstanceInput> instInputList = componentInstInputs.get(ciUid);
Map<String, ComponentInstanceInput> existingInstInputs = ToscaDataDefinition.listToMapByName(instInputList);
collectedVFInputs.putAll(existingInstInputs);
List<ComponentInstanceInput> mergedList = new ArrayList<>(collectedVFInputs.values());
- instInputs.put(ciUid, mergedList);
+ componentInstInputs.put(ciUid, mergedList);
}
+ return res;
}
private Either<ToscaElement, StorageOperationStatus> fetchToscaElement(Map<String, ToscaElement> origCompMap, ComponentInstanceDataDefinition vfInst, String origCompUid) {
@@ -201,22 +264,23 @@ public class NodeTemplateMissingDataResolver <T extends Component> {
return artifactLabel;
}
- protected boolean fixVFGroups(Component component){
- boolean res = true;
-
+ public boolean fixVFGroups(Component component){
+ boolean res = false;
+
Map<String, ArtifactDefinition> deploymentArtifacts = component.getDeploymentArtifacts();
List<GroupDefinition> groups = component.getGroups();
if (groups == null || groups.isEmpty()) {
- LOGGER.debug("No groups in component {} id {} ", component.getName(), component.getUniqueId());
+ LOGGER.debug("No groups in component {} id {} ", component.getName(), component.getUniqueId());
return res;
}
for (GroupDefinition group : groups) {
if (group.getType().equals(Constants.DEFAULT_GROUP_VF_MODULE) && deploymentArtifacts != null) {
if (isProblematicGroup(group, component.getName(), deploymentArtifacts)) {
- List<String> groupArtifacts = new ArrayList<String>(group.getArtifacts());
- group.getArtifacts().clear();
- group.getArtifactsUuid().clear();
+ res = true;
+ List<String> groupArtifacts = null == group.getArtifacts()? new ArrayList<>() : new ArrayList<>(group.getArtifacts());
+ group.setArtifacts(new ArrayList<>());
+ group.setArtifactsUuid(new ArrayList<>());
for (String artifactId : groupArtifacts) {
String artifactlabel = findArtifactLabelFromArtifactId(artifactId);
LOGGER.debug("fix group: group name {} artifactId for fix {} artifactlabel {} ", group.getName(), artifactId, artifactlabel);
@@ -229,19 +293,16 @@ public class NodeTemplateMissingDataResolver <T extends Component> {
if (correctArtifactUUID != null && !correctArtifactUUID.isEmpty()) {
group.getArtifactsUuid().add(correctArtifactUUID);
}
-
}
}
}
}
-
- }
-
+ }
return res;
}
- protected boolean fixVFGroupInstances(Component component, ComponentInstance instance){
- boolean res = true;
+ public boolean fixVFGroupInstances(Component component, ComponentInstance instance){
+ boolean res = false;
Map<String, ArtifactDefinition> deploymentArtifacts = instance.getDeploymentArtifacts();
List<GroupInstance> groupInstances = instance.getGroupInstances();
@@ -252,10 +313,9 @@ public class NodeTemplateMissingDataResolver <T extends Component> {
for (GroupInstance group : groupInstances) {
if (group.getType().equals(Constants.DEFAULT_GROUP_VF_MODULE)) {
if (isProblematicGroupInstance(group, instance.getName(), component.getName(), deploymentArtifacts)) {
-
- LOGGER.debug("Migration1707ArtifactUuidFix fix group: resource id {}, group name {} ", component.getUniqueId(), group.getName());
- List<String> groupArtifacts = Optional.ofNullable(group.getArtifacts()).orElse(new ArrayList<>());
-
+ res = true;
+ LOGGER.debug("Migration1707ArtifactUuidFix fix group: resource id {}, group name {} ", component.getUniqueId(), group.getName());
+ List<String> groupArtifacts = null == group.getArtifacts()? new ArrayList<>() : new ArrayList<>(group.getArtifacts());
group.setArtifacts(new ArrayList<>());
group.setArtifactsUuid(new ArrayList<>());
group.setGroupInstanceArtifacts(new ArrayList<>());
@@ -285,12 +345,9 @@ public class NodeTemplateMissingDataResolver <T extends Component> {
}
}
}
-
}
}
}
-
return res;
}
-
}
diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/main/MigrationMenu.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/main/MigrationMenu.java
index dd9fa86084..600ebf848a 100644
--- a/asdctool/src/main/java/org/openecomp/sdc/asdctool/main/MigrationMenu.java
+++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/main/MigrationMenu.java
@@ -33,12 +33,7 @@ import org.openecomp.sdc.asdctool.impl.migration.v1607.CsarMigration;
import org.openecomp.sdc.asdctool.impl.migration.v1610.TitanFixUtils;
import org.openecomp.sdc.asdctool.impl.migration.v1610.ToscaArtifactsAlignment;
import org.openecomp.sdc.asdctool.impl.migration.v1702.Migration1702;
-import org.openecomp.sdc.asdctool.impl.migration.v1707.Migration1707;
-import org.openecomp.sdc.asdctool.impl.migration.v1707.Migration1707ArtifactUuidFix;
-import org.openecomp.sdc.asdctool.impl.migration.v1707.Migration1707Config;
-import org.openecomp.sdc.asdctool.impl.migration.v1707.DistributionStatusUpdate;
-import org.openecomp.sdc.asdctool.impl.migration.v1707.Migration1707VnfFix;
-import org.openecomp.sdc.asdctool.impl.migration.v1707.VfModulesPropertiesAdding;
+import org.openecomp.sdc.asdctool.impl.migration.v1707.*;
import org.openecomp.sdc.be.config.ConfigurationManager;
import org.openecomp.sdc.common.api.ConfigurationSource;
import org.openecomp.sdc.common.impl.ExternalConfiguration;
@@ -53,17 +48,17 @@ public class MigrationMenu {
private static final String SERVICE_MIGARTION_BEAN = "serviceMigrationBean";
private static enum MigrationOperationEnum {
- MIGRATION_1602_1604("migrate-1602-1604", SERVICE_MIGARTION_BEAN),
- ALIGN_DERIVED_FROM_1604("align-derived-from-1604", "derivedFromAlignment"),
- MIGRATE_1604_1607("migrate-1604-1607", SERVICE_MIGARTION_BEAN),
- ALIGN_VFC_NAMES_1604("align-vfc-names-1604", "vfcNamingAlignmentBean"),
- TEST_REMOVE_HEAT_PLACEHOLDERS("testremoveheatplaceholders", SERVICE_MIGARTION_BEAN),
- TEST_ADD_GROUP_UUIDS("testaddgroupuuids", SERVICE_MIGARTION_BEAN),
- ALIGN_GROUPS("align-groups", "groupsAlignment"),
- CLEAN_CSAR("clean-csar", "csarMigration"),
- POPULATE_COMPONENT_CACHE("populate-component-cache", "populateComponentCache"),
- FIX_PROPERTIES("fix-properties", "titanFixUtils"),
- ALIGN_TOSCA_ARTIFACTS("align-tosca-artifacts", "toscaArtifactsAlignment"),
+ MIGRATION_1602_1604("migrate-1602-1604", SERVICE_MIGARTION_BEAN),
+ ALIGN_DERIVED_FROM_1604("align-derived-from-1604", "derivedFromAlignment"),
+ MIGRATE_1604_1607("migrate-1604-1607", SERVICE_MIGARTION_BEAN),
+ ALIGN_VFC_NAMES_1604("align-vfc-names-1604", "vfcNamingAlignmentBean"),
+ TEST_REMOVE_HEAT_PLACEHOLDERS("testremoveheatplaceholders", SERVICE_MIGARTION_BEAN),
+ TEST_ADD_GROUP_UUIDS("testaddgroupuuids", SERVICE_MIGARTION_BEAN),
+ ALIGN_GROUPS("align-groups", "groupsAlignment"),
+ CLEAN_CSAR("clean-csar", "csarMigration"),
+ POPULATE_COMPONENT_CACHE("populate-component-cache", "populateComponentCache"),
+ FIX_PROPERTIES("fix-properties", "titanFixUtils"),
+ ALIGN_TOSCA_ARTIFACTS("align-tosca-artifacts", "toscaArtifactsAlignment"),
FIX_ICONS("fix-icons", "titanFixUtils"),
MIGRATION_1610_1702("migrate-1610-1702", "migration1702"),
MIGRATION_1702_1707("migrate-1702-1707", "migration1707"),
@@ -71,7 +66,8 @@ public class MigrationMenu {
VFMODULES_PROPERTIES_ADDING("vfModules-properties-adding", "vfModulesPropertiesAdding"),
MIGRATION_1707_RELATIONS_FIX("fix-relations-after-migration-1707", "migration1707relationsFix"),
MIGRATION_1707_VNF_FIX("fix-vnf-after-migration-1707", "migration1707vnfFix"),
- MIGRATION_1707_UUID_FIX("fix-UUID-1707", "migration1707UuidFix");
+ MIGRATION_1707_UUID_FIX("fix-UUID-1707", "migration1707UuidFix"),
+ MIGRATION_1707_MISSING_INFO_FIX("fix-missing-info-1707", "migration1707MissingInfoFix");
// UPDATE_DATA_TYPES("update_data_types", "updateDataTypes");
private String value, beanName;
@@ -225,7 +221,7 @@ public class MigrationMenu {
ToscaArtifactsAlignment toscaArtifactsAlignment = (ToscaArtifactsAlignment) context.getBean(operationEnum.getBeanName());
boolean isSuccessful = toscaArtifactsAlignment.alignToscaArtifacts();
if (isSuccessful) {
- log.info("Tosca Artifacts alignment was finished successfull");
+ log.info("Tosca Artifacts alignment was finished successfully");
System.exit(0);
} else {
log.info("Tosca Artifacts alignment has failed");
@@ -233,20 +229,20 @@ public class MigrationMenu {
}
break;
case MIGRATION_1610_1702:
- log.info("Start ASDC migration from 1610 to 1702");
+ log.info("Start SDC migration from 1610 to 1702");
Migration1702 migration = (Migration1702) context.getBean(operationEnum.getBeanName());
isSuccessful = migration.migrate(appConfigDir);
if (isSuccessful) {
- log.info("ASDC migration from 1610 to 1702 was finished successful");
+ log.info("SDC migration from 1610 to 1702 was finished successful");
System.exit(0);
} else{
- log.info("ASDC migration from 1610 to 1702 has failed");
+ log.info("SDC migration from 1610 to 1702 has failed");
System.exit(2);
}
-
+
break;
case MIGRATION_1702_1707://this migration is currently not needed, but will be commented out for production env
- log.info("Start ASDC migration from 1702 to 1707");
+// log.info("Start SDC migration from 1702 to 1707");
Migration1707 migration1707 = (Migration1707) context.getBean(operationEnum.getBeanName());
isSuccessful = migration1707.migrate();
if (isSuccessful) {
@@ -278,8 +274,8 @@ public class MigrationMenu {
}
String fixServices = args[3];
String runMode = args[4];
- log.info("Start fixing artifact UUID after 1707 migration with arguments run with configutation [{}] , for [{}] services", runMode, fixServices);
-
+ log.info("Start fixing artifact UUID after 1707 migration with arguments run with configuration [{}] , for [{}] services", runMode, fixServices);
+
Migration1707ArtifactUuidFix migrationFix = (Migration1707ArtifactUuidFix) context.getBean(operationEnum.getBeanName());
isSuccessful = migrationFix.migrate(fixServices, runMode);
if (isSuccessful) {
@@ -290,6 +286,20 @@ public class MigrationMenu {
}
System.exit(0);
break;
+ case MIGRATION_1707_MISSING_INFO_FIX:
+
+ log.info("Start fixing missing group and instance info after 1707 migration");
+
+ Migration1707MissingInfoFix migration1707Fix = (Migration1707MissingInfoFix) context.getBean(operationEnum.getBeanName());
+ isSuccessful = migration1707Fix.migrate();
+ if (isSuccessful) {
+ log.info("Fixing groups and node templates missing info was finished successfully");
+ } else{
+ log.info("Fixing groups and node templates missing info has failed");
+ System.exit(2);
+ }
+ System.exit(0);
+ break;
default:
usageAndExit();
}
@@ -330,5 +340,6 @@ public class MigrationMenu {
System.out.println("Usage: fix-relations-after-migration-1707 <configuration dir>");
System.out.println("Usage: fix-vnf-after-migration-1707 <configuration dir>");
System.out.println("Usage: fix-UUID-1707 <configuration dir> <all/distributed_only> <services/service_vf/fix/fix_only_services>");
+ System.out.println("Usage: fix-missing-info-1707 <configuration dir>");
}
}
diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/config/MigrationSpringConfig.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/config/MigrationSpringConfig.java
new file mode 100644
index 0000000000..0457c2136d
--- /dev/null
+++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/config/MigrationSpringConfig.java
@@ -0,0 +1,59 @@
+package org.openecomp.sdc.asdctool.migration.config;
+
+import org.openecomp.sdc.asdctool.migration.core.SdcMigrationTool;
+import org.openecomp.sdc.asdctool.migration.core.task.Migration;
+import org.openecomp.sdc.asdctool.migration.resolver.MigrationResolver;
+import org.openecomp.sdc.asdctool.migration.resolver.SpringBeansMigrationResolver;
+import org.openecomp.sdc.asdctool.migration.service.SdcRepoService;
+import org.openecomp.sdc.be.dao.cassandra.CassandraClient;
+import org.openecomp.sdc.be.dao.cassandra.MigrationTasksDao;
+import org.openecomp.sdc.be.dao.config.DAOSpringConfig;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Configuration
+@Import(DAOSpringConfig.class)
+@ComponentScan({"org.openecomp.sdc.asdctool.migration.tasks",//migration tasks
+ "org.openecomp.sdc.be.model.operations.impl",
+ "org.openecomp.sdc.be.model.cache",
+ "org.openecomp.sdc.be.dao.titan",
+ "org.openecomp.sdc.be.dao.cassandra",
+ "org.openecomp.sdc.be.model.jsontitan.operations",
+ "org.openecomp.sdc.be.dao.jsongraph"})
+public class MigrationSpringConfig {
+
+ @Autowired(required=false)
+ private List<Migration> migrations = new ArrayList<>();
+
+ @Bean(name = "sdc-migration-tool")
+ public SdcMigrationTool sdcMigrationTool(MigrationResolver migrationResolver, SdcRepoService sdcRepoService) {
+ return new SdcMigrationTool(migrationResolver, sdcRepoService);
+ }
+
+ @Bean(name = "spring-migrations-resolver")
+ public SpringBeansMigrationResolver migrationResolver(SdcRepoService sdcRepoService) {
+ return new SpringBeansMigrationResolver(migrations, sdcRepoService);
+ }
+
+ @Bean(name = "sdc-repo-service")
+ public SdcRepoService sdcRepoService(MigrationTasksDao migrationTasksDao) {
+ return new SdcRepoService(migrationTasksDao);
+ }
+
+ @Bean(name = "sdc-migration-tasks-cassandra-dao")
+ public MigrationTasksDao migrationTasksDao() {
+ return new MigrationTasksDao();
+ }
+
+ @Bean(name = "cassandra-client")
+ public CassandraClient cassandraClient() {
+ return new CassandraClient();
+ }
+
+}
diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/DBVersion.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/DBVersion.java
new file mode 100644
index 0000000000..003a27a1e4
--- /dev/null
+++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/DBVersion.java
@@ -0,0 +1,95 @@
+package org.openecomp.sdc.asdctool.migration.core;
+
+import java.math.BigInteger;
+
+public class DBVersion implements Comparable<DBVersion>{
+
+ private static final String VERSION_PARTS_SEPARATOR = "\\.";
+ private static final int MAJOR_PART_IDX = 0;
+ private static final int MINOR_PART_IDX = 1;
+ private BigInteger major;
+ private BigInteger minor;
+
+ /**
+ * The current db version. should be tested against real db to verify it is compatible to the db version
+ */
+ public static final DBVersion CURRENT_VERSION = new DBVersion(1710, 0);
+
+ private DBVersion(BigInteger major, BigInteger minor) {
+ this.major = major;
+ this.minor = minor;
+ }
+
+ private DBVersion(int major, int minor) {
+ this.major = BigInteger.valueOf(major);
+ this.minor = BigInteger.valueOf(minor);
+ }
+
+ public BigInteger getMajor() {
+ return major;
+ }
+
+ public BigInteger getMinor() {
+ return minor;
+ }
+
+ public static DBVersion from(BigInteger major, BigInteger minor) {
+ return new DBVersion(major, minor);
+ }
+
+ public static DBVersion fromString(String version) {
+ String[] split = version.split(VERSION_PARTS_SEPARATOR);
+ if (split.length != 2) {
+ throw new MigrationException("version must be of pattern: <major>.<minor>");
+ }
+ return new DBVersion(getVersionPart(split[MAJOR_PART_IDX]),
+ getVersionPart(split[MINOR_PART_IDX]));
+
+ }
+
+ private static BigInteger getVersionPart(String versionPart) {
+ try {
+ return new BigInteger(versionPart);
+ } catch (NumberFormatException e) {
+ throw new MigrationException(String.format("version part %s is non numeric", versionPart));
+ }
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s.%s", major, minor);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ DBVersion dbVersion = (DBVersion) o;
+
+ return major.equals(dbVersion.major) && minor.equals(dbVersion.minor);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = major.hashCode();
+ result = 31 * result + minor.hashCode();
+ return result;
+ }
+
+ @Override
+ public int compareTo(DBVersion o) {
+ if (o == null) {
+ return 1;
+ }
+ int majorsComparision = this.major.compareTo(o.major);
+ if (majorsComparision != 0) {
+ return majorsComparision;
+ }
+ int minorsComparision = this.minor.compareTo(o.minor);
+ if (minorsComparision != 0) {
+ return minorsComparision;
+ }
+ return 0;
+ }
+}
diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/MigrationException.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/MigrationException.java
new file mode 100644
index 0000000000..e9e805355e
--- /dev/null
+++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/MigrationException.java
@@ -0,0 +1,13 @@
+package org.openecomp.sdc.asdctool.migration.core;
+
+public class MigrationException extends RuntimeException {
+
+ public MigrationException(String message) {
+ super(message);
+ }
+
+ public MigrationException(String message, RuntimeException e) {
+ super(message, e);
+ }
+
+}
diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/SdcMigrationTool.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/SdcMigrationTool.java
new file mode 100644
index 0000000000..e2691dc7f8
--- /dev/null
+++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/SdcMigrationTool.java
@@ -0,0 +1,62 @@
+package org.openecomp.sdc.asdctool.migration.core;
+
+import org.openecomp.sdc.asdctool.migration.core.execution.MigrationExecutionResult;
+import org.openecomp.sdc.asdctool.migration.core.execution.MigrationExecutorImpl;
+import org.openecomp.sdc.asdctool.migration.core.task.Migration;
+import org.openecomp.sdc.asdctool.migration.core.task.MigrationResult;
+import org.openecomp.sdc.asdctool.migration.resolver.MigrationResolver;
+import org.openecomp.sdc.asdctool.migration.service.SdcRepoService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+
+public class SdcMigrationTool {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(SdcMigrationTool.class);
+
+ private MigrationResolver migrationsResolver;
+
+ private SdcRepoService sdcRepoService;
+
+ public SdcMigrationTool(MigrationResolver migrationsResolver, SdcRepoService sdcRepoService) {
+ this.migrationsResolver = migrationsResolver;
+ this.sdcRepoService = sdcRepoService;
+ }
+
+ public SdcMigrationTool() {
+ }
+
+ public boolean migrate(boolean enforceAll) {
+ LOGGER.info("starting migration process");
+ handleEnforceMigrationFlag(enforceAll);
+ List<Migration> migrations = migrationsResolver.resolveMigrations();
+ LOGGER.info("there are {} migrations task to execute", migrations.size());
+ for (Migration migration : migrations) {
+ try {
+ MigrationExecutionResult executionResult = new MigrationExecutorImpl().execute(migration);
+ if (migrationHasFailed(executionResult)) {
+ LOGGER.error("migration {} with version {} has failed. error msg: {}", migration.getClass().getName(), migration.getVersion().toString(), executionResult.getMsg());
+ return false;
+ }
+ sdcRepoService.createMigrationTask(executionResult.toMigrationTaskEntry());
+ } catch (RuntimeException e) {
+ LOGGER.error("migration {} with version {} has failed. error msg: {}", migration.getClass().getName(), migration.getVersion().toString(), e);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean migrationHasFailed(MigrationExecutionResult migrationResult) {
+ return migrationResult.getMigrationStatus().equals(MigrationResult.MigrationStatus.FAILED);
+ }
+
+ private void handleEnforceMigrationFlag(boolean enforceAll) {
+ if (enforceAll) {
+ LOGGER.info("enforcing migration for current version");
+ sdcRepoService.clearTasksForCurrentMajor();
+ }
+ }
+
+}
diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/execution/MigrationExecutionResult.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/execution/MigrationExecutionResult.java
new file mode 100644
index 0000000000..4ebec6e440
--- /dev/null
+++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/execution/MigrationExecutionResult.java
@@ -0,0 +1,70 @@
+package org.openecomp.sdc.asdctool.migration.core.execution;
+
+import org.openecomp.sdc.asdctool.migration.core.DBVersion;
+import org.openecomp.sdc.asdctool.migration.core.task.MigrationResult;
+import org.openecomp.sdc.be.resources.data.MigrationTaskEntry;
+
+import java.util.Date;
+
+public class MigrationExecutionResult {
+
+ private MigrationResult.MigrationStatus migrationStatus;
+ private String msg;
+ private double executionTime;
+ private DBVersion version;
+ private String taskName;
+
+ public MigrationTaskEntry toMigrationTaskEntry() {
+ MigrationTaskEntry migrationTaskEntry = new MigrationTaskEntry();
+ migrationTaskEntry.setMajorVersion(this.getVersion().getMajor().longValue());
+ migrationTaskEntry.setMinorVersion(this.getVersion().getMinor().longValue());
+ migrationTaskEntry.setTimestamp(new Date());
+ migrationTaskEntry.setTaskName(this.getTaskName());
+ migrationTaskEntry.setTaskStatus(this.getMigrationStatus().name());
+ migrationTaskEntry.setMessage(this.getMsg());
+ migrationTaskEntry.setExecutionTime(this.getExecutionTime());
+ return migrationTaskEntry;
+ }
+
+
+ public MigrationResult.MigrationStatus getMigrationStatus() {
+ return migrationStatus;
+ }
+
+ void setMigrationStatus(MigrationResult.MigrationStatus migrationStatus) {
+ this.migrationStatus = migrationStatus;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+ void setMsg(String msg) {
+ this.msg = msg;
+ }
+
+ double getExecutionTime() {
+ return executionTime;
+ }
+
+ void setExecutionTime(double executionTime) {
+ this.executionTime = executionTime;
+ }
+
+ public DBVersion getVersion() {
+ return version;
+ }
+
+ public void setVersion(DBVersion version) {
+ this.version = version;
+ }
+
+ String getTaskName() {
+ return taskName;
+ }
+
+ void setTaskName(String taskName) {
+ this.taskName = taskName;
+ }
+
+}
diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/execution/MigrationExecutor.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/execution/MigrationExecutor.java
new file mode 100644
index 0000000000..aba5056b48
--- /dev/null
+++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/execution/MigrationExecutor.java
@@ -0,0 +1,15 @@
+package org.openecomp.sdc.asdctool.migration.core.execution;
+
+import org.openecomp.sdc.asdctool.migration.core.MigrationException;
+import org.openecomp.sdc.asdctool.migration.core.task.Migration;
+
+public interface MigrationExecutor {
+
+ /**
+ * @param migration the migration to execute
+ * @return a {@link MigrationExecutionResult} with the relevant data on the current migration execution;
+ * @throws MigrationException in case there was an unexpected exception during migration
+ */
+ MigrationExecutionResult execute(Migration migration) throws MigrationException;
+
+}
diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/execution/MigrationExecutorImpl.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/execution/MigrationExecutorImpl.java
new file mode 100644
index 0000000000..2e4d3ba8b0
--- /dev/null
+++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/execution/MigrationExecutorImpl.java
@@ -0,0 +1,47 @@
+package org.openecomp.sdc.asdctool.migration.core.execution;
+
+import org.openecomp.sdc.asdctool.migration.core.MigrationException;
+import org.openecomp.sdc.asdctool.migration.core.task.Migration;
+import org.openecomp.sdc.asdctool.migration.core.task.MigrationResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.StopWatch;
+
+
+public class MigrationExecutorImpl implements MigrationExecutor {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(MigrationExecutorImpl.class);
+
+ @Override
+ public MigrationExecutionResult execute(Migration migration) throws MigrationException {
+ try {
+ LOGGER.info("starting migration {}. description: {}. version {}", migration.getClass().getName(), migration.description(), migration.getVersion().toString());
+ StopWatch stopWatch = new StopWatch();
+ stopWatch.start();
+ MigrationResult migrationResult = migration.migrate();
+ stopWatch.stop();
+ double executionTime = stopWatch.getTotalTimeSeconds();
+ return logAndCreateExecutionResult(migration, migrationResult, executionTime);
+ } catch (RuntimeException e) {
+ LOGGER.error("migration {} has failed!", migration.description(), e);
+ throw new MigrationException("migration %s failed!!!", e);
+
+ }
+ }
+
+ private MigrationExecutionResult logAndCreateExecutionResult(Migration migration, MigrationResult migrationResult, double executionTime) {
+ LOGGER.info("finished migration {}. with version {}. migration status: {}, migration message: {}, execution time: {}", migration.getClass().getName(), migration.getVersion().toString(), migrationResult.getMigrationStatus().name(), migrationResult.getMsg(), executionTime);
+ return createMigrationTask(migration, migrationResult, executionTime);
+ }
+
+ private MigrationExecutionResult createMigrationTask(Migration migration, MigrationResult migrationResult, double totalTimeSeconds) {
+ MigrationExecutionResult migrationExecutionResult = new MigrationExecutionResult();
+ migrationExecutionResult.setExecutionTime(totalTimeSeconds);
+ migrationExecutionResult.setMigrationStatus(migrationResult.getMigrationStatus());
+ migrationExecutionResult.setMsg(migrationResult.getMsg());
+ migrationExecutionResult.setTaskName(migration.getClass().getName());
+ migrationExecutionResult.setVersion(migration.getVersion());
+ return migrationExecutionResult;
+ }
+
+}
diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/task/Migration.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/task/Migration.java
new file mode 100644
index 0000000000..58f201acf5
--- /dev/null
+++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/task/Migration.java
@@ -0,0 +1,14 @@
+package org.openecomp.sdc.asdctool.migration.core.task;
+
+
+import org.openecomp.sdc.asdctool.migration.core.DBVersion;
+
+public interface Migration {
+
+ String description();
+
+ DBVersion getVersion();
+
+ MigrationResult migrate();
+
+}
diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/task/MigrationResult.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/task/MigrationResult.java
new file mode 100644
index 0000000000..8c4c090d94
--- /dev/null
+++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/core/task/MigrationResult.java
@@ -0,0 +1,31 @@
+package org.openecomp.sdc.asdctool.migration.core.task;
+
+public class MigrationResult {
+
+ private String msg;
+ private MigrationStatus migrationStatus;
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+
+ public MigrationStatus getMigrationStatus() {
+ return migrationStatus;
+ }
+
+ public void setMigrationStatus(MigrationStatus migrationStatus) {
+ this.migrationStatus = migrationStatus;
+ }
+
+ public enum MigrationStatus {
+ COMPLETED,
+ COMPLETED_WITH_ERRORS,
+ FAILED
+ }
+
+
+}
diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/main/MigrationMenu.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/main/MigrationMenu.java
new file mode 100644
index 0000000000..1e8a533624
--- /dev/null
+++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/main/MigrationMenu.java
@@ -0,0 +1,100 @@
+package org.openecomp.sdc.asdctool.migration.main;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.openecomp.sdc.asdctool.migration.config.MigrationSpringConfig;
+import org.openecomp.sdc.asdctool.migration.core.SdcMigrationTool;
+import org.openecomp.sdc.be.config.ConfigurationManager;
+import org.openecomp.sdc.common.api.ConfigurationSource;
+import org.openecomp.sdc.common.impl.ExternalConfiguration;
+import org.openecomp.sdc.common.impl.FSConfigurationSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+public class MigrationMenu {
+
+ private final static Logger LOGGER = LoggerFactory.getLogger(MigrationMenu.class);
+
+ public static void main(String[] args) {
+ CommandLine commandLine = initCmdLineOptions(args);
+ String appConfigDir = commandLine.getOptionValue("c");
+ boolean enforceAll = commandLine.hasOption("e");
+ uploadConfiguration(appConfigDir);
+ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MigrationSpringConfig.class);
+ doMigrate(enforceAll, context);
+
+ }
+
+ private static void doMigrate(boolean enforceAll, AnnotationConfigApplicationContext context) {
+ SdcMigrationTool migrationTool = context.getBean(SdcMigrationTool.class);
+ boolean migrate = migrationTool.migrate(enforceAll);
+ if (migrate) {
+ LOGGER.info("migration completed successfully");
+ System.exit(0);
+ } else {
+ LOGGER.error("migration failed");
+ System.exit(1);
+ }
+ }
+
+ private static CommandLine initCmdLineOptions(String[] args) {
+ Options options = buildCmdLineOptions();
+ CommandLineParser parser = new DefaultParser();
+ try {
+ // parse the command line arguments
+ return parser.parse( options, args );
+ }
+ catch( ParseException exp ) {
+ // oops, something went wrong
+ System.err.println( "Parsing failed. Reason: " + exp.getMessage() );
+ usageAndExit(options);
+ }
+ return null;
+ }
+
+ private static void usageAndExit(Options options) {
+ HelpFormatter formatter = new HelpFormatter();
+ formatter.printHelp( "yy", options );
+ System.exit(1);
+ }
+
+ private static Options buildCmdLineOptions() {
+ Option configPath = buildConfigPathOption();
+
+ Option enforceAll = buildEnforceAllOption();
+
+ Options options = new Options();
+ options.addOption(configPath);
+ options.addOption(enforceAll);
+ return options;
+ }
+
+ private static Option buildEnforceAllOption() {
+ return Option.builder("e")
+ .longOpt("enforceAll")
+ .desc("enforce running all migration steps for current version")
+ .build();
+ }
+
+ private static Option buildConfigPathOption() {
+ return Option.builder("c")
+ .longOpt("configFolderPath")
+ .required()
+ .hasArg()
+ .desc("path to sdc configuration folder - required")
+ .build();
+ }
+
+ private static void uploadConfiguration(String appConfigDir) {
+ ConfigurationSource configurationSource = new FSConfigurationSource(ExternalConfiguration.getChangeListener(), appConfigDir);
+ ConfigurationManager configurationManager = new ConfigurationManager(configurationSource);
+ }
+
+
+}
diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/resolver/MigrationResolver.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/resolver/MigrationResolver.java
new file mode 100644
index 0000000000..b272d45ff0
--- /dev/null
+++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/resolver/MigrationResolver.java
@@ -0,0 +1,16 @@
+package org.openecomp.sdc.asdctool.migration.resolver;
+
+
+import org.openecomp.sdc.asdctool.migration.core.task.Migration;
+
+import java.util.List;
+
+public interface MigrationResolver {
+
+ /**
+ *
+ * @return a list of {@code T}
+ */
+ List<Migration> resolveMigrations();
+
+}
diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/resolver/SpringBeansMigrationResolver.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/resolver/SpringBeansMigrationResolver.java
new file mode 100644
index 0000000000..4af5d76123
--- /dev/null
+++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/resolver/SpringBeansMigrationResolver.java
@@ -0,0 +1,45 @@
+package org.openecomp.sdc.asdctool.migration.resolver;
+
+
+import org.openecomp.sdc.asdctool.migration.core.DBVersion;
+import org.openecomp.sdc.asdctool.migration.core.task.Migration;
+import org.openecomp.sdc.asdctool.migration.service.SdcRepoService;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class SpringBeansMigrationResolver implements MigrationResolver {
+
+ private List<Migration> migrations = new ArrayList<>();
+
+ private SdcRepoService sdcRepoService;
+
+ public SpringBeansMigrationResolver(List<Migration> migrations, SdcRepoService sdcRepoService) {
+ this.migrations = migrations;
+ this.sdcRepoService = sdcRepoService;
+ }
+
+ @Override
+ public List<Migration> resolveMigrations() {
+ migrations.sort(Comparator.comparing(Migration::getVersion));
+ return resolveNonExecutedMigrations();
+ }
+
+ //package private for testing
+ void setMigrations(List<Migration> migrations) {
+ this.migrations = migrations;
+ }
+
+ private List<Migration> resolveNonExecutedMigrations() {
+ DBVersion latestDBVersion = sdcRepoService.getLatestDBVersion();
+ return migrations.stream()
+ .filter(mig -> isMigrationVersionGreaterThanLatestVersion(latestDBVersion, mig))
+ .collect(Collectors.toList());
+ }
+
+ private boolean isMigrationVersionGreaterThanLatestVersion(DBVersion latestDBVersion, Migration mig) {
+ return mig.getVersion().compareTo(latestDBVersion) > 0;
+ }
+}
diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/service/SdcRepoService.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/service/SdcRepoService.java
new file mode 100644
index 0000000000..2888ecb474
--- /dev/null
+++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/service/SdcRepoService.java
@@ -0,0 +1,34 @@
+package org.openecomp.sdc.asdctool.migration.service;
+
+import org.openecomp.sdc.asdctool.migration.core.DBVersion;
+import org.openecomp.sdc.be.dao.cassandra.MigrationTasksDao;
+import org.openecomp.sdc.be.resources.data.MigrationTaskEntry;
+
+import java.math.BigInteger;
+
+public class SdcRepoService {
+
+ private MigrationTasksDao migrationTasksDao;
+
+ public SdcRepoService(MigrationTasksDao migrationTasksDao) {
+ this.migrationTasksDao = migrationTasksDao;
+ }
+
+ public DBVersion getLatestDBVersion() {
+ BigInteger currentMajorVersion = DBVersion.CURRENT_VERSION.getMajor();
+ BigInteger latestMinorVersion = migrationTasksDao.getLatestMinorVersion(currentMajorVersion);
+ return latestMinorVersion == null ? DBVersion.from(currentMajorVersion, BigInteger.valueOf(Integer.MIN_VALUE)) : DBVersion.from(currentMajorVersion, latestMinorVersion);
+ }
+
+ public void clearTasksForCurrentMajor() {
+ BigInteger currentMajorVersion = DBVersion.CURRENT_VERSION.getMajor();
+ migrationTasksDao.deleteAllTasksForVersion(currentMajorVersion);
+ }
+
+ public void createMigrationTask(MigrationTaskEntry migrationTaskEntry) {
+ migrationTasksDao.createMigrationTask(migrationTaskEntry);
+ }
+
+
+
+}
diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/tasks/mig1710/ExampleMigration.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/tasks/mig1710/ExampleMigration.java
new file mode 100644
index 0000000000..1302dc26a8
--- /dev/null
+++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/migration/tasks/mig1710/ExampleMigration.java
@@ -0,0 +1,27 @@
+//package org.openecomp.sdc.asdctool.migration.tasks.mig1710;//package org.openecomp.sdc.migration.tasks.mig1710;
+//
+//import org.openecomp.sdc.asdctool.migration.core.DBVersion;
+//import org.openecomp.sdc.asdctool.migration.core.task.Migration;
+//import org.openecomp.sdc.asdctool.migration.core.task.MigrationResult;
+//import org.springframework.stereotype.Component;
+//
+//@Component
+//public class ExampleMigration implements Migration {
+//
+// @Override
+// public String description() {
+// return "some description";
+// }
+//
+// @Override
+// public DBVersion getVersion() {
+// return DBVersion.fromString("1710.0");
+// }
+//
+// @Override
+// public MigrationResult migrate() {
+// MigrationResult migrationResult = new MigrationResult();
+// migrationResult.setMigrationStatus(MigrationResult.MigrationStatus.COMPLETED);
+// return migrationResult;
+// }
+//} \ No newline at end of file