class SnapshotService {

  public List<Pair<Node, String>> takeSnapshotClusterWide(
      String snapshotName,
      String clusterName,
      String owner,
      String cause,
      String... keyspace) throws ReaperException {

    try {
      List<Pair<Node, String>> snapshotResults = Lists.newArrayList();
      Cluster cluster = context.storage.getCluster(clusterName);

      Snapshot snapshot = Snapshot.builder()
              .withClusterName(clusterName)
              .withName(snapshotName)
              .withOwner(owner)
              .withCause(cause)
              .withCreationDate(DateTime.now())
              .build();

      context.storage.saveSnapshot(snapshot);
      LOG.info("Cluster : {} ; Cluster obj : {}", clusterName, cluster);
      List<String> liveNodes = clusterFacade.getLiveNodes(cluster);

      List<Callable<Pair<Node, String>>> snapshotTasks = liveNodes
              .stream()
              .map(host -> Node.builder().withCluster(cluster).withHostname(host).build())
              .map(node -> takeSnapshotTask(snapshotName, node, keyspace))
              .collect(Collectors.toList());

      List<Future<Pair<Node, String>>> futures = executor.invokeAll(snapshotTasks);
      for (Future<Pair<Node, String>> future : futures) {
        snapshotResults.add(future.get());
      }

      return snapshotResults;
    } catch (InterruptedException | ExecutionException e) {
      LOG.error("Failed taking snapshot for cluster {}", clusterName, e);
      throw new ReaperException(e);
    }
  }

  private  SnapshotService(AppContext context, ExecutorService executor, Supplier<ClusterFacade> clusterFacadeSupplier);

}