aboutsummaryrefslogtreecommitdiffstats
path: root/asdctool/src
diff options
context:
space:
mode:
authorMichael Lando <ml636r@att.com>2017-07-17 21:12:03 +0300
committerMichael Lando <ml636r@att.com>2017-07-17 21:12:03 +0300
commit75aacbbe1acf78fa53378f07f0a8c7769449a17e (patch)
tree68a9799eb8f4704dd9a3d513401df9bb11af7739 /asdctool/src
parentdec02e7cc74e1c401be51bd9d266575e1e008f5f (diff)
[SDC] rebase 1710 code
Change-Id: I532ed68979fee7840ea8a5395e7e965b155fb9f9 Signed-off-by: Michael Lando <ml636r@att.com>
Diffstat (limited to 'asdctool/src')
-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
-rw-r--r--asdctool/src/main/resources/config/configuration.yaml1
-rw-r--r--asdctool/src/main/resources/config/logback.xml15
-rw-r--r--asdctool/src/main/resources/scripts/postMigration1707Fix.sh35
-rw-r--r--asdctool/src/main/resources/scripts/sdc-migration.sh36
-rw-r--r--asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/DummyMigrationFactory.java72
-rw-r--r--asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/core/DBVersionTest.java57
-rw-r--r--asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/core/SdcMigrationToolTest.java101
-rw-r--r--asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/core/execution/MigrationExecutorImplTest.java47
-rw-r--r--asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/resolver/SpringBeansMigrationResolverTest.java84
-rw-r--r--asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/scanner/ClassScanner.java81
-rw-r--r--asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/service/SdcRepoServiceTest.java55
-rw-r--r--asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/task/MigrationTasksTest.java56
33 files changed, 1630 insertions, 68 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
diff --git a/asdctool/src/main/resources/config/configuration.yaml b/asdctool/src/main/resources/config/configuration.yaml
index b998e2cf1f..0421d656be 100644
--- a/asdctool/src/main/resources/config/configuration.yaml
+++ b/asdctool/src/main/resources/config/configuration.yaml
@@ -507,6 +507,7 @@ cassandraConfig:
- { name: sdcaudit, replicationStrategy: SimpleStrategy, replicationInfo: ['1']}
- { name: sdcartifact, replicationStrategy: SimpleStrategy, replicationInfo: ['1']}
- { name: sdccomponent, replicationStrategy: SimpleStrategy, replicationInfo: ['1']}
+ - { name: sdcrepository, replicationStrategy: SimpleStrategy, replicationInfo: ['1']}
switchoverDetector:
diff --git a/asdctool/src/main/resources/config/logback.xml b/asdctool/src/main/resources/config/logback.xml
index 0426a32d9e..dadc5254a5 100644
--- a/asdctool/src/main/resources/config/logback.xml
+++ b/asdctool/src/main/resources/config/logback.xml
@@ -4,7 +4,16 @@
<property scope="system" name="ECOMP-subcomponent-name" value="SDC-TOOL" />
<property name="default-log-pattern"
value="%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}|%X{uuid}|%X{serviceInstanceID}|%thread||${ECOMP-subcomponent-name}|%X{userId}|%level|%X{alarmSeverity}|%X{localAddr}|${beFqdn}|%X{remoteAddr}|%logger{35}|%X{timer}|ActivityType=&lt;%M&gt;, Desc=&lt;%msg&gt;%n" />
-
+
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <encoder>
+ <pattern>${default-log-pattern}</pattern>
+ </encoder>
+ </layout>
+ </appender>
+
<appender name="DEBUG_ROLLING"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${HOME}/asdctool/logs/${ECOMP-component-name}/${ECOMP-subcomponent-name}/debug.log</file>
@@ -65,4 +74,8 @@
<appender-ref ref="MALFORMED_DATA"/>
</logger>
+ <logger name="org.openecomp.sdc.asdctool.migration" level="INFO" >
+ <appender-ref ref="STDOUT"/>
+ </logger>
+
</configuration> \ No newline at end of file
diff --git a/asdctool/src/main/resources/scripts/postMigration1707Fix.sh b/asdctool/src/main/resources/scripts/postMigration1707Fix.sh
new file mode 100644
index 0000000000..56a16db70a
--- /dev/null
+++ b/asdctool/src/main/resources/scripts/postMigration1707Fix.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+
+##############################
+# Data Migration 1707
+##############################
+
+CURRENT_DIR=`pwd`
+BASEDIR=$(dirname $0)
+
+if [ ${BASEDIR:0:1} = "/" ]
+then
+ FULL_PATH=$BASEDIR
+else
+ FULL_PATH=$CURRENT_DIR/$BASEDIR
+fi
+
+source ${FULL_PATH}/baseOperation.sh
+
+mainClass="org.openecomp.sdc.asdctool.main.MigrationMenu"
+
+command="java $JVM_LOG_FILE -Xmx6000M -cp $JARS $mainClass fix-missing-info-1707 $@"
+echo $command
+
+$command
+result=$?
+
+
+
+echo "***********************************"
+echo "***** $result *********************"
+echo "***********************************"
+
+exit $result
+
+
diff --git a/asdctool/src/main/resources/scripts/sdc-migration.sh b/asdctool/src/main/resources/scripts/sdc-migration.sh
new file mode 100644
index 0000000000..1616890217
--- /dev/null
+++ b/asdctool/src/main/resources/scripts/sdc-migration.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+
+##############################
+# Data Migration
+##############################
+
+CURRENT_DIR=`pwd`
+BASEDIR=$(dirname $0)
+
+if [ ${BASEDIR:0:1} = "/" ]
+then
+ FULL_PATH=$BASEDIR
+else
+ FULL_PATH=$CURRENT_DIR/$BASEDIR
+fi
+
+source ${FULL_PATH}/baseOperation.sh
+
+mainClass="org.openecomp.sdc.asdctool.migration.main.MigrationMenu"
+
+command="java $JVM_LOG_FILE -Xmx6000M -cp $JARS $mainClass $@"
+echo $command
+
+$command
+result=$?
+
+
+
+echo "***********************************"
+echo "***** $result *********************"
+echo "***********************************"
+
+exit $result
+
+
+
diff --git a/asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/DummyMigrationFactory.java b/asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/DummyMigrationFactory.java
new file mode 100644
index 0000000000..b16951ef02
--- /dev/null
+++ b/asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/DummyMigrationFactory.java
@@ -0,0 +1,72 @@
+package org.openecomp.sdc.asdctool.migration;
+
+
+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;
+
+public class DummyMigrationFactory {
+
+ public static Migration SUCCESSFUL_MIGRATION = new Migration() {
+ @Override
+ public String description() {
+ return "success mig";
+ }
+
+ @Override
+ public DBVersion getVersion() {
+ return DBVersion.fromString("1710.22");
+ }
+
+ @Override
+ public MigrationResult migrate() {
+ MigrationResult migrationResult = new MigrationResult();
+ migrationResult.setMigrationStatus(MigrationResult.MigrationStatus.COMPLETED);
+ migrationResult.setMsg("myMsg");
+ return migrationResult;
+ }
+ };
+
+ public static Migration FAILED_MIGRATION = new Migration() {
+ @Override
+ public String description() {
+ return "failed mig";
+ }
+
+ @Override
+ public DBVersion getVersion() {
+ return DBVersion.fromString("1710.22");
+ }
+
+ @Override
+ public MigrationResult migrate() {
+ MigrationResult migrationResult = new MigrationResult();
+ migrationResult.setMigrationStatus(MigrationResult.MigrationStatus.FAILED);
+ migrationResult.setMsg("myMsg");
+ return migrationResult;
+ }
+ };
+
+ public static Migration getMigration(String version, MigrationResult.MigrationStatus status) {
+ return new Migration() {
+ @Override
+ public String description() {
+ return "success mig";
+ }
+
+ @Override
+ public DBVersion getVersion() {
+ return DBVersion.fromString(version);
+ }
+
+ @Override
+ public MigrationResult migrate() {
+ MigrationResult migrationResult = new MigrationResult();
+ migrationResult.setMigrationStatus(status);
+ migrationResult.setMsg("myMsg");
+ return migrationResult;
+ }
+ };
+ }
+
+}
diff --git a/asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/core/DBVersionTest.java b/asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/core/DBVersionTest.java
new file mode 100644
index 0000000000..4e5fd3ab31
--- /dev/null
+++ b/asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/core/DBVersionTest.java
@@ -0,0 +1,57 @@
+package org.openecomp.sdc.asdctool.migration.core;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+public class DBVersionTest {
+
+
+ @DataProvider(name = "invalidVersionStringsProvider")
+ private Object[][] invalidVersionStringsProvider() {
+ return new Object[][] {
+ {"1.1.1"},
+ {"1.a"},
+ {"a.1"},
+ {"1"}
+ };
+ }
+
+ @Test(dataProvider = "invalidVersionStringsProvider", expectedExceptions = MigrationException.class)
+ public void testFromString_invalidVersionString(String invalidVersion) {
+ DBVersion.fromString(invalidVersion);
+ }
+
+ @DataProvider(name = "validVersionStringsProvider")
+ private Object[][] validVersionStringsProvider() {
+ return new Object[][] {
+ {"1.1", "1.1"},
+ {"10100.0001", "10100.1"},
+ {"000.1", "0.1"},
+ {"01.00001000", "1.1000"},
+ };
+ }
+
+ @Test(dataProvider = "validVersionStringsProvider")
+ public void testFromString(String validString, String expectedVersionString) {
+ assertEquals(expectedVersionString, DBVersion.fromString(validString).toString());
+ }
+
+ @DataProvider(name = "versionComparisionProvider")
+ public static Object[][] versionComparisionProvider() {
+ return new Object[][] {
+ {"1.1", "001.00001", 0},
+ {"10.1", "0010.00001", 0},
+ {"1.1", "001.000010", -1},
+ {"1.1", "0010.00001", -1},
+ {"10.10", "0010.00001", 1},
+ {"1.1", "001.00", 1},
+ };
+ }
+
+ @Test(dataProvider = "versionComparisionProvider")
+ public void testVersionCompareTo2(String firstVersion, String otherVersion, int expectedComparisionResult) throws Exception {
+ assertEquals(DBVersion.fromString(firstVersion).compareTo(DBVersion.fromString(otherVersion)), expectedComparisionResult);
+ }
+}
diff --git a/asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/core/SdcMigrationToolTest.java b/asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/core/SdcMigrationToolTest.java
new file mode 100644
index 0000000000..b1813227e2
--- /dev/null
+++ b/asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/core/SdcMigrationToolTest.java
@@ -0,0 +1,101 @@
+package org.openecomp.sdc.asdctool.migration.core;
+
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.mockito.internal.verification.Times;
+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.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class SdcMigrationToolTest {
+
+ @InjectMocks
+ private SdcMigrationTool testInstance = spy(SdcMigrationTool.class);
+
+ @Mock
+ private MigrationResolver migrationResolverMock;
+
+ @Mock
+ private SdcRepoService sdcRepoServiceMock;
+
+ @BeforeMethod
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Test
+ public void testMigrate_noMigrations() throws Exception {
+ when(migrationResolverMock.resolveMigrations()).thenReturn(Collections.emptyList());
+ testInstance.migrate(false);
+ verify(sdcRepoServiceMock, new Times(0)).clearTasksForCurrentMajor();
+ verify(sdcRepoServiceMock, new Times(0)).createMigrationTask(Mockito.any());
+ }
+
+ @Test
+ public void testMigrate_enforceFlag_removeAllMigrationTasksForCurrentVersion() throws Exception {
+ when(migrationResolverMock.resolveMigrations()).thenReturn(Collections.emptyList());
+ testInstance.migrate(true);
+ verify(sdcRepoServiceMock, new Times(1)).clearTasksForCurrentMajor();
+ }
+
+ @Test
+ public void testMigrate_stopAfterFirstFailure() throws Exception {
+ when(migrationResolverMock.resolveMigrations()).thenReturn(Arrays.asList(new SuccessfulMigration(), new FailedMigration(), new SuccessfulMigration()));
+ testInstance.migrate(false);
+ verify(sdcRepoServiceMock, new Times(0)).clearTasksForCurrentMajor();
+ verify(sdcRepoServiceMock, new Times(1)).createMigrationTask(Mockito.any());
+
+ }
+
+ private class FailedMigration implements Migration {
+
+ @Override
+ public String description() {
+ return null;
+ }
+
+ @Override
+ public DBVersion getVersion() {
+ return DBVersion.fromString("1710.22");
+ }
+
+ @Override
+ public MigrationResult migrate() {
+ MigrationResult migrationResult = new MigrationResult();
+ migrationResult.setMigrationStatus(MigrationResult.MigrationStatus.FAILED);
+ return migrationResult;
+ }
+ }
+
+ private class SuccessfulMigration implements Migration {
+
+ @Override
+ public String description() {
+ return null;
+ }
+
+ @Override
+ public DBVersion getVersion() {
+ return DBVersion.fromString("1710.22");
+ }
+
+ @Override
+ public MigrationResult migrate() {
+ MigrationResult migrationResult = new MigrationResult();
+ migrationResult.setMigrationStatus(MigrationResult.MigrationStatus.COMPLETED);
+ return migrationResult;
+ }
+ }
+}
diff --git a/asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/core/execution/MigrationExecutorImplTest.java b/asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/core/execution/MigrationExecutorImplTest.java
new file mode 100644
index 0000000000..763d6c83d2
--- /dev/null
+++ b/asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/core/execution/MigrationExecutorImplTest.java
@@ -0,0 +1,47 @@
+package org.openecomp.sdc.asdctool.migration.core.execution;
+
+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.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+public class MigrationExecutorImplTest {
+
+ @Test
+ public void testExecuteMigration() throws Exception {
+ MigrationExecutionResult execute = new MigrationExecutorImpl().execute(new DummyMigration());
+
+ }
+
+ private void assertMigrationTaskEntryByMigrationExecutionResult(MigrationExecutionResult executionResult, Migration migration, MigrationResult result) {
+ assertEquals(executionResult.getMsg(), result.getMsg());
+ assertEquals(executionResult.getMigrationStatus().name(), result.getMigrationStatus());
+ assertEquals(executionResult.getTaskName(), migration.getClass().getName());
+ assertEquals(executionResult.getVersion(), migration.getVersion());
+ assertNotNull(executionResult.getExecutionTime());
+ }
+
+ private class DummyMigration implements Migration {
+
+ @Override
+ public String description() {
+ return null;
+ }
+
+ @Override
+ public DBVersion getVersion() {
+ return DBVersion.fromString("1710.22");
+ }
+
+ @Override
+ public MigrationResult migrate() {
+ MigrationResult migrationResult = new MigrationResult();
+ migrationResult.setMigrationStatus(MigrationResult.MigrationStatus.COMPLETED);
+ migrationResult.setMsg("myMsg");
+ return migrationResult;
+ }
+ }
+}
diff --git a/asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/resolver/SpringBeansMigrationResolverTest.java b/asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/resolver/SpringBeansMigrationResolverTest.java
new file mode 100644
index 0000000000..6084608f0e
--- /dev/null
+++ b/asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/resolver/SpringBeansMigrationResolverTest.java
@@ -0,0 +1,84 @@
+package org.openecomp.sdc.asdctool.migration.resolver;
+
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+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.openecomp.sdc.asdctool.migration.service.SdcRepoService;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static org.mockito.Mockito.when;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+public class SpringBeansMigrationResolverTest {
+
+ @InjectMocks
+ private SpringBeansMigrationResolver testInstance;
+
+ @Mock
+ private SdcRepoService sdcRepoServiceMock;
+
+ private List<Migration> migrations = Arrays.asList(createMigration("1710.1"), createMigration("1710.22"), createMigration("1707.12"), createMigration("1710.3"));
+
+
+ @BeforeMethod
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ testInstance.setMigrations(migrations);
+ }
+
+ @Test
+ public void testResolveMigrations_getMigrationsWithVersionGreaterThanLatest() throws Exception {
+ when(sdcRepoServiceMock.getLatestDBVersion()).thenReturn(DBVersion.fromString("1710.2"));
+ List<Migration> resolvedMigrations = testInstance.resolveMigrations();
+ assertEquals(resolvedMigrations.size(), 2);
+ assertEquals(resolvedMigrations.get(0).getVersion(), DBVersion.fromString("1710.3"));
+ assertEquals(resolvedMigrations.get(1).getVersion(), DBVersion.fromString("1710.22"));
+ }
+
+ @Test
+ public void testResolveMigration_noLatestVersionForCurrentMajorVersion() throws Exception {
+ when(sdcRepoServiceMock.getLatestDBVersion()).thenReturn(DBVersion.fromString("1710.-1"));
+ List<Migration> resolvedMigrations = testInstance.resolveMigrations();
+ assertEquals(resolvedMigrations.size(), 3);
+ assertEquals(resolvedMigrations.get(0).getVersion(), DBVersion.fromString("1710.1"));
+ assertEquals(resolvedMigrations.get(1).getVersion(), DBVersion.fromString("1710.3"));
+ assertEquals(resolvedMigrations.get(2).getVersion(), DBVersion.fromString("1710.22"));
+ }
+
+ @Test
+ public void testResolveMigrations_emptyMigrationsList() throws Exception {
+ testInstance.setMigrations(Collections.emptyList());
+ when(sdcRepoServiceMock.getLatestDBVersion()).thenReturn(DBVersion.fromString("1710.-1"));
+ List<Migration> resolvedMigrations = testInstance.resolveMigrations();
+ assertTrue(resolvedMigrations.isEmpty());
+ }
+
+ private Migration createMigration(String version) {
+ return new Migration() {
+ @Override
+ public String description() {
+ return null;
+ }
+
+ @Override
+ public DBVersion getVersion() {
+ return DBVersion.fromString(version);
+ }
+
+ @Override
+ public MigrationResult migrate() {
+ return null;
+ }
+ };
+ }
+
+}
diff --git a/asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/scanner/ClassScanner.java b/asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/scanner/ClassScanner.java
new file mode 100644
index 0000000000..a2bf623b83
--- /dev/null
+++ b/asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/scanner/ClassScanner.java
@@ -0,0 +1,81 @@
+package org.openecomp.sdc.asdctool.migration.scanner;
+
+import org.apache.commons.io.FileUtils;
+import org.openecomp.sdc.asdctool.migration.core.MigrationException;
+
+import java.io.File;
+import java.lang.reflect.Modifier;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * scan and instantiate classes of given type in the class path
+ */
+public class ClassScanner {
+
+
+ private ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+
+ public <T> List<T> getAllClassesOfType(String basePackage, Class<T> ofType) {
+ Collection<File> allClassesInPackage = getAllClassesInPackage(basePackage);
+ List<T> loadedClasses = new ArrayList<>();
+ for (File clazzFile : allClassesInPackage) {
+ Optional<T> instance = loadAndInstantiateClass(getClassReference(clazzFile), ofType);
+ instance.ifPresent(loadedClasses::add);
+ }
+ return loadedClasses;
+ }
+
+ private <T> Optional<T> loadAndInstantiateClass(String classReference, Class<T> ofType) {
+ try {
+ return instantiateClassOfType(classReference, ofType);
+ }catch (ClassNotFoundException e) {
+ //log
+ throw new MigrationException(String.format("could not find class %s of type %s. cause: %s", classReference, ofType.toGenericString(), e.getMessage()));
+ } catch (IllegalAccessException e1) {
+ //log
+ throw new MigrationException(String.format("could not instantiate class %s of type %s. class is not accessible. cause: %s", classReference, ofType.toGenericString(), e1.getMessage()));
+ } catch (InstantiationException e2) {
+ //log
+ throw new MigrationException(String.format("could not instantiate class %s of type %s. cause: %s", classReference, ofType.toGenericString(), e2.getMessage()));
+ }
+ }
+
+ private <T> Optional<T> instantiateClassOfType(String classReference, Class<T> ofType) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
+ String className = classReference.replaceAll(".class$", "").replaceAll(".class", "");
+ Class<?> aClass = classLoader.loadClass(className);
+ if (ofType.isAssignableFrom(aClass) && isInstantiateAbleClass(aClass)){
+ return Optional.of((T) aClass.newInstance());
+ }
+ return Optional.empty();
+ }
+
+ private boolean isInstantiateAbleClass(Class<?> clazz) {
+ return !Modifier.isAbstract(clazz.getModifiers()) && !clazz.isEnum() && !clazz.isAnonymousClass() && !clazz.isInterface();
+ }
+
+ private Collection<File> getAllClassesInPackage(String fromPackage) {
+ String path = fromPackage.replace(".", "/");
+ URL resource = classLoader.getResource(path);
+ if (noMigrationTasks(resource)) {
+ return Collections.emptyList();
+ }
+ return FileUtils.listFiles(new File(resource.getFile()), new String[]{"class"}, true);
+ }
+
+ private boolean noMigrationTasks(URL resource) {
+ return resource == null;
+ }
+
+ private String getClassReference(File classFile) {
+ String asPackage = classFile.getPath().replace(File.separator, ".");
+ String classes = "classes.";
+ return asPackage.substring(asPackage.indexOf(classes) + classes.length());
+ }
+
+
+}
diff --git a/asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/service/SdcRepoServiceTest.java b/asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/service/SdcRepoServiceTest.java
new file mode 100644
index 0000000000..f8e9abe2c9
--- /dev/null
+++ b/asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/service/SdcRepoServiceTest.java
@@ -0,0 +1,55 @@
+package org.openecomp.sdc.asdctool.migration.service;
+
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.internal.verification.Times;
+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 org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.math.BigInteger;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.testng.Assert.assertEquals;
+
+public class SdcRepoServiceTest {
+
+ @InjectMocks
+ private SdcRepoService testInstance;
+
+ @Mock
+ private MigrationTasksDao migrationTasksDaoMock;
+
+ @BeforeMethod
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Test
+ public void testGetLatestVersion_noMinorVersionForCurrentVersion() throws Exception {
+ when(migrationTasksDaoMock.getLatestMinorVersion(DBVersion.CURRENT_VERSION.getMajor())).thenReturn(null);
+ DBVersion latestDBVersion = testInstance.getLatestDBVersion();
+ assertEquals(latestDBVersion.getMajor(), DBVersion.CURRENT_VERSION.getMajor());
+ assertEquals(latestDBVersion.getMinor(), BigInteger.valueOf(Integer.MIN_VALUE));
+ }
+
+ @Test
+ public void testGetLatestVersion() throws Exception {
+ when(migrationTasksDaoMock.getLatestMinorVersion(DBVersion.CURRENT_VERSION.getMajor())).thenReturn(BigInteger.TEN);
+ DBVersion latestDBVersion = testInstance.getLatestDBVersion();
+ assertEquals(latestDBVersion.getMajor(), DBVersion.CURRENT_VERSION.getMajor());
+ assertEquals(latestDBVersion.getMinor(), BigInteger.TEN);
+ }
+
+ @Test
+ public void testCreateMigrationTask() throws Exception {
+ MigrationTaskEntry taskEntry = new MigrationTaskEntry();
+ testInstance.createMigrationTask(taskEntry);
+ verify(migrationTasksDaoMock, new Times(1)).createMigrationTask(taskEntry);
+ }
+
+}
diff --git a/asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/task/MigrationTasksTest.java b/asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/task/MigrationTasksTest.java
new file mode 100644
index 0000000000..037d51ba12
--- /dev/null
+++ b/asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/task/MigrationTasksTest.java
@@ -0,0 +1,56 @@
+package org.openecomp.sdc.asdctool.migration.task;
+
+import org.apache.commons.lang.StringUtils;
+import org.openecomp.sdc.asdctool.migration.core.DBVersion;
+import org.openecomp.sdc.asdctool.migration.core.task.Migration;
+import org.openecomp.sdc.asdctool.migration.scanner.ClassScanner;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+
+public class MigrationTasksTest {
+
+ public static final String MIGRATIONS_BASE_PACKAGE = "org.openecomp.sdc.asdctool.migration.tasks";
+ private List<Migration> migrations;
+
+ @BeforeMethod
+ public void setUp() throws Exception {
+ ClassScanner classScanner = new ClassScanner();
+ migrations = classScanner.getAllClassesOfType(MIGRATIONS_BASE_PACKAGE, Migration.class);
+ }
+
+ @Test
+ public void testNoTasksWithSameVersion() throws Exception {
+ Map<DBVersion, List<Migration>> migrationsByVersion = migrations.stream().collect(Collectors.groupingBy(Migration::getVersion));
+ migrationsByVersion.forEach((version, migrations) -> {
+ if (migrations.size() > 1) {
+ System.out.println(String.format("the following migration tasks have the same version %s. versions must be unique", version.toString()));
+ Assert.fail(String.format("migration tasks %s has same version %s. migration tasks versions must be unique.", getMigrationsNameAsString(migrations), version.toString()));
+ }
+ });
+ }
+
+ @Test
+ public void testNoTaskWithVersionGreaterThanCurrentVersion() throws Exception {
+ Set<Migration> migrationsWithVersionsGreaterThanCurrent = migrations.stream().filter(mig -> mig.getVersion().compareTo(DBVersion.CURRENT_VERSION) > 0)
+ .collect(Collectors.toSet());
+
+ if (!migrationsWithVersionsGreaterThanCurrent.isEmpty()) {
+ Assert.fail(String.format("migrations tasks %s have version which is greater than DBVersion.CURRENT_VERSION %s. did you forget to update current version?",
+ getMigrationsNameAsString(migrationsWithVersionsGreaterThanCurrent),
+ DBVersion.CURRENT_VERSION.toString()));
+ }
+ }
+
+ private String getMigrationsNameAsString(Collection<Migration> migrations) {
+ return StringUtils.join(migrations.stream().map(mig -> mig.getClass().getName()).collect(Collectors.toList()), ",");
+ }
+}