http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b7db056/server/src/com/cloud/storage/upload/UploadListener.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/storage/upload/UploadListener.java
index 038cc38,d3b7af9..5d7a4ba
--- a/server/src/com/cloud/storage/upload/UploadListener.java
+++ b/server/src/com/cloud/storage/upload/UploadListener.java
@@@ -24,15 -23,18 +23,21 @@@ import java.util.Map
  import java.util.Timer;
  import java.util.TimerTask;
  
+ import javax.inject.Inject;
+ 
 +import org.apache.log4j.Level;
 +import org.apache.log4j.Logger;
 +
  import org.apache.cloudstack.api.command.user.iso.ExtractIsoCmd;
  import org.apache.cloudstack.api.command.user.template.ExtractTemplateCmd;
  import org.apache.cloudstack.api.command.user.volume.ExtractVolumeCmd;
  import org.apache.cloudstack.api.response.ExtractResponse;
+ import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+ import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
+ import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
+ import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
 -import org.apache.log4j.Level;
 -import org.apache.log4j.Logger;
 +import org.apache.cloudstack.framework.jobs.AsyncJobManager;
 +import org.apache.cloudstack.jobs.JobInfo;
  
  import com.cloud.agent.Listener;
  import com.cloud.agent.api.AgentControlAnswer;
@@@ -46,9 -48,9 +51,8 @@@ import com.cloud.agent.api.storage.Uplo
  import com.cloud.agent.api.storage.UploadProgressCommand;
  import com.cloud.agent.api.storage.UploadProgressCommand.RequestType;
  import com.cloud.api.ApiDBUtils;
 -import com.cloud.async.AsyncJobManager;
 -import com.cloud.async.AsyncJobResult;
 +import com.cloud.api.ApiSerializerHelper;
- import com.cloud.exception.AgentUnavailableException;
- import com.cloud.host.HostVO;
+ import com.cloud.host.Host;
  import com.cloud.storage.Storage;
  import com.cloud.storage.Upload.Status;
  import com.cloud.storage.Upload.Type;
@@@ -59,401 -61,420 +63,420 @@@ import com.cloud.utils.exception.CloudR
  
  public class UploadListener implements Listener {
  
- 
 -    private static final class StatusTask extends TimerTask {
 -        private final UploadListener ul;
 -        private final RequestType reqType;
 +      private static final class StatusTask extends TimerTask {
 +              private final UploadListener ul;
 +              private final RequestType reqType;
  
-               public StatusTask( UploadListener ul,  RequestType req) {
-                       reqType = req;
+         public StatusTask(UploadListener ul, RequestType req) {
 -            this.reqType = req;
 -            this.ul = ul;
 -        }
++            reqType = req;
 +                      this.ul = ul;
 +              }
  
 -        @Override
 -        public void run() {
 -            ul.sendCommand(reqType);
 +              @Override
 +              public void run() {
 +                ul.sendCommand(reqType);
  
 -        }
 -    }
 +              }
 +      }
  
 -    private static final class TimeoutTask extends TimerTask {
 -        private final UploadListener ul;
 +      private static final class TimeoutTask extends TimerTask {
 +              private final UploadListener ul;
  
-               public TimeoutTask( UploadListener ul) {
+         public TimeoutTask(UploadListener ul) {
 -            this.ul = ul;
 -        }
 +                      this.ul = ul;
 +              }
  
 -        @Override
 -        public void run() {
 -            ul.checkProgress();
 -        }
 -    }
 +              @Override
 +              public void run() {
 +                ul.checkProgress();
 +              }
 +      }
  
 -    public static final Logger s_logger = 
Logger.getLogger(UploadListener.class.getName());
 -    public static final int SMALL_DELAY = 100;
 -    public static final long STATUS_POLL_INTERVAL = 10000L;
 +      public static final Logger s_logger = 
Logger.getLogger(UploadListener.class.getName());
 +      public static final int SMALL_DELAY = 100;
 +      public static final long STATUS_POLL_INTERVAL = 10000L;
  
-       public static final String UPLOADED=Status.UPLOADED.toString();
-       public static final String NOT_UPLOADED=Status.NOT_UPLOADED.toString();
-       public static final String UPLOAD_ERROR=Status.UPLOAD_ERROR.toString();
-       public static final String 
UPLOAD_IN_PROGRESS=Status.UPLOAD_IN_PROGRESS.toString();
-       public static final String UPLOAD_ABANDONED=Status.ABANDONED.toString();
-       public static final Map<String,String> responseNameMap;
-       static{
-           Map<String, String>tempMap = new HashMap<String, String>();
+     public static final String UPLOADED = Status.UPLOADED.toString();
+     public static final String NOT_UPLOADED = Status.NOT_UPLOADED.toString();
+     public static final String UPLOAD_ERROR = Status.UPLOAD_ERROR.toString();
+     public static final String UPLOAD_IN_PROGRESS = 
Status.UPLOAD_IN_PROGRESS.toString();
+     public static final String UPLOAD_ABANDONED = Status.ABANDONED.toString();
+     public static final Map<String, String> responseNameMap;
+     static {
+         Map<String, String> tempMap = new HashMap<String, String>();
          tempMap.put(Type.ISO.toString(), ExtractIsoCmd.getStaticName());
          tempMap.put(Type.TEMPLATE.toString(), 
ExtractTemplateCmd.getStaticName());
          tempMap.put(Type.VOLUME.toString(), ExtractVolumeCmd.getStaticName());
-         tempMap.put("DEFAULT","extractresponse");
+         tempMap.put("DEFAULT", "extractresponse");
          responseNameMap = Collections.unmodifiableMap(tempMap);
 -    }
 +      }
  
- 
-       private HostVO sserver;
+     private DataStore sserver;
  
 -    private boolean uploadActive = true;
 +      private boolean uploadActive = true;
  
 -    private UploadDao uploadDao;
 +      private UploadDao uploadDao;
  
 -    private final UploadMonitorImpl uploadMonitor;
 +      private final UploadMonitorImpl uploadMonitor;
  
 -    private UploadState currState;
 +      private UploadState currState;
  
 -    private UploadCommand cmd;
 +      private UploadCommand cmd;
  
 -    private Timer timer;
 +      private Timer timer;
  
 -    private StatusTask statusTask;
 -    private TimeoutTask timeoutTask;
 -    private Date lastUpdated = new Date();
 -    private String jobId;
 -    private Long accountId;
 -    private String typeName;
 -    private Type type;
 -    private long asyncJobId;
 -    private long eventId;
 -    private AsyncJobManager asyncMgr;
 -    private ExtractResponse resultObj;
 +      private StatusTask statusTask;
 +      private TimeoutTask timeoutTask;
 +      private Date lastUpdated = new Date();
 +      private String jobId;
 +      private Long accountId;
 +      private String typeName;
 +      private Type type;
 +      private long asyncJobId;
 +      private long eventId;
 +      private AsyncJobManager asyncMgr;
 +      private ExtractResponse resultObj;
+     @Inject
+     EndPointSelector _epSelector;
  
 -    public AsyncJobManager getAsyncMgr() {
 -        return asyncMgr;
 -    }
 +      public AsyncJobManager getAsyncMgr() {
 +              return asyncMgr;
 +      }
  
 -    public void setAsyncMgr(AsyncJobManager asyncMgr) {
 -        this.asyncMgr = asyncMgr;
 -    }
 +      public void setAsyncMgr(AsyncJobManager asyncMgr) {
 +              this.asyncMgr = asyncMgr;
 +      }
  
 -    public long getAsyncJobId() {
 -        return asyncJobId;
 -    }
 +      public long getAsyncJobId() {
 +              return asyncJobId;
 +      }
  
 -    public void setAsyncJobId(long asyncJobId) {
 -        this.asyncJobId = asyncJobId;
 -    }
 +      public void setAsyncJobId(long asyncJobId) {
 +              this.asyncJobId = asyncJobId;
 +      }
  
 -    public long getEventId() {
 -        return eventId;
 -    }
 +      public long getEventId() {
 +              return eventId;
 +      }
  
 -    public void setEventId(long eventId) {
 -        this.eventId = eventId;
 -    }
 +      public void setEventId(long eventId) {
 +              this.eventId = eventId;
 +      }
  
 -    private final Map<String, UploadState> stateMap = new HashMap<String, 
UploadState>();
 -    private Long uploadId;
 +      private final Map<String,  UploadState> stateMap = new HashMap<String, 
UploadState>();
 +      private Long uploadId;
  
-       public UploadListener(HostVO host, Timer _timer, UploadDao uploadDao,
+     public UploadListener(DataStore host, Timer _timer, UploadDao uploadDao,
 -            UploadVO uploadObj, UploadMonitorImpl uploadMonitor, 
UploadCommand cmd,
 -            Long accountId, String typeName, Type type, long eventId, long 
asyncJobId, AsyncJobManager asyncMgr) {
 -        this.sserver = host;
 -        this.uploadDao = uploadDao;
 -        this.uploadMonitor = uploadMonitor;
 -        this.cmd = cmd;
 -        this.uploadId = uploadObj.getId();
 -        this.accountId = accountId;
 -        this.typeName = typeName;
 -        this.type = type;
 -        initStateMachine();
 -        this.currState = getState(Status.NOT_UPLOADED.toString());
 -        this.timer = _timer;
 -        this.timeoutTask = new TimeoutTask(this);
 -        this.timer.schedule(timeoutTask, 3 * STATUS_POLL_INTERVAL);
 -        this.eventId = eventId;
 -        this.asyncJobId = asyncJobId;
 -        this.asyncMgr = asyncMgr;
 -        String extractId = null;
 +                      UploadVO uploadObj, UploadMonitorImpl uploadMonitor, 
UploadCommand cmd,
 +                      Long accountId, String typeName, Type type, long 
eventId, long asyncJobId, AsyncJobManager asyncMgr) {
 +              sserver = host;
 +              this.uploadDao = uploadDao;
 +              this.uploadMonitor = uploadMonitor;
 +              this.cmd = cmd;
 +              uploadId = uploadObj.getId();
 +              this.accountId = accountId;
 +              this.typeName = typeName;
 +              this.type = type;
 +              initStateMachine();
-               currState = getState(Status.NOT_UPLOADED.toString());
-               timer = _timer;
-               timeoutTask = new TimeoutTask(this);
-               timer.schedule(timeoutTask, 3*STATUS_POLL_INTERVAL);
++        currState = getState(Status.NOT_UPLOADED.toString());
++        timer = _timer;
++        timeoutTask = new TimeoutTask(this);
++        timer.schedule(timeoutTask, 3 * STATUS_POLL_INTERVAL);
 +              this.eventId = eventId;
 +              this.asyncJobId = asyncJobId;
 +              this.asyncMgr = asyncMgr;
 +              String extractId = null;
-               if ( type == Type.VOLUME ){
+         if (type == Type.VOLUME) {
 -            extractId = 
ApiDBUtils.findVolumeById(uploadObj.getTypeId()).getUuid();
 -        }
 +                  extractId = 
ApiDBUtils.findVolumeById(uploadObj.getTypeId()).getUuid();
 +              }
-               else{
+         else {
 -            extractId = 
ApiDBUtils.findTemplateById(uploadObj.getTypeId()).getUuid();
 -        }
 -        this.resultObj = new ExtractResponse(extractId, typeName, 
ApiDBUtils.findAccountById(accountId).getUuid(), Status.NOT_UPLOADED.toString(),
 -                ApiDBUtils.findUploadById(uploadId).getUuid());
 -        resultObj.setResponseName(responseNameMap.get(type.toString()));
 +                  extractId = 
ApiDBUtils.findTemplateById(uploadObj.getTypeId()).getUuid();
 +              }
 +              resultObj = new ExtractResponse(extractId, typeName, 
ApiDBUtils.findAccountById(accountId).getUuid(), Status.NOT_UPLOADED.toString(),
 +                      ApiDBUtils.findUploadById(uploadId).getUuid());
 +              resultObj.setResponseName(responseNameMap.get(type.toString()));
-               updateDatabase(Status.NOT_UPLOADED, cmd.getUrl(),"");
+         updateDatabase(Status.NOT_UPLOADED, cmd.getUrl(), "");
 -    }
 +      }
  
 -    public UploadListener(UploadMonitorImpl monitor) {
 -        uploadMonitor = monitor;
 -    }
 +      public UploadListener(UploadMonitorImpl monitor) {
 +          uploadMonitor = monitor;
 +      }
  
 -    public void checkProgress() {
 -        transition(UploadEvent.TIMEOUT_CHECK, null);
 -    }
 +      public void checkProgress() {
 +              transition(UploadEvent.TIMEOUT_CHECK, null);
 +      }
  
 -    @Override
 -    public int getTimeout() {
 -        return -1;
 -    }
 +      @Override
 +      public int getTimeout() {
 +              return -1;
 +      }
  
 -    @Override
 -    public boolean isRecurring() {
 -        return false;
 -    }
 +      @Override
 +      public boolean isRecurring() {
 +              return false;
 +      }
  
 -    public void setCommand(UploadCommand _cmd) {
 -        this.cmd = _cmd;
 -    }
 +      public void setCommand(UploadCommand _cmd) {
 +              cmd = _cmd;
 +      }
  
 -    public void setJobId(String _jobId) {
 -        this.jobId = _jobId;
 -    }
 +      public void setJobId(String _jobId) {
 +              jobId = _jobId;
 +      }
  
 -    public String getJobId() {
 -        return jobId;
 -    }
 +      public String getJobId() {
 +              return jobId;
 +      }
  
 -    @Override
 -    public boolean processAnswers(long agentId, long seq, Answer[] answers) {
 -        boolean processed = false;
 +      @Override
 +      public boolean processAnswers(long agentId, long seq, Answer[] answers) 
{
 +              boolean processed = false;
-       if(answers != null & answers.length > 0) {
-               if(answers[0] instanceof UploadAnswer) {
+         if (answers != null & answers.length > 0) {
+             if (answers[0] instanceof UploadAnswer) {
 -                final UploadAnswer answer = (UploadAnswer)answers[0];
 -                if (getJobId() == null) {
 -                    setJobId(answer.getJobId());
 +                      final UploadAnswer answer = (UploadAnswer)answers[0];
 +                      if (getJobId() == null) {
 +                              setJobId(answer.getJobId());
-                       } else if 
(!getJobId().equalsIgnoreCase(answer.getJobId())){
+                 } else if (!getJobId().equalsIgnoreCase(answer.getJobId())) {
 -                    return false;//TODO
 -                }
 -                transition(UploadEvent.UPLOAD_ANSWER, answer);
 -                processed = true;
 -            }
 -        }
 +                              return false;//TODO
 +                      }
 +                      transition(UploadEvent.UPLOAD_ANSWER, answer);
 +                      processed = true;
 +              }
 +      }
          return processed;
 -    }
 +      }
  
- 
 -    @Override
 -    public boolean processCommands(long agentId, long seq, Command[] 
commands) {
 -        return false;
 -    }
 +      @Override
 +      public boolean processCommands(long agentId, long seq, Command[] 
commands) {
 +              return false;
 +      }
  
 -    @Override
 +      @Override
-       public void processConnect(HostVO agent, StartupCommand cmd, boolean 
forRebalance) {
+     public void processConnect(Host agent, StartupCommand cmd, boolean 
forRebalance) {
 -        if (!(cmd instanceof StartupStorageCommand)) {
 -            return;
 -        }
 +              if (!(cmd instanceof StartupStorageCommand)) {
 +              return;
 +          }
  
 -        long agentId = agent.getId();
 +          long agentId = agent.getId();
  
 -        StartupStorageCommand storage = (StartupStorageCommand)cmd;
 -        if (storage.getResourceType() == 
Storage.StorageResourceType.STORAGE_HOST ||
 +          StartupStorageCommand storage = (StartupStorageCommand)cmd;
 +          if (storage.getResourceType() == 
Storage.StorageResourceType.STORAGE_HOST ||
-           storage.getResourceType() == 
Storage.StorageResourceType.SECONDARY_STORAGE )
+                 storage.getResourceType() == 
Storage.StorageResourceType.SECONDARY_STORAGE)
 -        {
 -            uploadMonitor.handleUploadSync(agentId);
 -        }
 -    }
 -
 -    @Override
 -    public AgentControlAnswer processControlCommand(long agentId,
 -            AgentControlCommand cmd) {
 -        return null;
 -    }
 -
 -    public void setUploadInactive(Status reason) {
 +          {
 +              uploadMonitor.handleUploadSync(agentId);
 +          }
 +      }
 +
 +      @Override
 +      public AgentControlAnswer processControlCommand(long agentId,
 +                      AgentControlCommand cmd) {
 +              return null;
 +      }
 +
 +      public void setUploadInactive(Status reason) {
-               uploadActive=false;
-               uploadMonitor.handleUploadEvent(sserver, accountId, typeName, 
type, uploadId, reason, eventId);
+         uploadActive = false;
+         uploadMonitor.handleUploadEvent(accountId, typeName, type, uploadId, 
reason, eventId);
 -    }
 +      }
  
 -    public void logUploadStart() {
 -        //uploadMonitor.logEvent(accountId, event, "Storage server " + 
sserver.getName() + " started upload of " +type.toString() + " " + typeName, 
EventVO.LEVEL_INFO, eventId);
 -    }
 +      public void logUploadStart() {
 +              //uploadMonitor.logEvent(accountId, event, "Storage server " + 
sserver.getName() + " started upload of " +type.toString() + " " + typeName, 
EventVO.LEVEL_INFO, eventId);
 +      }
  
 -    public void cancelTimeoutTask() {
 +      public void cancelTimeoutTask() {
-               if (timeoutTask != null) timeoutTask.cancel();
+         if (timeoutTask != null)
+             timeoutTask.cancel();
 -    }
 +      }
  
 -    public void cancelStatusTask() {
 +      public void cancelStatusTask() {
-               if (statusTask != null) statusTask.cancel();
+         if (statusTask != null)
+             statusTask.cancel();
 -    }
 -
 -    @Override
 -    public boolean processDisconnect(long agentId, com.cloud.host.Status 
state) {
 -        setDisconnected();
 -        return true;
 -    }
 -
 -    @Override
 -    public boolean processTimeout(long agentId, long seq) {
 -        return true;
 -    }
 -
 -    private void initStateMachine() {
 -        stateMap.put(Status.NOT_UPLOADED.toString(), new 
NotUploadedState(this));
 -        stateMap.put(Status.UPLOADED.toString(), new 
UploadCompleteState(this));
 -        stateMap.put(Status.UPLOAD_ERROR.toString(), new 
UploadErrorState(this));
 -        stateMap.put(Status.UPLOAD_IN_PROGRESS.toString(), new 
UploadInProgressState(this));
 -        stateMap.put(Status.ABANDONED.toString(), new 
UploadAbandonedState(this));
 -    }
 -
 -    private UploadState getState(String stateName) {
 -        return stateMap.get(stateName);
 -    }
 -
 -    private synchronized void transition(UploadEvent event, Object evtObj) {
 -        if (currState == null) {
 -            return;
 -        }
 -        String prevName = currState.getName();
 -        String nextState = currState.handleEvent(event, evtObj);
 -        if (nextState != null) {
 -            currState = getState(nextState);
 -            if (currState != null) {
 -                currState.onEntry(prevName, event, evtObj);
 -            } else {
 +      }
 +
 +      @Override
 +      public boolean processDisconnect(long agentId, com.cloud.host.Status 
state) {
 +              setDisconnected();
 +              return true;
 +      }
 +
 +      @Override
 +      public boolean processTimeout(long agentId, long seq) {
 +              return true;
 +      }
 +
 +      private void initStateMachine() {
 +              stateMap.put(Status.NOT_UPLOADED.toString(), new 
NotUploadedState(this));
 +              stateMap.put(Status.UPLOADED.toString(), new 
UploadCompleteState(this));
 +              stateMap.put(Status.UPLOAD_ERROR.toString(), new 
UploadErrorState(this));
 +              stateMap.put(Status.UPLOAD_IN_PROGRESS.toString(), new 
UploadInProgressState(this));
 +              stateMap.put(Status.ABANDONED.toString(), new 
UploadAbandonedState(this));
 +      }
 +
 +      private UploadState getState(String stateName) {
 +              return stateMap.get(stateName);
 +      }
 +
 +      private synchronized void transition(UploadEvent event, Object evtObj) {
 +          if (currState == null) {
 +              return;
 +          }
 +              String prevName = currState.getName();
 +              String nextState = currState.handleEvent(event, evtObj);
 +              if (nextState != null) {
 +                      currState = getState(nextState);
 +                      if (currState != null) {
 +                              currState.onEntry(prevName, event, evtObj);
 +                      } else {
-                               throw new CloudRuntimeException("Invalid next 
state: currState="+prevName+", evt="+event + ", next=" + nextState);
+                 throw new CloudRuntimeException("Invalid next state: 
currState=" + prevName + ", evt=" + event + ", next=" + nextState);
 -            }
 -        } else {
 +                      }
 +              } else {
-                       throw new CloudRuntimeException("Unhandled event 
transition: currState="+prevName+", evt="+event);
+             throw new CloudRuntimeException("Unhandled event transition: 
currState=" + prevName + ", evt=" + event);
 -        }
 -    }
 +              }
 +      }
  
 -    public Date getLastUpdated() {
 -        return lastUpdated;
 -    }
 +      public Date getLastUpdated() {
 +              return lastUpdated;
 +      }
  
 -    public void setLastUpdated() {
 -        lastUpdated = new Date();
 -    }
 +      public void setLastUpdated() {
 +              lastUpdated  = new Date();
 +      }
  
 -    public void log(String message, Level level) {
 -        s_logger.log(level, message + ", " + type.toString() + " = " + 
typeName + " at host " + sserver.getName());
 -    }
 +      public void log(String message, Level level) {
 +              s_logger.log(level, message + ", " + type.toString() + " = " + 
typeName + " at host " + sserver.getName());
 +      }
  
 -    public void setDisconnected() {
 -        transition(UploadEvent.DISCONNECT, null);
 -    }
 +      public void setDisconnected() {
 +              transition(UploadEvent.DISCONNECT, null);
 +      }
  
 -    public void 
scheduleStatusCheck(com.cloud.agent.api.storage.UploadProgressCommand.RequestType
 getStatus) {
 +      public void 
scheduleStatusCheck(com.cloud.agent.api.storage.UploadProgressCommand.RequestType
 getStatus) {
-               if (statusTask != null) statusTask.cancel();
+         if (statusTask != null)
+             statusTask.cancel();
  
 -        statusTask = new StatusTask(this, getStatus);
 -        timer.schedule(statusTask, STATUS_POLL_INTERVAL);
 -    }
 +              statusTask = new StatusTask(this, getStatus);
 +              timer.schedule(statusTask, STATUS_POLL_INTERVAL);
 +      }
  
 -    public void scheduleTimeoutTask(long delay) {
 +      public void scheduleTimeoutTask(long delay) {
-               if (timeoutTask != null) timeoutTask.cancel();
+         if (timeoutTask != null)
+             timeoutTask.cancel();
  
 -        timeoutTask = new TimeoutTask(this);
 -        timer.schedule(timeoutTask, delay);
 -        if (s_logger.isDebugEnabled()) {
 -            log("Scheduling timeout at " + delay + " ms", Level.DEBUG);
 -        }
 -    }
 -
 -    public void updateDatabase(Status state, String uploadErrorString) {
 -        resultObj.setResultString(uploadErrorString);
 -        resultObj.setState(state.toString());
 -        asyncMgr.updateAsyncJobAttachment(asyncJobId, type.toString(), 1L);
 -        asyncMgr.updateAsyncJobStatus(asyncJobId, 
AsyncJobResult.STATUS_IN_PROGRESS, resultObj);
 -
 -        UploadVO vo = uploadDao.createForUpdate();
 -        vo.setUploadState(state);
 -        vo.setLastUpdated(new Date());
 -        vo.setErrorString(uploadErrorString);
 -        uploadDao.update(getUploadId(), vo);
 -    }
 +              timeoutTask = new TimeoutTask(this);
 +              timer.schedule(timeoutTask, delay);
 +              if (s_logger.isDebugEnabled()) {
 +                      log("Scheduling timeout at " + delay + " ms", 
Level.DEBUG);
 +              }
 +      }
 +
 +      public void updateDatabase(Status state, String uploadErrorString) {
 +              resultObj.setResultString(uploadErrorString);
 +              resultObj.setState(state.toString());
 +              asyncMgr.updateAsyncJobAttachment(asyncJobId, type.toString(), 
1L);
 +        asyncMgr.updateAsyncJobStatus(asyncJobId, 
JobInfo.Status.IN_PROGRESS.ordinal(), 
ApiSerializerHelper.toSerializedString(resultObj));
 +
 +              UploadVO vo = uploadDao.createForUpdate();
 +              vo.setUploadState(state);
 +              vo.setLastUpdated(new Date());
 +              vo.setErrorString(uploadErrorString);
 +              uploadDao.update(getUploadId(), vo);
 +      }
  
-       public void updateDatabase(Status state, String uploadUrl,String 
uploadErrorString) {
+     public void updateDatabase(Status state, String uploadUrl, String 
uploadErrorString) {
 -        resultObj.setResultString(uploadErrorString);
 -        resultObj.setState(state.toString());
 -        asyncMgr.updateAsyncJobAttachment(asyncJobId, type.toString(), 1L);
 -        asyncMgr.updateAsyncJobStatus(asyncJobId, 
AsyncJobResult.STATUS_IN_PROGRESS, resultObj);
 -
 -        UploadVO vo = uploadDao.createForUpdate();
 -        vo.setUploadState(state);
 -        vo.setLastUpdated(new Date());
 -        vo.setUploadUrl(uploadUrl);
 -        vo.setJobId(null);
 -        vo.setUploadPercent(0);
 -        vo.setErrorString(uploadErrorString);
 -
 -        uploadDao.update(getUploadId(), vo);
 -    }
 +              resultObj.setResultString(uploadErrorString);
 +              resultObj.setState(state.toString());
 +              asyncMgr.updateAsyncJobAttachment(asyncJobId, type.toString(), 
1L);
 +        asyncMgr.updateAsyncJobStatus(asyncJobId, 
JobInfo.Status.IN_PROGRESS.ordinal(), 
ApiSerializerHelper.toSerializedString(resultObj));
  
- 
 -    private Long getUploadId() {
 -        return uploadId;
 -    }
 +              UploadVO vo = uploadDao.createForUpdate();
 +              vo.setUploadState(state);
 +              vo.setLastUpdated(new Date());
 +              vo.setUploadUrl(uploadUrl);
 +              vo.setJobId(null);
 +              vo.setUploadPercent(0);
 +              vo.setErrorString(uploadErrorString);
 +
 +              uploadDao.update(getUploadId(), vo);
 +      }
 +
 +      private Long getUploadId() {
 +              return uploadId;
 +      }
  
 -    public synchronized void updateDatabase(UploadAnswer answer) {
 +      public synchronized void updateDatabase(UploadAnswer answer) {
  
-           if(answer.getErrorString().startsWith("553")){
+         if (answer.getErrorString().startsWith("553")) {
 -            answer.setErrorString(answer.getErrorString().concat("Please 
check if the file name already exists."));
 -        }
 -        resultObj.setResultString(answer.getErrorString());
 -        resultObj.setState(answer.getUploadStatus().toString());
 -        resultObj.setUploadPercent(answer.getUploadPct());
 +              answer.setErrorString(answer.getErrorString().concat("Please 
check if the file name already exists."));
 +          }
 +              resultObj.setResultString(answer.getErrorString());
 +              resultObj.setState(answer.getUploadStatus().toString());
 +              resultObj.setUploadPercent(answer.getUploadPct());
  
-               if (answer.getUploadStatus() == Status.UPLOAD_IN_PROGRESS){
+         if (answer.getUploadStatus() == Status.UPLOAD_IN_PROGRESS) {
 -            asyncMgr.updateAsyncJobAttachment(asyncJobId, type.toString(), 
1L);
 -            asyncMgr.updateAsyncJobStatus(asyncJobId, 
AsyncJobResult.STATUS_IN_PROGRESS, resultObj);
 +                      asyncMgr.updateAsyncJobAttachment(asyncJobId, 
type.toString(), 1L);
 +            asyncMgr.updateAsyncJobStatus(asyncJobId, 
JobInfo.Status.IN_PROGRESS.ordinal(), 
ApiSerializerHelper.toSerializedString(resultObj));
-               }else if(answer.getUploadStatus() == Status.UPLOADED){
-                   resultObj.setResultString("Success");
+         } else if (answer.getUploadStatus() == Status.UPLOADED) {
+             resultObj.setResultString("Success");
 -            asyncMgr.completeAsyncJob(asyncJobId, 
AsyncJobResult.STATUS_SUCCEEDED, 1, resultObj);
 +            asyncMgr.completeAsyncJob(asyncJobId, JobInfo.Status.SUCCEEDED, 
1, ApiSerializerHelper.toSerializedString(resultObj));
-               }else{
+         } else {
 -            asyncMgr.completeAsyncJob(asyncJobId, 
AsyncJobResult.STATUS_FAILED, 2, resultObj);
 -        }
 +            asyncMgr.completeAsyncJob(asyncJobId, JobInfo.Status.FAILED, 2, 
ApiSerializerHelper.toSerializedString(resultObj));
 +              }
          UploadVO updateBuilder = uploadDao.createForUpdate();
 -        updateBuilder.setUploadPercent(answer.getUploadPct());
 -        updateBuilder.setUploadState(answer.getUploadStatus());
 -        updateBuilder.setLastUpdated(new Date());
 -        updateBuilder.setErrorString(answer.getErrorString());
 -        updateBuilder.setJobId(answer.getJobId());
 -
 -        uploadDao.update(getUploadId(), updateBuilder);
 -    }
 -
 -    public void sendCommand(RequestType reqType) {
 -        if (getJobId() != null) {
 -            if (s_logger.isTraceEnabled()) {
 -                log("Sending progress command ", Level.TRACE);
 -            }
 -            try {
 +              updateBuilder.setUploadPercent(answer.getUploadPct());
 +              updateBuilder.setUploadState(answer.getUploadStatus());
 +              updateBuilder.setLastUpdated(new Date());
 +              updateBuilder.setErrorString(answer.getErrorString());
 +              updateBuilder.setJobId(answer.getJobId());
 +
 +              uploadDao.update(getUploadId(), updateBuilder);
 +      }
 +
 +      public void sendCommand(RequestType reqType) {
 +              if (getJobId() != null) {
 +                      if (s_logger.isTraceEnabled()) {
 +                              log("Sending progress command ", Level.TRACE);
 +                      }
 +                      try {
-                   uploadMonitor.send(sserver.getId(), new 
UploadProgressCommand(getCommand(), getJobId(), reqType), this);
-             } catch (AgentUnavailableException e) {
+                 EndPoint ep = _epSelector.select(sserver);
+                 ep.sendMessageAsync(new UploadProgressCommand(getCommand(), 
getJobId(), reqType), new Callback(ep.getId(), this));
+             } catch (Exception e) {
 -                s_logger.debug("Send command failed", e);
 -                setDisconnected();
 +              s_logger.debug("Send command failed", e);
 +                              setDisconnected();
              }
 -        }
 +              }
  
 -    }
 +      }
  
 -    private UploadCommand getCommand() {
 -        return cmd;
 -    }
 +      private UploadCommand getCommand() {
 +              return cmd;
 +      }
  
 -    public void logDisconnect() {
 -        s_logger.warn("Unable to monitor upload progress of " + typeName + " 
at host " + sserver.getName());
 -    }
 +      public void logDisconnect() {
 +              s_logger.warn("Unable to monitor upload progress of " + 
typeName + " at host " + sserver.getName());
 +      }
  
 -    public void scheduleImmediateStatusCheck(RequestType request) {
 +      public void scheduleImmediateStatusCheck(RequestType request) {
-               if (statusTask != null) statusTask.cancel();
+         if (statusTask != null)
+             statusTask.cancel();
 -        statusTask = new StatusTask(this, request);
 -        timer.schedule(statusTask, SMALL_DELAY);
 -    }
 +              statusTask = new StatusTask(this, request);
 +              timer.schedule(statusTask, SMALL_DELAY);
 +      }
  
 -    public void setCurrState(Status uploadState) {
 -        this.currState = getState(currState.toString());
 -    }
 +      public void setCurrState(Status uploadState) {
 +              currState = getState(currState.toString());
 +      }
+ 
+     public static class Callback implements AsyncCompletionCallback<Answer> {
+         long id;
+         Listener listener;
+ 
+         public Callback(long id, Listener listener) {
+             this.id = id;
+             this.listener = listener;
+         }
+ 
+         @Override
+         public void complete(Answer answer) {
+             listener.processAnswers(id, -1, new Answer[] {answer});
+         }
+     }
  }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b7db056/server/src/com/cloud/storage/upload/UploadMonitor.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/storage/upload/UploadMonitor.java
index d4f5762,b4ba531..c660299
--- a/server/src/com/cloud/storage/upload/UploadMonitor.java
+++ b/server/src/com/cloud/storage/upload/UploadMonitor.java
@@@ -17,14 -17,17 +17,15 @@@
  package com.cloud.storage.upload;
  
  
+ import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
 +import org.apache.cloudstack.framework.jobs.AsyncJobManager;
+ import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
  
- import com.cloud.host.HostVO;
 -import com.cloud.async.AsyncJobManager;
 -import com.cloud.host.HostVO;
+ import com.cloud.storage.Storage.ImageFormat;
  import com.cloud.storage.Upload.Mode;
  import com.cloud.storage.Upload.Status;
  import com.cloud.storage.Upload.Type;
  import com.cloud.storage.UploadVO;
--import com.cloud.storage.VMTemplateHostVO;
  import com.cloud.storage.VMTemplateVO;
  import com.cloud.storage.VolumeVO;
  import com.cloud.utils.component.Manager;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b7db056/server/src/com/cloud/storage/upload/UploadMonitorImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/storage/upload/UploadMonitorImpl.java
index 01eabad,d46db0c..f7cf88d
--- a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java
+++ b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java
@@@ -35,19 -42,15 +42,16 @@@ import org.apache.cloudstack.storage.im
  import org.apache.log4j.Logger;
  import org.springframework.stereotype.Component;
  
 +import org.apache.cloudstack.framework.jobs.AsyncJobManager;
 +
  import com.cloud.agent.AgentManager;
- import com.cloud.agent.Listener;
- import com.cloud.agent.api.Command;
+ import com.cloud.agent.api.Answer;
  import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
  import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand;
  import com.cloud.agent.api.storage.UploadCommand;
  import com.cloud.agent.api.storage.UploadProgressCommand.RequestType;
- import com.cloud.agent.manager.Commands;
  import com.cloud.api.ApiDBUtils;
 -import com.cloud.async.AsyncJobManager;
  import com.cloud.configuration.dao.ConfigurationDao;
- import com.cloud.exception.AgentUnavailableException;
  import com.cloud.host.Host;
  import com.cloud.host.HostVO;
  import com.cloud.host.dao.HostDao;
@@@ -83,10 -85,8 +86,8 @@@ import com.cloud.vm.dao.SecondaryStorag
  public class UploadMonitorImpl extends ManagerBase implements UploadMonitor {
  
        static final Logger s_logger = 
Logger.getLogger(UploadMonitorImpl.class);
 -
 -    @Inject
 +      
 +    @Inject 
-     VMTemplateHostDao _vmTemplateHostDao;
-     @Inject 
      UploadDao _uploadDao;
      @Inject
      SecondaryStorageVmDao _secStorageVmDao;
@@@ -140,91 -144,89 +145,89 @@@
        @Override
        public UploadVO createNewUploadEntry(Long hostId, Long typeId, 
UploadVO.Status  uploadState,
                                                Type  type, String uploadUrl, 
Upload.Mode mode){
 -
 -        UploadVO uploadObj = new UploadVO(hostId, typeId, new Date(),
 +             
 +        UploadVO uploadObj = new UploadVO(hostId, typeId, new Date(), 
                                            uploadState, type, uploadUrl, mode);
          _uploadDao.persist(uploadObj);
 -
 +        
          return uploadObj;
 -
 +          
        }
 -
 +      
        @Override
-       public void extractVolume(UploadVO uploadVolumeObj, HostVO sserver, 
VolumeVO volume, String url, Long dataCenterId, String installPath, long 
eventId, long asyncJobId, AsyncJobManager asyncMgr){                            
   
+       public void extractVolume(UploadVO uploadVolumeObj, DataStore secStore, 
VolumeVO volume, String url, Long dataCenterId, String installPath, long 
eventId, long asyncJobId, AsyncJobManager asyncMgr){
 -
 +                                              
                uploadVolumeObj.setUploadState(Upload.Status.NOT_UPLOADED);
                _uploadDao.update(uploadVolumeObj.getId(), uploadVolumeObj);
 -
 -          start();
 +                              
 +          start();            
                UploadCommand ucmd = new UploadCommand(url, volume.getId(), 
volume.getSize(), installPath, Type.VOLUME);
-               UploadListener ul = new UploadListener(sserver, _timer, 
_uploadDao, uploadVolumeObj, this, ucmd, volume.getAccountId(), 
volume.getName(), Type.VOLUME, eventId, asyncJobId, asyncMgr);
+               UploadListener ul = new UploadListener(secStore, _timer, 
_uploadDao, uploadVolumeObj, this, ucmd, volume.getAccountId(), 
volume.getName(), Type.VOLUME, eventId, asyncJobId, asyncMgr);
                _listenerMap.put(uploadVolumeObj, ul);
  
                try {
-               send(sserver.getId(), ucmd, ul);
-         } catch (AgentUnavailableException e) {
-                       s_logger.warn("Unable to start upload of volume " + 
volume.getName() + " from " + sserver.getName() + " to " +url, e);
+                   EndPoint ep = _epSelector.select(secStore);
+             ep.sendMessageAsync(ucmd, new UploadListener.Callback(ep.getId(), 
ul));
+         } catch (Exception e) {
+                       s_logger.warn("Unable to start upload of volume " + 
volume.getName() + " from " + secStore.getName() + " to " +url, e);
                        ul.setDisconnected();
                        ul.scheduleStatusCheck(RequestType.GET_OR_RESTART);
 -        }
 +        }             
        }
  
        @Override
        public Long extractTemplate( VMTemplateVO template, String url,
-                       VMTemplateHostVO vmTemplateHost,Long dataCenterId, long 
eventId, long asyncJobId, AsyncJobManager asyncMgr){
+                       TemplateDataStoreVO vmTemplateHost,Long dataCenterId, 
long eventId, long asyncJobId, AsyncJobManager asyncMgr){
  
                Type type = (template.getFormat() == ImageFormat.ISO) ? 
Type.ISO : Type.TEMPLATE ;
 -
 +                              
-               List<HostVO> storageServers = 
_resourceMgr.listAllHostsInOneZoneByType(Host.Type.SecondaryStorage, 
dataCenterId);
-               HostVO sserver = storageServers.get(0);                 
+               DataStore secStore = this.storeMgr.getImageStore(dataCenterId);
 -
 +              
-               UploadVO uploadTemplateObj = new UploadVO(sserver.getId(), 
template.getId(), new Date(), 
+               UploadVO uploadTemplateObj = new UploadVO(secStore.getId(), 
template.getId(), new Date(),
                                                                                
                        Upload.Status.NOT_UPLOADED, type, url, Mode.FTP_UPLOAD);
 -              _uploadDao.persist(uploadTemplateObj);
 -
 +              _uploadDao.persist(uploadTemplateObj);                          
       
 +                      
                if(vmTemplateHost != null) {
                    start();
 -                      UploadCommand ucmd = new UploadCommand(template, url, 
vmTemplateHost.getInstallPath(), vmTemplateHost.getSize());
 +                      UploadCommand ucmd = new UploadCommand(template, url, 
vmTemplateHost.getInstallPath(), vmTemplateHost.getSize());       
-                       UploadListener ul = new UploadListener(sserver, _timer, 
_uploadDao, uploadTemplateObj, this, ucmd, template.getAccountId(), 
template.getName(), type, eventId, asyncJobId, asyncMgr);                   
+                       UploadListener ul = new UploadListener(secStore, 
_timer, _uploadDao, uploadTemplateObj, this, ucmd, template.getAccountId(), 
template.getName(), type, eventId, asyncJobId, asyncMgr);
                        _listenerMap.put(uploadTemplateObj, ul);
- 
-                       try {
-                   send(sserver.getId(), ucmd, ul);
-             } catch (AgentUnavailableException e) {
-                               s_logger.warn("Unable to start upload of " + 
template.getUniqueName() + " from " + sserver.getName() + " to " +url, e);
+                       try{
+                           EndPoint ep = _epSelector.select(secStore);
+                 ep.sendMessageAsync(ucmd, new 
UploadListener.Callback(ep.getId(), ul));
+             } catch (Exception e) {
+                               s_logger.warn("Unable to start upload of " + 
template.getUniqueName() + " from " + secStore.getName() + " to " +url, e);
                                ul.setDisconnected();
                                
ul.scheduleStatusCheck(RequestType.GET_OR_RESTART);
              }
                        return uploadTemplateObj.getId();
 -              }
 -              return null;
 -      }
 -
 +              }               
 +              return null;            
 +      }       
 +      
        @Override
-       public UploadVO createEntityDownloadURL(VMTemplateVO template, 
VMTemplateHostVO vmTemplateHost, Long dataCenterId, long eventId) {
+       public UploadVO createEntityDownloadURL(VMTemplateVO template, 
TemplateDataStoreVO vmTemplateHost, Long dataCenterId, long eventId) {
 -
 +          
            String errorString = "";
            boolean success = false;
-           Host secStorage = 
ApiDBUtils.findHostById(vmTemplateHost.getHostId());          
            Type type = (template.getFormat() == ImageFormat.ISO) ? Type.ISO : 
Type.TEMPLATE ;
 -
 -
 +          
-         //Check if ssvm is up
-         HostVO ssvm = 
_ssvmMgr.pickSsvmHost(ApiDBUtils.findHostById(vmTemplateHost.getHostId()));
-         if( ssvm == null ) {
-             throw new CloudRuntimeException("There is no secondary storage VM 
for secondary storage host " + secStorage.getId());
-         }
 +          
            //Check if it already exists.
 -          List<UploadVO> extractURLList = 
_uploadDao.listByTypeUploadStatus(template.getId(), type, 
UploadVO.Status.DOWNLOAD_URL_CREATED);
 +          List<UploadVO> extractURLList = 
_uploadDao.listByTypeUploadStatus(template.getId(), type, 
UploadVO.Status.DOWNLOAD_URL_CREATED);        
            if (extractURLList.size() > 0) {
              return extractURLList.get(0);
          }
 -
 -          // It doesn't exist so create a DB entry.
 +          
 +          // It doesn't exist so create a DB entry.       
-           UploadVO uploadTemplateObj = new 
UploadVO(vmTemplateHost.getHostId(), template.getId(), new Date(), 
+           UploadVO uploadTemplateObj = new 
UploadVO(vmTemplateHost.getDataStoreId(), template.getId(), new Date(),
 -                                                      
Status.DOWNLOAD_URL_NOT_CREATED, 0, type, Mode.HTTP_DOWNLOAD);
 -          uploadTemplateObj.setInstallPath(vmTemplateHost.getInstallPath());
 +                                                      
Status.DOWNLOAD_URL_NOT_CREATED, 0, type, Mode.HTTP_DOWNLOAD); 
 +          uploadTemplateObj.setInstallPath(vmTemplateHost.getInstallPath());  
                                                
            _uploadDao.persist(uploadTemplateObj);
+ 
+           // find an endpoint to send command
+           DataStore store = 
this.storeMgr.getDataStore(vmTemplateHost.getDataStoreId(), 
DataStoreRole.Image);
+           EndPoint ep = _epSelector.select(store);
            try{
            // Create Symlink at ssvm
                String path = vmTemplateHost.getInstallPath();
@@@ -256,12 -257,12 +258,12 @@@
                  _uploadDao.update(uploadTemplateObj.getId(), uploadJob);
              }
            }
 -
 +          
        }
 -
 +      
        @Override
-     public void createVolumeDownloadURL(Long entityId, String path, Type 
type, Long dataCenterId, Long uploadId) {
+     public void createVolumeDownloadURL(Long entityId, String path, Type 
type, Long dataCenterId, Long uploadId, ImageFormat format) {
 -
 +        
            String errorString = "";
            boolean success = false;
            try{
@@@ -278,20 -279,19 +280,19 @@@
              _uploadDao.update(uploadJob.getId(), uploadJob);
  
              // Create Symlink at ssvm
-             String uuid = UUID.randomUUID().toString() + 
path.substring(path.length() - 4) ; // last 4 characters of the path specify 
the format like .vhd
-             HostVO secStorage = 
ApiDBUtils.findHostById(ApiDBUtils.findUploadById(uploadId).getHostId());
-             HostVO ssvm = _ssvmMgr.pickSsvmHost(secStorage);
-             if( ssvm == null ) {
-               errorString = "There is no secondary storage VM for secondary 
storage host " + secStorage.getName();
+             String uuid = UUID.randomUUID().toString() + "." + 
format.toString().toLowerCase() ;
+             DataStore secStore = 
this.storeMgr.getDataStore(ApiDBUtils.findUploadById(uploadId).getDataStoreId(),
 DataStoreRole.Image);
+             EndPoint ep = _epSelector.select(secStore);
+             if( ep == null ) {
+               errorString = "There is no secondary storage VM for secondary 
storage host " + secStore.getName();
                throw new CloudRuntimeException(errorString);
              }
 -
 +            
-             CreateEntityDownloadURLCommand cmd = new 
CreateEntityDownloadURLCommand(secStorage.getParent(), path, uuid);
-             try {
-                   send(ssvm.getId(), cmd, null);
-             } catch (AgentUnavailableException e) {
-                 errorString = "Unable to create a link for " +type+ " 
id:"+entityId + "," + e.getMessage();
-                 s_logger.warn(errorString, e);
+             CreateEntityDownloadURLCommand cmd = new 
CreateEntityDownloadURLCommand(((ImageStoreEntity)secStore).getMountPoint(), 
path, uuid);
+             Answer ans = ep.sendMessage(cmd);
+             if (ans == null || !ans.getResult()) {
+                 errorString = "Unable to create a link for " +type+ " 
id:"+entityId + "," + ans.getDetails();
+                 s_logger.warn(errorString);
                  throw new CloudRuntimeException(errorString);
              }
  
@@@ -340,21 -340,23 +341,23 @@@
                        hostname = hostname + ".realhostip.com";
                    }               
                }
 -              return scheme + "://" + hostname + "/userdata/" + uuid;
 +              return scheme + "://" + hostname + "/userdata/" + uuid; 
            }
 -
 +      
  
  
-       public void send(Long hostId, Command cmd, Listener listener) throws 
AgentUnavailableException {
-               _agentMgr.send(hostId, new Commands(cmd), listener);
-       }
  
        @Override
        public boolean configure(String name, Map<String, Object> params)
                        throws ConfigurationException {
          final Map<String, String> configs = 
_configDao.getConfiguration("ManagementServer", params);
          _sslCopy = 
Boolean.parseBoolean(configs.get("secstorage.encrypt.copy"));
 -
 +        
+         String cert = configs.get("secstorage.secure.copy.cert");
+         if ("realhostip.com".equalsIgnoreCase(cert)) {
+               s_logger.warn("Only realhostip.com ssl cert is supported, 
ignoring self-signed and other certs");
+         }
+ 
          _ssvmUrlDomain = configs.get("secstorage.ssl.cert.domain");      
          
          _agentMgr.registerForHostEvents(new UploadListener(this), true, 
false, false);
@@@ -378,12 -380,12 +381,12 @@@
        }
  
        @Override
 -      public boolean stop() {
 +      public boolean stop() {         
                return true;
        }
 -
 +      
-       public void handleUploadEvent(HostVO host, Long accountId, String 
typeName, Type type, Long uploadId, com.cloud.storage.Upload.Status reason, 
long eventId) {
+       public void handleUploadEvent(Long accountId, String typeName, Type 
type, Long uploadId, com.cloud.storage.Upload.Status reason, long eventId) {
 -
 +              
                if ((reason == Upload.Status.UPLOADED) || 
(reason==Upload.Status.ABANDONED)){
                        UploadVO uploadObj = new UploadVO(uploadId);
                        UploadListener oldListener = 
_listenerMap.get(uploadObj);
@@@ -459,17 -461,18 +462,18 @@@
  
          final int EXTRACT_URL_LIFE_LIMIT_IN_SECONDS = _urlExpirationInterval;
          List<UploadVO> extractJobs= 
_uploadDao.listByModeAndStatus(Mode.HTTP_DOWNLOAD, Status.DOWNLOAD_URL_CREATED);
 -
 +        
          for (UploadVO extractJob : extractJobs){
 -            if( getTimeDiff(extractJob.getLastUpdated()) > 
EXTRACT_URL_LIFE_LIMIT_IN_SECONDS ){
 +            if( getTimeDiff(extractJob.getLastUpdated()) > 
EXTRACT_URL_LIFE_LIMIT_IN_SECONDS ){                           
                  String path = extractJob.getInstallPath();
-                 HostVO secStorage = 
ApiDBUtils.findHostById(extractJob.getHostId());
+                 DataStore secStore = 
this.storeMgr.getDataStore(extractJob.getDataStoreId(), DataStoreRole.Image);
+ 
 -
 +                
                  // Would delete the symlink for the Type and if Type == 
VOLUME then also the volume
-                 DeleteEntityDownloadURLCommand cmd = new 
DeleteEntityDownloadURLCommand(path, 
extractJob.getType(),extractJob.getUploadUrl(), secStorage.getParent());
-                 HostVO ssvm = _ssvmMgr.pickSsvmHost(secStorage);
-                 if( ssvm == null ) {
-                       s_logger.warn("UploadMonitor cleanup: There is no 
secondary storage VM for secondary storage host " + extractJob.getHostId());
+                 DeleteEntityDownloadURLCommand cmd = new 
DeleteEntityDownloadURLCommand(path, 
extractJob.getType(),extractJob.getUploadUrl(), 
((ImageStoreVO)secStore).getParent());
+                 EndPoint ep = _epSelector.select(secStore);
+                  if( ep == null ) {
+                       s_logger.warn("UploadMonitor cleanup: There is no 
secondary storage VM for secondary storage host " + 
extractJob.getDataStoreId());
                        continue; //TODO: why continue? why not break?
                  }
                  if (s_logger.isDebugEnabled()) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7b7db056/server/src/com/cloud/template/TemplateAdapterBase.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/template/TemplateAdapterBase.java
index 9b6487b,c1f0604..8e01063
--- a/server/src/com/cloud/template/TemplateAdapterBase.java
+++ b/server/src/com/cloud/template/TemplateAdapterBase.java
@@@ -27,10 -27,9 +27,10 @@@ import org.apache.cloudstack.api.comman
  import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd;
  import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
  import org.apache.cloudstack.api.command.user.template.ExtractTemplateCmd;
 +import org.apache.cloudstack.context.CallContext;
  import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
  import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
- import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole;
+ import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
  import org.apache.log4j.Logger;
  
  import com.cloud.api.ApiDBUtils;
@@@ -99,31 -100,24 +100,24 @@@ public abstract class TemplateAdapterBa
                    (accountType == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN));
        }
  
+       @Override
 -    public TemplateProfile prepare(boolean isIso, Long userId, String name, 
String displayText, Integer bits,
 +      public TemplateProfile prepare(boolean isIso, Long userId, String name, 
String displayText, Integer bits,
              Boolean passwordEnabled, Boolean requiresHVM, String url, Boolean 
isPublic, Boolean featured,
              Boolean isExtractable, String format, Long guestOSId, Long 
zoneId, HypervisorType hypervisorType,
              String accountName, Long domainId, String chksum, Boolean 
bootable, Map details) throws ResourceAllocationException {
            return prepare(isIso, userId, name, displayText, bits, 
passwordEnabled, requiresHVM, url, isPublic, featured, isExtractable, format, 
guestOSId, zoneId, hypervisorType,
-                   chksum, bootable, null, null, details, false, null);
+                   chksum, bootable, null, null, details, false, null, false);
        }
 -
 +      
+       @Override
 -    public TemplateProfile prepare(boolean isIso, long userId, String name, 
String displayText, Integer bits,
 +      public TemplateProfile prepare(boolean isIso, long userId, String name, 
String displayText, Integer bits,
                        Boolean passwordEnabled, Boolean requiresHVM, String 
url, Boolean isPublic, Boolean featured,
                        Boolean isExtractable, String format, Long guestOSId, 
Long zoneId, HypervisorType hypervisorType,
                        String chksum, Boolean bootable, String templateTag, 
Account templateOwner, Map details, Boolean sshkeyEnabled,
-                       String imageStoreUuid) throws 
ResourceAllocationException {
+                       String imageStoreUuid, Boolean isDynamicallyScalable) 
throws ResourceAllocationException {
                //Long accountId = null;
                // parameters verification
 -
 +              
-           String storeUuid = imageStoreUuid;
-         if (storeUuid != null) {
-             DataStore store = this.storeMgr.getDataStore(storeUuid, 
DataStoreRole.Image);
-             if (store == null) {
-                 throw new InvalidParameterValueException("invalide image 
store uuid" + storeUuid);
-             }
-             
-         }
-         
                if (isPublic == null) {
                        isPublic = Boolean.FALSE;
                }
@@@ -216,57 -211,54 +211,54 @@@
                  throw new IllegalArgumentException("Cannot use reserved names 
for templates");
              }
          }
 -
 +        
-         DataStore imageStore = this.templateMgr.getImageStore(imageStoreUuid, 
zoneId);
-         if (imageStore == null) {
-             throw new IllegalArgumentException("Cann't find an image store");
-         }
-         Long imageStoreId = imageStore.getId();
-         
          Long id = _tmpltDao.getNextInSequence(Long.class, "id");
 -        UserContext.current().setEventDetails("Id: " +id+ " name: " + name);
 +        CallContext.current().setEventDetails("Id: " +id+ " name: " + name);
                return new TemplateProfile(id, userId, name, displayText, bits, 
passwordEnabled, requiresHVM, url, isPublic,
-                               featured, isExtractable, imgfmt, guestOSId, 
zoneId, hypervisorType, templateOwner.getAccountName(), 
templateOwner.getDomainId(), templateOwner.getAccountId(), chksum, bootable, 
templateTag, details, sshkeyEnabled, imageStoreId);
+                               featured, isExtractable, imgfmt, guestOSId, 
zoneId, hypervisorType, templateOwner.getAccountName(), 
templateOwner.getDomainId(), templateOwner.getAccountId(), chksum, bootable, 
templateTag, details, sshkeyEnabled, null, isDynamicallyScalable);
+ 
        }
 -
 +      
        @Override
        public TemplateProfile prepare(RegisterTemplateCmd cmd) throws 
ResourceAllocationException {
            //check if the caller can operate with the template owner
 -        Account caller = UserContext.current().getCaller();
 +        Account caller = CallContext.current().getCallingAccount();
          Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId());
          _accountMgr.checkAccess(caller, null, true, owner);
 +          
  
 -
 -
 -              return prepare(false, UserContext.current().getCallerUserId(), 
cmd.getTemplateName(), cmd.getDisplayText(),
 +        
 +              return prepare(false, CallContext.current().getCallingUserId(), 
cmd.getTemplateName(), cmd.getDisplayText(),
                                cmd.getBits(), cmd.isPasswordEnabled(), 
cmd.getRequiresHvm(), cmd.getUrl(), cmd.isPublic(), cmd.isFeatured(),
                                cmd.isExtractable(), cmd.getFormat(), 
cmd.getOsTypeId(), cmd.getZoneId(), HypervisorType.getType(cmd.getHypervisor()),
-                               cmd.getChecksum(), true, cmd.getTemplateTag(), 
owner, cmd.getDetails(), cmd.isSshKeyEnabled(), cmd.getImageStoreUuid());
+                               cmd.getChecksum(), true, cmd.getTemplateTag(), 
owner, cmd.getDetails(), cmd.isSshKeyEnabled(), null, 
cmd.isDynamicallyScalable());
+ 
        }
  
+       @Override
 -    public TemplateProfile prepare(RegisterIsoCmd cmd) throws 
ResourceAllocationException {
 +      public TemplateProfile prepare(RegisterIsoCmd cmd) throws 
ResourceAllocationException {
            //check if the caller can operate with the template owner
 -          Account caller = UserContext.current().getCaller();
 +          Account caller = CallContext.current().getCallingAccount();
            Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId());
            _accountMgr.checkAccess(caller, null, true, owner);
 -
 -              return prepare(true, UserContext.current().getCallerUserId(), 
cmd.getIsoName(), cmd.getDisplayText(), 64, false,
 +         
 +              return prepare(true, CallContext.current().getCallingUserId(), 
cmd.getIsoName(), cmd.getDisplayText(), 64, false,
                                        true, cmd.getUrl(), cmd.isPublic(), 
cmd.isFeatured(), cmd.isExtractable(), ImageFormat.ISO.toString(), 
cmd.getOsTypeId(),
-                                       cmd.getZoneId(), HypervisorType.None, 
cmd.getChecksum(), cmd.isBootable(), null, owner, null, false, 
cmd.getImageStoreUuid());
+                                       cmd.getZoneId(), HypervisorType.None, 
cmd.getChecksum(), cmd.isBootable(), null, owner, null, false, 
cmd.getImageStoreUuid(), cmd.isDynamicallyScalable());
        }
 -
 +      
        protected VMTemplateVO persistTemplate(TemplateProfile profile) {
                Long zoneId = profile.getZoneId();
                VMTemplateVO template = new 
VMTemplateVO(profile.getTemplateId(), profile.getName(), profile.getFormat(), 
profile.getIsPublic(),
                                profile.getFeatured(), 
profile.getIsExtractable(), TemplateType.USER, profile.getUrl(), 
profile.getRequiresHVM(),
                                profile.getBits(), profile.getAccountId(), 
profile.getCheckSum(), profile.getDisplayText(),
 -                              profile.getPasswordEnabled(), 
profile.getGuestOsId(), profile.getBootable(), profile.getHypervisorType(), 
profile.getTemplateTag(),
 +                              profile.getPasswordEnabled(), 
profile.getGuestOsId(), profile.getBootable(), profile.getHypervisorType(), 
profile.getTemplateTag(), 
                                profile.getDetails(), 
profile.getSshKeyEnabled());
  
-               template.setImageDataStoreId(profile.getImageStoreId());
+ 
                if (zoneId == null || zoneId.longValue() == -1) {
              List<DataCenterVO> dcs = _dcDao.listAll();
 -
 +            
              if (dcs.isEmpty()) {
                throw new CloudRuntimeException("No zones are present in the 
system, can't add template");
              }
@@@ -315,11 -307,12 +307,12 @@@
  
                return userId;
        }
 -
 +      
+       @Override
 -    public TemplateProfile prepareDelete(DeleteTemplateCmd cmd) {
 +      public TemplateProfile prepareDelete(DeleteTemplateCmd cmd) {
                Long templateId = cmd.getId();
 -              Long userId = UserContext.current().getCallerUserId();
 -              Account account = UserContext.current().getCaller();
 +              Long userId = CallContext.current().getCallingUserId();
 +              Account account = CallContext.current().getCallingAccount();
                Long zoneId = cmd.getZoneId();
  
                VMTemplateVO template = 
_tmpltDao.findById(templateId.longValue());
@@@ -378,6 -371,8 +371,8 @@@
        return new TemplateProfile(userId, template, zoneId);
        }
  
+       @Override
 -    abstract public VMTemplateVO create(TemplateProfile profile);
 +      abstract public VMTemplateVO create(TemplateProfile profile);
+       @Override
 -    abstract public boolean delete(TemplateProfile profile);
 +      abstract public boolean delete(TemplateProfile profile);
  }

Reply via email to