private void downloadTemplateToStorage(VMTemplateVO template, HostVO sserver) {
    boolean downloadJobExists = false;
    VMTemplateHostVO vmTemplateHost = null;

    vmTemplateHost = _vmTemplateHostDao.findByHostTemplate(sserver.getId(), template.getId());
    if (vmTemplateHost == null) {
      vmTemplateHost =
          new VMTemplateHostVO(
              sserver.getId(),
              template.getId(),
              new Date(),
              0,
              VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED,
              null,
              null,
              "jobid0000",
              null,
              template.getUrl());
      _vmTemplateHostDao.persist(vmTemplateHost);
    } else if ((vmTemplateHost.getJobId() != null) && (vmTemplateHost.getJobId().length() > 2)) {
      downloadJobExists = true;
    }

    Long maxTemplateSizeInBytes = getMaxTemplateSizeInBytes();
    String secUrl = sserver.getStorageUrl();
    if (vmTemplateHost != null) {
      start();
      DownloadCommand dcmd = new DownloadCommand(secUrl, template, maxTemplateSizeInBytes);
      if (downloadJobExists) {
        dcmd =
            new DownloadProgressCommand(
                dcmd, vmTemplateHost.getJobId(), RequestType.GET_OR_RESTART);
      }
      dcmd.setProxy(getHttpProxy());
      if (vmTemplateHost.isCopy()) {
        dcmd.setCreds(TemplateConstants.DEFAULT_HTTP_AUTH_USER, _copyAuthPasswd);
      }
      HostVO ssAhost = _ssvmMgr.pickSsvmHost(sserver);
      if (ssAhost == null) {
        s_logger.warn(
            "There is no secondary storage VM for secondary storage host " + sserver.getName());
        return;
      }
      DownloadListener dl =
          new DownloadListener(
              ssAhost,
              sserver,
              template,
              _timer,
              _vmTemplateHostDao,
              vmTemplateHost.getId(),
              this,
              dcmd,
              _templateDao,
              _resourceLimitMgr,
              _alertMgr,
              _accountMgr);
      if (downloadJobExists) {
        dl.setCurrState(vmTemplateHost.getDownloadState());
      }
      DownloadListener old = null;
      synchronized (_listenerMap) {
        old = _listenerMap.put(vmTemplateHost, dl);
      }
      if (old != null) {
        old.abandon();
      }

      try {
        send(ssAhost.getId(), dcmd, dl);
      } catch (AgentUnavailableException e) {
        s_logger.warn(
            "Unable to start /resume download of template "
                + template.getUniqueName()
                + " to "
                + sserver.getName(),
            e);
        dl.setDisconnected();
        dl.scheduleStatusCheck(RequestType.GET_OR_RESTART);
      }
    }
  }
  @Override
  public boolean copyTemplate(VMTemplateVO template, HostVO sourceServer, HostVO destServer)
      throws StorageUnavailableException {

    boolean downloadJobExists = false;
    VMTemplateHostVO destTmpltHost = null;
    VMTemplateHostVO srcTmpltHost = null;

    srcTmpltHost = _vmTemplateHostDao.findByHostTemplate(sourceServer.getId(), template.getId());
    if (srcTmpltHost == null) {
      throw new InvalidParameterValueException(
          "Template " + template.getName() + " not associated with " + sourceServer.getName());
    }

    String url = generateCopyUrl(sourceServer, srcTmpltHost);
    if (url == null) {
      s_logger.warn(
          "Unable to start/resume copy of template "
              + template.getUniqueName()
              + " to "
              + destServer.getName()
              + ", no secondary storage vm in running state in source zone");
      throw new CloudRuntimeException(
          "No secondary VM in running state in zone " + sourceServer.getDataCenterId());
    }
    destTmpltHost = _vmTemplateHostDao.findByHostTemplate(destServer.getId(), template.getId());
    if (destTmpltHost == null) {
      destTmpltHost =
          new VMTemplateHostVO(
              destServer.getId(),
              template.getId(),
              new Date(),
              0,
              VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED,
              null,
              null,
              "jobid0000",
              null,
              url);
      destTmpltHost.setCopy(true);
      destTmpltHost.setPhysicalSize(srcTmpltHost.getPhysicalSize());
      _vmTemplateHostDao.persist(destTmpltHost);
    } else if ((destTmpltHost.getJobId() != null) && (destTmpltHost.getJobId().length() > 2)) {
      downloadJobExists = true;
    }

    Long maxTemplateSizeInBytes = getMaxTemplateSizeInBytes();
    if (srcTmpltHost.getSize() > maxTemplateSizeInBytes) {
      throw new CloudRuntimeException(
          "Cant copy the template as the template's size "
              + srcTmpltHost.getSize()
              + " is greater than max.template.iso.size "
              + maxTemplateSizeInBytes);
    }

    if (destTmpltHost != null) {
      start();
      String sourceChecksum =
          this.templateMgr.getChecksum(srcTmpltHost.getHostId(), srcTmpltHost.getInstallPath());
      DownloadCommand dcmd =
          new DownloadCommand(
              destServer.getStorageUrl(),
              url,
              template,
              TemplateConstants.DEFAULT_HTTP_AUTH_USER,
              _copyAuthPasswd,
              maxTemplateSizeInBytes);
      if (downloadJobExists) {
        dcmd =
            new DownloadProgressCommand(dcmd, destTmpltHost.getJobId(), RequestType.GET_OR_RESTART);
      }
      dcmd.setProxy(getHttpProxy());
      dcmd.setChecksum(
          sourceChecksum); // We need to set the checksum as the source template might be a
                           // compressed url and have cksum for compressed image. Bug #10775
      HostVO ssAhost = _ssvmMgr.pickSsvmHost(destServer);
      if (ssAhost == null) {
        s_logger.warn(
            "There is no secondary storage VM for secondary storage host " + destServer.getName());
        return false;
      }
      DownloadListener dl =
          new DownloadListener(
              ssAhost,
              destServer,
              template,
              _timer,
              _vmTemplateHostDao,
              destTmpltHost.getId(),
              this,
              dcmd,
              _templateDao,
              _resourceLimitMgr,
              _alertMgr,
              _accountMgr);
      if (downloadJobExists) {
        dl.setCurrState(destTmpltHost.getDownloadState());
      }
      DownloadListener old = null;
      synchronized (_listenerMap) {
        old = _listenerMap.put(destTmpltHost, dl);
      }
      if (old != null) {
        old.abandon();
      }

      try {
        send(ssAhost.getId(), dcmd, dl);
        return true;
      } catch (AgentUnavailableException e) {
        s_logger.warn(
            "Unable to start /resume COPY of template "
                + template.getUniqueName()
                + " to "
                + destServer.getName(),
            e);
        dl.setDisconnected();
        dl.scheduleStatusCheck(RequestType.GET_OR_RESTART);
        e.printStackTrace();
      }
    }

    return false;
  }