heal all script

Issue - ID: SDC-665

Change-Id: Ib035549589ccd9c113235886442b1b2c9a198b86
Signed-off-by: ayalaben <ayala.benzvi@amdocs.com>
diff --git a/openecomp-be/tools/zusammen-tools/pom.xml b/openecomp-be/tools/zusammen-tools/pom.xml
index ecb185e..b4a61c5 100644
--- a/openecomp-be/tools/zusammen-tools/pom.xml
+++ b/openecomp-be/tools/zusammen-tools/pom.xml
@@ -17,32 +17,32 @@
         <dependency>
             <groupId>org.openecomp.sdc</groupId>
             <artifactId>openecomp-sdc-vendor-software-product-api</artifactId>
-            <version>1.2.0-SNAPSHOT</version>
+            <version>${project.version}</version>
         </dependency>
         <dependency>
             <artifactId>openecomp-zusammen-plugin</artifactId>
             <groupId>org.openecomp.sdc.core</groupId>
-            <version>1.2.0-SNAPSHOT</version>
+            <version>${project.version}</version>
         </dependency>
         <dependency>
             <groupId>org.openecomp.sdc</groupId>
             <artifactId>openecomp-sdc-vendor-software-product-core</artifactId>
-            <version>1.2.0-SNAPSHOT</version>
+            <version>${project.version}</version>
         </dependency>
         <dependency>
             <groupId>org.openecomp.sdc</groupId>
             <artifactId>openecomp-sdc-vendor-license-api</artifactId>
-            <version>1.2.0-SNAPSHOT</version>
+            <version>${project.version}</version>
         </dependency>
         <dependency>
             <groupId>org.openecomp.sdc</groupId>
             <artifactId>openecomp-sdc-model-impl</artifactId>
-            <version>1.2.0-SNAPSHOT</version>
+            <version>${project.version}</version>
         </dependency>
         <dependency>
             <groupId>org.openecomp.sdc.core</groupId>
             <artifactId>openecomp-zusammen-core</artifactId>
-            <version>1.2.0-SNAPSHOT</version>
+            <version>${project.version}</version>
         </dependency>
         <dependency>
             <groupId>com.amdocs.zusammen.plugin</groupId>
@@ -57,7 +57,12 @@
         <dependency>
             <groupId>org.openecomp.sdc</groupId>
             <artifactId>openecomp-sdc-vendor-license-core</artifactId>
-            <version>1.2.0-SNAPSHOT</version>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.openecomp.sdc</groupId>
+            <artifactId>openecomp-sdc-vendor-software-product-manager</artifactId>
+            <version>${project.version}</version>
         </dependency>
     </dependencies>
     <artifactId>openecomp-zusammen-tools</artifactId>
diff --git a/openecomp-be/tools/zusammen-tools/src/main/java/org/openecomp/core/tools/Commands/HealAll.java b/openecomp-be/tools/zusammen-tools/src/main/java/org/openecomp/core/tools/Commands/HealAll.java
new file mode 100644
index 0000000..2bc48bd
--- /dev/null
+++ b/openecomp-be/tools/zusammen-tools/src/main/java/org/openecomp/core/tools/Commands/HealAll.java
@@ -0,0 +1,142 @@
+package org.openecomp.core.tools.Commands;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.openecomp.core.tools.concurrent.ItemHealingTask;
+import org.openecomp.core.tools.loaders.VersionInfoCassandraLoader;
+import org.openecomp.sdc.vendorsoftwareproduct.VendorSoftwareProductConstants;
+import org.openecomp.sdc.vendorsoftwareproduct.VendorSoftwareProductManager;
+import org.openecomp.sdc.vendorsoftwareproduct.VspManagerFactory;
+import org.openecomp.sdc.versioning.VersioningManager;
+import org.openecomp.sdc.versioning.VersioningManagerFactory;
+import org.openecomp.sdc.versioning.dao.types.Version;
+import org.openecomp.sdc.versioning.dao.types.VersionInfoEntity;
+
+import java.io.BufferedWriter;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.time.Duration;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.stream.Stream;
+
+/**
+ * Created by ayalaben on 11/6/2017
+ */
+public class HealAll {
+
+  private static final String HEALING_USER = "healing_user";
+  private static final int defaulThreadNumber =100;
+  private static BufferedWriter log;
+  private static List<ItemHealingTask> tasks = new ArrayList<>();
+  private static VendorSoftwareProductManager vspManager = VspManagerFactory
+      .getInstance().createInterface();
+  private static VersioningManager versioningManager = VersioningManagerFactory.getInstance()
+      .createInterface();
+
+  static {
+    try {
+      log =
+          new BufferedWriter(new FileWriter("healing.log",true));
+    } catch (IOException e) {
+      if (log != null) {
+        try {
+          log.close();
+        } catch (IOException e1) {
+          throw new RuntimeException("can't initial healing log file: " + e1.getMessage());
+        }
+      }
+      throw new RuntimeException("can't initial healing log file: " + e.getMessage());
+    }
+  }
+
+  public static void healAll(String threadNumber) {
+
+    writeToLog("----starting healing------");
+    Instant startTime = Instant.now();
+
+    int numberOfThreads = Objects.nonNull(threadNumber) ? Integer.valueOf(threadNumber) :
+        defaulThreadNumber;
+    ExecutorService executor = Executors.newFixedThreadPool(numberOfThreads);
+
+   filterByEntityType(VersionInfoCassandraLoader.list(),
+        VendorSoftwareProductConstants.VENDOR_SOFTWARE_PRODUCT_VERSIONABLE_TYPE).forEach
+       (HealAll::addTaskToTasks);
+
+    executeAllTasks(executor);
+
+    writeToLog("----finished healing------" );
+    Instant endTime = Instant.now();
+    writeToLog("Total runtime was: " + Duration.between(startTime, endTime));
+
+    try {
+      if (log != null) {
+        log.close();
+      }
+    } catch (IOException e) {
+      writeToLog("Error:" + e.getMessage());
+    }
+
+    System.exit(1);
+  }
+
+  private static void executeAllTasks(ExecutorService executor) {
+    List<Future<String>> futureTasks;
+    try {
+      futureTasks = executor.invokeAll(tasks);
+      futureTasks.forEach(future -> {
+        try {
+          log.write(future.get());
+          log.newLine();
+        } catch (Exception e) {
+          writeToLog(e.getMessage());
+        }
+      });
+    } catch (InterruptedException e) {
+      writeToLog("migration tasks failed with message: " + e.getMessage());
+      throw new RuntimeException(e);
+    }
+
+    boolean isThreadOpen = true;
+    while (isThreadOpen) {
+      isThreadOpen = futureTasks.stream().anyMatch(future -> !future.isDone());
+    }
+  }
+
+  private static Version resolveVersion(VersionInfoEntity versionInfoEntity) {
+    if (Objects.nonNull(versionInfoEntity.getCandidate())) {
+      return versionInfoEntity.getCandidate().getVersion();
+    } else if (!CollectionUtils.isEmpty(versionInfoEntity.getViewableVersions())) {
+     return versionInfoEntity.getViewableVersions().stream().max(Version::compateTo).get();
+    }
+    return versionInfoEntity.getActiveVersion();
+  }
+
+  private static void writeToLog(String message) {
+    try {
+      log.write(message);
+      log.newLine();
+    } catch (IOException e) {
+      throw new RuntimeException("unable to write to healing all log file.");
+    }
+  }
+
+  private static Stream<VersionInfoEntity> filterByEntityType(Collection<VersionInfoEntity>
+                                                             versionInfoEntities,
+                                                     String entityType){
+    return versionInfoEntities.stream().filter(versionInfoEntity -> versionInfoEntity
+        .getEntityType().equals(entityType));
+  }
+  private static void addTaskToTasks(VersionInfoEntity versionInfoEntity){
+    tasks.add(new ItemHealingTask(versionInfoEntity.getEntityId(), resolveVersion
+            (versionInfoEntity).toString(), versionInfoEntity.getCandidate() == null ?
+            HEALING_USER : versionInfoEntity.getCandidate().getUser(),
+            vspManager, versioningManager));
+  }
+
+}
diff --git a/openecomp-be/tools/zusammen-tools/src/main/java/org/openecomp/core/tools/concurrent/ItemHealingTask.java b/openecomp-be/tools/zusammen-tools/src/main/java/org/openecomp/core/tools/concurrent/ItemHealingTask.java
new file mode 100644
index 0000000..39b62d4
--- /dev/null
+++ b/openecomp-be/tools/zusammen-tools/src/main/java/org/openecomp/core/tools/concurrent/ItemHealingTask.java
@@ -0,0 +1,71 @@
+package org.openecomp.core.tools.concurrent;
+
+import org.openecomp.sdc.vendorsoftwareproduct.VendorSoftwareProductConstants;
+import org.openecomp.sdc.vendorsoftwareproduct.VendorSoftwareProductManager;
+import org.openecomp.sdc.vendorsoftwareproduct.dao.type.VspDetails;
+import org.openecomp.sdc.versioning.VersioningManager;
+import org.openecomp.sdc.versioning.VersioningUtil;
+import org.openecomp.sdc.versioning.dao.types.Version;
+import org.openecomp.sdc.versioning.types.VersionInfo;
+import org.openecomp.sdc.versioning.types.VersionableEntityAction;
+
+import java.util.concurrent.Callable;
+
+/**
+ * Created by ayalaben on 11/7/2017
+ */
+public class ItemHealingTask implements Callable<String> {
+
+  private String itemId;
+  private String versionId;
+  private String user;
+  private VendorSoftwareProductManager vspManager;
+  private VersioningManager versioningManager;
+
+  public String getItemId() {
+    return itemId;
+  }
+
+  public String getVersionId() {
+    return versionId;
+  }
+
+
+  public ItemHealingTask(String itemId, String versionId, String user,
+                         VendorSoftwareProductManager vspManager,
+                         VersioningManager versioningManager) {
+    this.itemId = itemId;
+    this.versionId = versionId;
+    this.user = user;
+    this.versioningManager = versioningManager;
+    this.vspManager = vspManager;
+  }
+
+  @Override
+  public String call() throws Exception {
+
+    VersionInfo versionInfo = getVersionInfo(itemId, VersionableEntityAction.Read, user);
+    Version resolvedVersion = VersioningUtil.resolveVersion(Version.valueOf(versionId),
+        versionInfo, user);
+    VspDetails vspDetails = vspManager.getVsp(itemId, resolvedVersion, user);
+
+    try {
+      vspManager.callAutoHeal(itemId, versionInfo, vspDetails, user);
+
+    } catch (Exception e) {
+      return (String.format("healing failed on vsp: %s with id: %s, versionId: %s, resolved " +
+              "Version: %s, with message: %s",vspDetails.getName(),itemId,
+          versionId,resolvedVersion,e.getMessage()));
+    }
+
+    return String.format("healed vsp: %s, with id: %s, versionId:%s, resolved version: %s",
+        vspDetails.getName(), itemId, versionId,resolvedVersion );
+  }
+
+  private VersionInfo getVersionInfo(String vendorSoftwareProductId, VersionableEntityAction action,
+                                     String user) {
+    return versioningManager.getEntityVersionInfo(
+        VendorSoftwareProductConstants.VENDOR_SOFTWARE_PRODUCT_VERSIONABLE_TYPE,
+        vendorSoftwareProductId, user, action);
+  }
+}
diff --git a/openecomp-be/tools/zusammen-tools/src/main/java/org/openecomp/core/tools/loaders/VersionInfoCassandraLoader.java b/openecomp-be/tools/zusammen-tools/src/main/java/org/openecomp/core/tools/loaders/VersionInfoCassandraLoader.java
index 8840975..aba8754 100644
--- a/openecomp-be/tools/zusammen-tools/src/main/java/org/openecomp/core/tools/loaders/VersionInfoCassandraLoader.java
+++ b/openecomp-be/tools/zusammen-tools/src/main/java/org/openecomp/core/tools/loaders/VersionInfoCassandraLoader.java
@@ -20,7 +20,6 @@
 
 package org.openecomp.core.tools.loaders;
 
-import com.datastax.driver.mapping.Mapper;
 import com.datastax.driver.mapping.Result;
 import com.datastax.driver.mapping.annotations.Accessor;
 import com.datastax.driver.mapping.annotations.Query;
@@ -30,18 +29,14 @@
 
 import java.util.Collection;
 
-public class VersionInfoCassandraLoader  {
+public class VersionInfoCassandraLoader {
 
   private static NoSqlDb noSqlDb = NoSqlDbFactory.getInstance().createInterface();
-  private static Mapper<VersionInfoEntity> mapper =
-      noSqlDb.getMappingManager().mapper(VersionInfoEntity.class);
   private static VersionInfoAccessor accessor =
       noSqlDb.getMappingManager().createAccessor(VersionInfoAccessor.class);
 
 
-
-
-  public Collection<VersionInfoEntity> list() {
+  public static Collection<VersionInfoEntity> list() {
     return accessor.getAll().all();
   }
 
diff --git a/openecomp-be/tools/zusammen-tools/src/main/java/org/openecomp/core/tools/main/ZusammenMainTool.java b/openecomp-be/tools/zusammen-tools/src/main/java/org/openecomp/core/tools/main/ZusammenMainTool.java
index 6f092d2..b55d517 100644
--- a/openecomp-be/tools/zusammen-tools/src/main/java/org/openecomp/core/tools/main/ZusammenMainTool.java
+++ b/openecomp-be/tools/zusammen-tools/src/main/java/org/openecomp/core/tools/main/ZusammenMainTool.java
@@ -2,6 +2,7 @@
 
 import com.amdocs.zusammen.datatypes.SessionContext;
 import com.amdocs.zusammen.datatypes.UserInfo;
+import org.openecomp.core.tools.Commands.HealAll;
 import org.openecomp.core.tools.Commands.ImportCommand;
 import org.openecomp.core.tools.Commands.ExportDataCommand;
 import org.openecomp.core.tools.Commands.ResetOldVersion;
@@ -46,6 +47,8 @@
       case IMPORT:
         ImportCommand.importData(context, ToolsUtil.getParam("f",args),ToolsUtil.getParam("i",args));
         break;
+      case HEAL_ALL:
+        HealAll.healAll(ToolsUtil.getParam("t",args));
 
     }
 
@@ -68,7 +71,8 @@
 
     RESET_OLD_VERSION("reset-old-version"),
     EXPORT("export"),
-    IMPORT("import");
+    IMPORT("import"),
+    HEAL_ALL("heal-all");
 
     COMMANDS(String command) {
       this.command  = command;
diff --git a/openecomp-be/tools/zusammen-tools/src/main/resources/zusammenMainTool.sh b/openecomp-be/tools/zusammen-tools/src/main/resources/zusammenMainTool.sh
index 78af19b..61388a1 100644
--- a/openecomp-be/tools/zusammen-tools/src/main/resources/zusammenMainTool.sh
+++ b/openecomp-be/tools/zusammen-tools/src/main/resources/zusammenMainTool.sh
@@ -8,6 +8,7 @@
 #  3.  Import one item - ./zusammenMainTool.sh -c  IMPORT -f ${fileName} -i ${elementId}
 #  4.  Import all - ./zusammenMainTool.sh -c  IMPORT -f  ${fileName}
 #  5.  Reset old version - ./zusammenMainTool.sh -c  RESET_OLD_VERSION
+#  6.  Heal all - ./zusammenMainTool.sh -c  HEAL_ALL -t ${thread number}
 #
 ##########################################################################################################
 
@@ -22,5 +23,5 @@
 fi
 echo "Configuration file location:  ${CONF_FILE_LOCATION}"
 
-java -Dlog.home=/apps/jetty/base/be/logs -Dconfiguration.yaml=${CONF_FILE_LOCATION}  -jar openecomp-zusammen-tools-1.2.0-SNAPSHOT.jar org.openecomp.core.tools.main.ZusammenMainTool $1 $2 $3 $4 $5 $6
+java -Dconfig.home=/opt/app/jetty/base/be/config -Dlog.home=/apps/jetty/base/be/logs -Dconfiguration.yaml=${CONF_FILE_LOCATION}  -classpath openecomp-zusammen-tools-1.2.0-SNAPSHOT.jar:lib/* org.openecomp.core.tools.main.ZusammenMainTool $1 $2 $3 $4 $5 $6
 STATUS="${?}" echo "${STATUS}"