cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ahu...@apache.org
Subject [38/50] [abbrv] Merged
Date Fri, 10 May 2013 23:33:21 GMT
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/30479293/server/src/com/cloud/storage/upload/UploadListener.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/storage/upload/UploadListener.java
index 8d9cbb6,ee13cf9..d3b7af9
--- a/server/src/com/cloud/storage/upload/UploadListener.java
+++ b/server/src/com/cloud/storage/upload/UploadListener.java
@@@ -16,7 -16,7 +16,6 @@@
  // under the License.
  package com.cloud.storage.upload;
  
--
  import java.util.Collections;
  import java.util.Date;
  import java.util.HashMap;
@@@ -24,10 -24,8 +23,16 @@@ import java.util.Map
  import java.util.Timer;
  import java.util.TimerTask;
  
 +import javax.inject.Inject;
 +
  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;
  
@@@ -42,18 -40,14 +47,10 @@@ import com.cloud.agent.api.storage.Uplo
  import com.cloud.agent.api.storage.UploadCommand;
  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.exception.AgentUnavailableException;
 -import com.cloud.host.HostVO;
 +import com.cloud.host.Host;
- import com.cloud.host.HostVO;
  import com.cloud.storage.Storage;
  import com.cloud.storage.Upload.Status;
  import com.cloud.storage.Upload.Type;
@@@ -64,403 -58,401 +61,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;
--
--		public StatusTask( UploadListener ul,  RequestType req) {
--			this.reqType = req;
--			this.ul = ul;
--		}
--
--		@Override
--		public void run() {
--		  ul.sendCommand(reqType);
--
--		}
--	}
--
--	private static final class TimeoutTask extends TimerTask {
--		private final UploadListener ul;
--
--		public TimeoutTask( UploadListener ul) {
--			this.ul = ul;
--		}
--
--		@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 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>();
++    private static final class StatusTask extends TimerTask {
++        private final UploadListener ul;
++        private final RequestType reqType;
++
++        public StatusTask(UploadListener ul, RequestType req) {
++            this.reqType = req;
++            this.ul = ul;
++        }
++
++        @Override
++        public void run() {
++            ul.sendCommand(reqType);
++
++        }
++    }
++
++    private static final class TimeoutTask extends TimerTask {
++        private final UploadListener ul;
++
++        public TimeoutTask(UploadListener ul) {
++            this.ul = ul;
++        }
++
++        @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 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 DataStore sserver;
- 
- 	private boolean uploadActive = true;
- 
- 	private UploadDao uploadDao;
- 
- 	private final UploadMonitorImpl uploadMonitor;
- 
- 	private UploadState currState;
- 
- 	private UploadCommand cmd;
- 
- 	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;
- 	@Inject EndPointSelector _epSelector;
- 
- 	public AsyncJobManager getAsyncMgr() {
- 		return asyncMgr;
- 	}
- 
- 	public void setAsyncMgr(AsyncJobManager asyncMgr) {
- 		this.asyncMgr = asyncMgr;
- 	}
- 
- 	public long getAsyncJobId() {
- 		return asyncJobId;
- 	}
- 
- 	public void setAsyncJobId(long asyncJobId) {
- 		this.asyncJobId = asyncJobId;
- 	}
- 
- 	public long getEventId() {
- 		return eventId;
- 	}
- 
- 	public void setEventId(long eventId) {
- 		this.eventId = eventId;
- 	}
- 
- 	private final Map<String,  UploadState> stateMap = new HashMap<String, UploadState>();
- 	private Long uploadId;
- 
- 	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;
- 		if ( type == Type.VOLUME ){
- 		    extractId = ApiDBUtils.findVolumeById(uploadObj.getTypeId()).getUuid();
- 		}
- 		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()));
- 		updateDatabase(Status.NOT_UPLOADED, cmd.getUrl(),"");
- 	}
- 
- 	public UploadListener(UploadMonitorImpl monitor) {
- 	    uploadMonitor = monitor;
- 	}
- 
- 	public void checkProgress() {
- 		transition(UploadEvent.TIMEOUT_CHECK, null);
- 	}
- 
- 	@Override
- 	public int getTimeout() {
- 		return -1;
- 	}
- 
- 	@Override
- 	public boolean isRecurring() {
- 		return false;
- 	}
- 
- 	public void setCommand(UploadCommand _cmd) {
- 		this.cmd = _cmd;
- 	}
- 
- 	public void setJobId(String _jobId) {
- 		this.jobId = _jobId;
- 	}
- 
- 	public String getJobId() {
- 		return jobId;
- 	}
- 
- 	@Override
- 	public boolean processAnswers(long agentId, long seq, Answer[] answers) {
- 		boolean processed = false;
-     	if(answers != null & answers.length > 0) {
-     		if(answers[0] instanceof UploadAnswer) {
-     			final UploadAnswer answer = (UploadAnswer)answers[0];
-     			if (getJobId() == null) {
-     				setJobId(answer.getJobId());
-     			} else if (!getJobId().equalsIgnoreCase(answer.getJobId())){
-     				return false;//TODO
-     			}
-     			transition(UploadEvent.UPLOAD_ANSWER, answer);
-     			processed = true;
-     		}
-     	}
 -	private HostVO sserver;
 -
 -	private boolean uploadActive = true;
 -
 -	private UploadDao uploadDao;
 -
 -	private final UploadMonitorImpl uploadMonitor;
 -
 -	private UploadState currState;
 -
 -	private UploadCommand cmd;
 -
 -	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;
 -
 -	public AsyncJobManager getAsyncMgr() {
 -		return asyncMgr;
 -	}
 -
 -	public void setAsyncMgr(AsyncJobManager asyncMgr) {
 -		this.asyncMgr = asyncMgr;
 -	}
 -
 -	public long getAsyncJobId() {
 -		return asyncJobId;
 -	}
 -
 -	public void setAsyncJobId(long asyncJobId) {
 -		this.asyncJobId = asyncJobId;
 -	}
 -
 -	public long getEventId() {
 -		return eventId;
 -	}
 -
 -	public void setEventId(long eventId) {
 -		this.eventId = eventId;
 -	}
 -
 -	private final Map<String,  UploadState> stateMap = new HashMap<String, UploadState>();
 -	private Long uploadId;
 -
 -	public UploadListener(HostVO 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;
 -		if ( type == Type.VOLUME ){
 -		    extractId = ApiDBUtils.findVolumeById(uploadObj.getTypeId()).getUuid();
 -		}
 -		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()));
 -		updateDatabase(Status.NOT_UPLOADED, cmd.getUrl(),"");
 -	}
 -
 -	public UploadListener(UploadMonitorImpl monitor) {
 -	    uploadMonitor = monitor;
 -	}
 -
 -	public void checkProgress() {
 -		transition(UploadEvent.TIMEOUT_CHECK, null);
 -	}
 -
 -	@Override
 -	public int getTimeout() {
 -		return -1;
 -	}
 -
 -	@Override
 -	public boolean isRecurring() {
 -		return false;
 -	}
 -
 -	public void setCommand(UploadCommand _cmd) {
 -		this.cmd = _cmd;
 -	}
 -
 -	public void setJobId(String _jobId) {
 -		this.jobId = _jobId;
 -	}
 -
 -	public String getJobId() {
 -		return jobId;
 -	}
 -
 -	@Override
 -	public boolean processAnswers(long agentId, long seq, Answer[] answers) {
 -		boolean processed = false;
 -    	if(answers != null & answers.length > 0) {
 -    		if(answers[0] instanceof UploadAnswer) {
 -    			final UploadAnswer answer = (UploadAnswer)answers[0];
 -    			if (getJobId() == null) {
 -    				setJobId(answer.getJobId());
 -    			} else if (!getJobId().equalsIgnoreCase(answer.getJobId())){
 -    				return false;//TODO
 -    			}
 -    			transition(UploadEvent.UPLOAD_ANSWER, answer);
 -    			processed = true;
 -    		}
 -    	}
++    }
++
++    private DataStore sserver;
++
++    private boolean uploadActive = true;
++
++    private UploadDao uploadDao;
++
++    private final UploadMonitorImpl uploadMonitor;
++
++    private UploadState currState;
++
++    private UploadCommand cmd;
++
++    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;
++    @Inject
++    EndPointSelector _epSelector;
++
++    public AsyncJobManager getAsyncMgr() {
++        return asyncMgr;
++    }
++
++    public void setAsyncMgr(AsyncJobManager asyncMgr) {
++        this.asyncMgr = asyncMgr;
++    }
++
++    public long getAsyncJobId() {
++        return asyncJobId;
++    }
++
++    public void setAsyncJobId(long asyncJobId) {
++        this.asyncJobId = asyncJobId;
++    }
++
++    public long getEventId() {
++        return eventId;
++    }
++
++    public void setEventId(long eventId) {
++        this.eventId = eventId;
++    }
++
++    private final Map<String, UploadState> stateMap = new HashMap<String, UploadState>();
++    private Long uploadId;
++
++    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;
++        if (type == Type.VOLUME) {
++            extractId = ApiDBUtils.findVolumeById(uploadObj.getTypeId()).getUuid();
++        }
++        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()));
++        updateDatabase(Status.NOT_UPLOADED, cmd.getUrl(), "");
++    }
++
++    public UploadListener(UploadMonitorImpl monitor) {
++        uploadMonitor = monitor;
++    }
++
++    public void checkProgress() {
++        transition(UploadEvent.TIMEOUT_CHECK, null);
++    }
++
++    @Override
++    public int getTimeout() {
++        return -1;
++    }
++
++    @Override
++    public boolean isRecurring() {
++        return false;
++    }
++
++    public void setCommand(UploadCommand _cmd) {
++        this.cmd = _cmd;
++    }
++
++    public void setJobId(String _jobId) {
++        this.jobId = _jobId;
++    }
++
++    public String getJobId() {
++        return jobId;
++    }
++
++    @Override
++    public boolean processAnswers(long agentId, long seq, Answer[] answers) {
++        boolean processed = false;
++        if (answers != null & answers.length > 0) {
++            if (answers[0] instanceof UploadAnswer) {
++                final UploadAnswer answer = (UploadAnswer)answers[0];
++                if (getJobId() == null) {
++                    setJobId(answer.getJobId());
++                } else if (!getJobId().equalsIgnoreCase(answer.getJobId())) {
++                    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 void processConnect(Host agent, StartupCommand cmd, boolean forRebalance) {
- 		if (!(cmd instanceof StartupStorageCommand)) {
- 	        return;
- 	    }
- 
- 	    long agentId = agent.getId();
- 
- 	    StartupStorageCommand storage = (StartupStorageCommand)cmd;
- 	    if (storage.getResourceType() == Storage.StorageResourceType.STORAGE_HOST ||
- 	    storage.getResourceType() == Storage.StorageResourceType.SECONDARY_STORAGE )
- 	    {
- 	    	uploadMonitor.handleUploadSync(agentId);
- 	    }
- 	}
- 
- 	@Override
- 	public AgentControlAnswer processControlCommand(long agentId,
- 			AgentControlCommand cmd) {
- 		return null;
- 	}
- 
- 	public void setUploadInactive(Status reason) {
- 		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 cancelTimeoutTask() {
- 		if (timeoutTask != null) timeoutTask.cancel();
- 	}
- 
- 	public void cancelStatusTask() {
- 		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 {
- 				throw new CloudRuntimeException("Invalid next state: currState="+prevName+", evt="+event + ", next=" + nextState);
- 			}
- 		} else {
- 			throw new CloudRuntimeException("Unhandled event transition: currState="+prevName+", evt="+event);
- 		}
- 	}
- 
- 	public Date getLastUpdated() {
- 		return lastUpdated;
- 	}
- 
- 	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 setDisconnected() {
- 		transition(UploadEvent.DISCONNECT, null);
- 	}
- 
- 	public void scheduleStatusCheck(com.cloud.agent.api.storage.UploadProgressCommand.RequestType getStatus) {
- 		if (statusTask != null) statusTask.cancel();
- 
- 		statusTask = new StatusTask(this, getStatus);
- 		timer.schedule(statusTask, STATUS_POLL_INTERVAL);
- 	}
- 
- 	public void scheduleTimeoutTask(long delay) {
- 		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);
- 	}
- 
- 	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);
- 	}
- 
- 	private Long getUploadId() {
- 		return uploadId;
- 	}
- 
- 	public synchronized void updateDatabase(UploadAnswer answer) {
- 
- 	    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());
- 
- 		if (answer.getUploadStatus() == Status.UPLOAD_IN_PROGRESS){
- 			asyncMgr.updateAsyncJobAttachment(asyncJobId, type.toString(), 1L);
- 			asyncMgr.updateAsyncJobStatus(asyncJobId, AsyncJobResult.STATUS_IN_PROGRESS, resultObj);
- 		}else if(answer.getUploadStatus() == Status.UPLOADED){
- 		    resultObj.setResultString("Success");
- 			asyncMgr.completeAsyncJob(asyncJobId, AsyncJobResult.STATUS_SUCCEEDED, 1, resultObj);
- 		}else{
- 			asyncMgr.completeAsyncJob(asyncJobId, AsyncJobResult.STATUS_FAILED, 2, resultObj);
- 		}
 -	public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) {
 -		if (!(cmd instanceof StartupStorageCommand)) {
 -	        return;
 -	    }
 -
 -	    long agentId = agent.getId();
 -
 -	    StartupStorageCommand storage = (StartupStorageCommand)cmd;
 -	    if (storage.getResourceType() == Storage.StorageResourceType.STORAGE_HOST ||
 -	    storage.getResourceType() == Storage.StorageResourceType.SECONDARY_STORAGE )
 -	    {
 -	    	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);
 -	}
 -
 -	public void logUploadStart() {
 -		//uploadMonitor.logEvent(accountId, event, "Storage server " + sserver.getName() + " started upload of " +type.toString() + " " + typeName, EventVO.LEVEL_INFO, eventId);
 -	}
 -
 -	public void cancelTimeoutTask() {
 -		if (timeoutTask != null) timeoutTask.cancel();
 -	}
 -
 -	public void cancelStatusTask() {
 -		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 {
 -				throw new CloudRuntimeException("Invalid next state: currState="+prevName+", evt="+event + ", next=" + nextState);
 -			}
 -		} else {
 -			throw new CloudRuntimeException("Unhandled event transition: currState="+prevName+", evt="+event);
 -		}
 -	}
 -
 -	public Date getLastUpdated() {
 -		return lastUpdated;
 -	}
 -
 -	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 setDisconnected() {
 -		transition(UploadEvent.DISCONNECT, null);
 -	}
 -
 -	public void scheduleStatusCheck(com.cloud.agent.api.storage.UploadProgressCommand.RequestType getStatus) {
 -		if (statusTask != null) statusTask.cancel();
 -
 -		statusTask = new StatusTask(this, getStatus);
 -		timer.schedule(statusTask, STATUS_POLL_INTERVAL);
 -	}
 -
 -	public void scheduleTimeoutTask(long delay) {
 -		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);
 -	}
 -
 -	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);
 -	}
 -
 -	private Long getUploadId() {
 -		return uploadId;
 -	}
 -
 -	public synchronized void updateDatabase(UploadAnswer answer) {
 -
 -	    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());
 -
 -		if (answer.getUploadStatus() == Status.UPLOAD_IN_PROGRESS){
 -			asyncMgr.updateAsyncJobAttachment(asyncJobId, type.toString(), 1L);
 -			asyncMgr.updateAsyncJobStatus(asyncJobId, AsyncJobResult.STATUS_IN_PROGRESS, resultObj);
 -		}else if(answer.getUploadStatus() == Status.UPLOADED){
 -		    resultObj.setResultString("Success");
 -			asyncMgr.completeAsyncJob(asyncJobId, AsyncJobResult.STATUS_SUCCEEDED, 1, resultObj);
 -		}else{
 -			asyncMgr.completeAsyncJob(asyncJobId, AsyncJobResult.STATUS_FAILED, 2, resultObj);
 -		}
++    }
++
++    @Override
++    public boolean processCommands(long agentId, long seq, Command[] commands) {
++        return false;
++    }
++
++    @Override
++    public void processConnect(Host agent, StartupCommand cmd, boolean forRebalance) {
++        if (!(cmd instanceof StartupStorageCommand)) {
++            return;
++        }
++
++        long agentId = agent.getId();
++
++        StartupStorageCommand storage = (StartupStorageCommand)cmd;
++        if (storage.getResourceType() == Storage.StorageResourceType.STORAGE_HOST ||
++                storage.getResourceType() == Storage.StorageResourceType.SECONDARY_STORAGE)
++        {
++            uploadMonitor.handleUploadSync(agentId);
++        }
++    }
++
++    @Override
++    public AgentControlAnswer processControlCommand(long agentId,
++            AgentControlCommand cmd) {
++        return null;
++    }
++
++    public void setUploadInactive(Status reason) {
++        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 cancelTimeoutTask() {
++        if (timeoutTask != null)
++            timeoutTask.cancel();
++    }
++
++    public void cancelStatusTask() {
++        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 {
++                throw new CloudRuntimeException("Invalid next state: currState=" + prevName + ", evt=" + event + ", next=" + nextState);
++            }
++        } else {
++            throw new CloudRuntimeException("Unhandled event transition: currState=" + prevName + ", evt=" + event);
++        }
++    }
++
++    public Date getLastUpdated() {
++        return lastUpdated;
++    }
++
++    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 setDisconnected() {
++        transition(UploadEvent.DISCONNECT, null);
++    }
++
++    public void scheduleStatusCheck(com.cloud.agent.api.storage.UploadProgressCommand.RequestType getStatus) {
++        if (statusTask != null)
++            statusTask.cancel();
++
++        statusTask = new StatusTask(this, getStatus);
++        timer.schedule(statusTask, STATUS_POLL_INTERVAL);
++    }
++
++    public void scheduleTimeoutTask(long delay) {
++        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);
++    }
++
++    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);
++    }
++
++    private Long getUploadId() {
++        return uploadId;
++    }
++
++    public synchronized void updateDatabase(UploadAnswer answer) {
++
++        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());
++
++        if (answer.getUploadStatus() == Status.UPLOAD_IN_PROGRESS) {
++            asyncMgr.updateAsyncJobAttachment(asyncJobId, type.toString(), 1L);
++            asyncMgr.updateAsyncJobStatus(asyncJobId, AsyncJobResult.STATUS_IN_PROGRESS, resultObj);
++        } else if (answer.getUploadStatus() == Status.UPLOADED) {
++            resultObj.setResultString("Success");
++            asyncMgr.completeAsyncJob(asyncJobId, AsyncJobResult.STATUS_SUCCEEDED, 1, resultObj);
++        } else {
++            asyncMgr.completeAsyncJob(asyncJobId, AsyncJobResult.STATUS_FAILED, 2, 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 {
- 			    EndPoint ep = _epSelector.select(sserver);
- 			    ep.sendMessageAsyncWithListener(new UploadProgressCommand(getCommand(), getJobId(), reqType), this);
 -	            uploadMonitor.send(sserver.getId(), new UploadProgressCommand(getCommand(), getJobId(), reqType), this);
 -            } catch (AgentUnavailableException e) {
 -            	s_logger.debug("Send command failed", e);
 -				setDisconnected();
++        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);
+             }
 -		}
 -
 -	}
 -
 -	private UploadCommand getCommand() {
 -		return cmd;
 -	}
 -
 -	public void logDisconnect() {
 -		s_logger.warn("Unable to monitor upload progress of " + typeName + " at host " + sserver.getName());
 -	}
 -
 -	public void scheduleImmediateStatusCheck(RequestType request) {
 -		if (statusTask != null) statusTask.cancel();
 -		statusTask = new StatusTask(this, request);
 -		timer.schedule(statusTask, SMALL_DELAY);
 -	}
 -
 -	public void setCurrState(Status uploadState) {
 -		this.currState = getState(currState.toString());
 -	}
++            try {
++                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;
- 	}
- 
- 	public void logDisconnect() {
- 		s_logger.warn("Unable to monitor upload progress of " + typeName + " at host " + sserver.getName());
- 	}
- 
- 	public void scheduleImmediateStatusCheck(RequestType request) {
- 		if (statusTask != null) statusTask.cancel();
- 		statusTask = new StatusTask(this, request);
- 		timer.schedule(statusTask, SMALL_DELAY);
- 	}
- 
- 	public void setCurrState(Status uploadState) {
- 		this.currState = getState(currState.toString());
- 	}
++        }
++
++    }
++
++    private UploadCommand getCommand() {
++        return cmd;
++    }
++
++    public void logDisconnect() {
++        s_logger.warn("Unable to monitor upload progress of " + typeName + " at host " + sserver.getName());
++    }
++
++    public void scheduleImmediateStatusCheck(RequestType request) {
++        if (statusTask != null)
++            statusTask.cancel();
++        statusTask = new StatusTask(this, request);
++        timer.schedule(statusTask, SMALL_DELAY);
++    }
++
++    public void setCurrState(Status uploadState) {
++        this.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/30479293/server/src/com/cloud/storage/upload/UploadMonitorImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/storage/upload/UploadMonitorImpl.java
index 9eac227,77f0d20..b944b76
--- a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java
+++ b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java
@@@ -32,39 -32,32 +32,35 @@@ import javax.ejb.Local
  import javax.inject.Inject;
  import javax.naming.ConfigurationException;
  
 +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.EndPoint;
 +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
- import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
 +import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
++import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
  import org.apache.log4j.Logger;
  import org.springframework.stereotype.Component;
  
  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.Command;
  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.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;
  import com.cloud.resource.ResourceManager;
++import com.cloud.storage.DataStoreRole;
  import com.cloud.storage.Storage.ImageFormat;
  import com.cloud.storage.Upload;
  import com.cloud.storage.Upload.Mode;
  import com.cloud.storage.Upload.Status;
  import com.cloud.storage.Upload.Type;
- import com.cloud.storage.DataStoreRole;
  import com.cloud.storage.UploadVO;
 -import com.cloud.storage.VMTemplateHostVO;
  import com.cloud.storage.VMTemplateVO;
  import com.cloud.storage.VolumeVO;
  import com.cloud.storage.dao.UploadDao;
@@@ -167,37 -159,37 +163,37 @@@ public class UploadMonitorImpl extends 
  		_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.sendMessageAsyncWithListener(ucmd, ul);
++            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);			
 -		
 -		UploadVO uploadTemplateObj = new UploadVO(sserver.getId(), template.getId(), new Date(), 
 +
 +		DataStore secStore = this.storeMgr.getImageStore(dataCenterId);
 +
 +		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());	
 -			UploadListener ul = new UploadListener(sserver, _timer, _uploadDao, uploadTemplateObj, this, ucmd, template.getAccountId(), template.getName(), type, eventId, asyncJobId, asyncMgr);			
 +			UploadCommand ucmd = new UploadCommand(template, url, vmTemplateHost.getInstallPath(), vmTemplateHost.getSize());
 +			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.sendMessageAsyncWithListener(ucmd, ul);
++                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);
              }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/30479293/server/src/com/cloud/template/HypervisorTemplateAdapter.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/template/HypervisorTemplateAdapter.java
index 2e50406,322f32e..b2a49a3
--- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java
+++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java
@@@ -30,31 -30,38 +30,39 @@@ import javax.inject.Inject
  import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
  import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
  import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd;
+ import org.apache.cloudstack.api.command.user.template.ExtractTemplateCmd;
 -import com.cloud.agent.api.storage.PrepareOVAPackingCommand;
 -import com.cloud.agent.api.storage.PrepareOVAPackingAnswer;
  import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
 -import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult;
  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.engine.subsystem.api.storage.ImageDataFactory;
 -import org.apache.cloudstack.engine.subsystem.api.storage.ImageService;
++import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
++import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
 +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
 +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
 +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
 +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult;
 +import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
  import org.apache.cloudstack.framework.async.AsyncCallFuture;
 +import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
 +import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
 +import org.apache.cloudstack.framework.async.AsyncRpcConext;
 +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
  import org.apache.log4j.Logger;
  
  import com.cloud.agent.AgentManager;
+ import com.cloud.agent.api.Answer;
 -import com.cloud.agent.api.storage.DeleteTemplateCommand;
++import com.cloud.agent.api.storage.PrepareOVAPackingCommand;
 +import com.cloud.alert.AlertManager;
  import com.cloud.configuration.Resource.ResourceType;
+ import com.cloud.dc.DataCenterVO;
 -import com.cloud.event.EventTypes;
 -import com.cloud.event.UsageEventUtils;
  import com.cloud.exception.InvalidParameterValueException;
  import com.cloud.exception.ResourceAllocationException;
+ import com.cloud.host.HostVO;
 -import com.cloud.storage.Storage.ImageFormat;
++import com.cloud.hypervisor.Hypervisor.HypervisorType;
  import com.cloud.storage.Storage.TemplateType;
  import com.cloud.storage.TemplateProfile;
 -import com.cloud.storage.VMTemplateHostVO;
  import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
  import com.cloud.storage.VMTemplateVO;
 -import com.cloud.storage.VMTemplateZoneVO;
  import com.cloud.storage.download.DownloadMonitor;
 -import com.cloud.storage.secondary.SecondaryStorageVmManager;
  import com.cloud.user.Account;
  import com.cloud.utils.UriUtils;
  import com.cloud.utils.db.DB;
@@@ -67,10 -79,10 +75,12 @@@ public class HypervisorTemplateAdapter 
  	@Inject AgentManager _agentMgr;
  
      @Inject DataStoreManager storeMgr;
 -    @Inject ImageService imageService;
 -    @Inject ImageDataFactory imageFactory;
 +    @Inject TemplateService imageService;
 +    @Inject TemplateDataFactory imageFactory;
      @Inject TemplateManager templateMgr;
 +    @Inject AlertManager alertMgr;
++    @Inject
++    EndPointSelector _epSelector;
  
      @Override
      public String getName() {
@@@ -216,67 -270,129 +226,67 @@@
  	public boolean delete(TemplateProfile profile) {
  		boolean success = true;
  
--    	VMTemplateVO template = (VMTemplateVO)profile.getTemplate();
 -    	Long zoneId = profile.getZoneId();
 -    	Long templateId = template.getId();
 -
 -    	String zoneName;
 -    	List<HostVO> secondaryStorageHosts;
 -    	if (!template.isCrossZones() && zoneId != null) {
 -    		DataCenterVO zone = _dcDao.findById(zoneId);
 -    		zoneName = zone.getName();
 -    		secondaryStorageHosts = _ssvmMgr.listSecondaryStorageHostsInOneZone(zoneId);
 -    	} else {
 -    		zoneName = "(all zones)";
 -    		secondaryStorageHosts = _ssvmMgr.listSecondaryStorageHostsInAllZones();
 -    	}
++    	VMTemplateVO template = profile.getTemplate();
  
 -    	s_logger.debug("Attempting to mark template host refs for template: " + template.getName() + " as destroyed in zone: " + zoneName);
 -
 -		// Make sure the template is downloaded to all the necessary secondary storage hosts
 -		for (HostVO secondaryStorageHost : secondaryStorageHosts) {
 -			long hostId = secondaryStorageHost.getId();
 -			List<VMTemplateHostVO> templateHostVOs = _tmpltHostDao.listByHostTemplate(hostId, templateId);
 -			for (VMTemplateHostVO templateHostVO : templateHostVOs) {
 -				if (templateHostVO.getDownloadState() == Status.DOWNLOAD_IN_PROGRESS) {
 -					String errorMsg = "Please specify a template that is not currently being downloaded.";
 -					s_logger.debug("Template: " + template.getName() + " is currently being downloaded to secondary storage host: " + secondaryStorageHost.getName() + "; cant' delete it.");
 -					throw new CloudRuntimeException(errorMsg);
 -				}
 -			}
 -		}
 -
 -		Account account = _accountDao.findByIdIncludingRemoved(template.getAccountId());
 -		String eventType = "";
 -
 -		if (template.getFormat().equals(ImageFormat.ISO)){
 -			eventType = EventTypes.EVENT_ISO_DELETE;
 -		} else {
 -			eventType = EventTypes.EVENT_TEMPLATE_DELETE;
 -		}
 -
 -		// Iterate through all necessary secondary storage hosts and mark the template on each host as destroyed
 -		for (HostVO secondaryStorageHost : secondaryStorageHosts) {
 -			long hostId = secondaryStorageHost.getId();
 -			long sZoneId = secondaryStorageHost.getDataCenterId();
 -			List<VMTemplateHostVO> templateHostVOs = _tmpltHostDao.listByHostTemplate(hostId, templateId);
 -			for (VMTemplateHostVO templateHostVO : templateHostVOs) {
 -				VMTemplateHostVO lock = _tmpltHostDao.acquireInLockTable(templateHostVO.getId());
 -				try {
 -					if (lock == null) {
 -						s_logger.debug("Failed to acquire lock when deleting templateHostVO with ID: " + templateHostVO.getId());
 -						success = false;
 -						break;
 -					}
 -					UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null);
 -                    templateHostVO.setDestroyed(true);
 -					_tmpltHostDao.update(templateHostVO.getId(), templateHostVO);
 -                    String installPath = templateHostVO.getInstallPath();
 -                    List<UserVmVO> userVmUsingIso = _userVmDao.listByIsoId(templateId);
 -                    //check if there is any VM using this ISO.
 -                    if (userVmUsingIso == null || userVmUsingIso.isEmpty()) {
 -                    if (installPath != null) {
 -                        Answer answer = _agentMgr.sendToSecStorage(secondaryStorageHost, new DeleteTemplateCommand(secondaryStorageHost.getStorageUrl(), installPath));
 -
 -                        if (answer == null || !answer.getResult()) {
 -                            s_logger.debug("Failed to delete " + templateHostVO + " due to " + ((answer == null) ? "answer is null" : answer.getDetails()));
 -                        } else {
 -                            _tmpltHostDao.remove(templateHostVO.getId());
 -                            s_logger.debug("Deleted template at: " + installPath);
 -                        }
 -                    } else {
 -                        _tmpltHostDao.remove(templateHostVO.getId());
 -                    }
 -                    }
 -					VMTemplateZoneVO templateZone = _tmpltZoneDao.findByZoneTemplate(sZoneId, templateId);
 -
 -					if (templateZone != null) {
 -						_tmpltZoneDao.remove(templateZone.getId());
 -					}
 -				} finally {
 -					if (lock != null) {
 -						_tmpltHostDao.releaseFromLockTable(lock.getId());
 -					}
 -				}
 -			}
 -
 -			if (!success) {
 -				break;
 -			}
 -		}
 -
 -		s_logger.debug("Successfully marked template host refs for template: " + template.getName() + " as destroyed in zone: " + zoneName);
 +        // find all eligible image stores for this template
 +        List<DataStore> imageStores = this.templateMgr.getImageStoreByTemplate(template.getId(), profile.getZoneId());
 +        if ( imageStores == null || imageStores.size() == 0 ){
 +            throw new CloudRuntimeException("Unable to find image store to delete template "+ profile.getTemplate());
 +        }
  
 -		// If there are no more non-destroyed template host entries for this template, delete it
 -		if (success && (_tmpltHostDao.listByTemplateId(templateId).size() == 0)) {
 -			long accountId = template.getAccountId();
 +        // Make sure the template is downloaded to all found image stores
 +        for (DataStore store : imageStores) {
 +            long storeId = store.getId();
 +            List<TemplateDataStoreVO> templateStores = _tmpltStoreDao.listByTemplateStore(template.getId(), storeId);
 +            for (TemplateDataStoreVO templateStore : templateStores) {
 +                if (templateStore.getDownloadState() == Status.DOWNLOAD_IN_PROGRESS) {
 +                    String errorMsg = "Please specify a template that is not currently being downloaded.";
 +                    s_logger.debug("Template: " + template.getName() + " is currently being downloaded to secondary storage host: " + store.getName() + "; cant' delete it.");
 +                    throw new CloudRuntimeException(errorMsg);
 +                }
 +            }
 +        }
  
 -			VMTemplateVO lock = _tmpltDao.acquireInLockTable(templateId);
  
 -			try {
 -				if (lock == null) {
 -					s_logger.debug("Failed to acquire lock when deleting template with ID: " + templateId);
 -					success = false;
 -				} else if (_tmpltDao.remove(templateId)) {
 -				    // Decrement the number of templates and total secondary storage space used by the account
 -				    _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.template);
 -				    _resourceLimitMgr.recalculateResourceCount(accountId, account.getDomainId(),
 -				            ResourceType.secondary_storage.getOrdinal());
 -				}
 +        for (DataStore imageStore : imageStores) {
 +            s_logger.info("Delete template from image store: " + imageStore.getName());
 +            AsyncCallFuture<TemplateApiResult> future = this.imageService
 +                    .deleteTemplateAsync(this.imageFactory.getTemplate(template.getId(), imageStore));
 +            try {
 +                TemplateApiResult result = future.get();
 +                success = result.isSuccess();
 +                if ( !success )
 +                    break;
 +            } catch (InterruptedException e) {
 +                s_logger.debug("delete template Failed", e);
 +                throw new CloudRuntimeException("delete template Failed", e);
 +            } catch (ExecutionException e) {
 +                s_logger.debug("delete template Failed", e);
 +                throw new CloudRuntimeException("delete template Failed", e);
 +            }
 +        }
  
 -			} finally {
 -				if (lock != null) {
 -					_tmpltDao.releaseFromLockTable(lock.getId());
 -				}
 -			}
 +        if (success) {
 +            s_logger.info("Delete template from template table");
 +            // remove template from vm_templates table
 +            if (_tmpltDao.remove(template.getId())) {
 +                // Decrement the number of templates and total secondary storage
 +                // space used by the account
 +                Account account = _accountDao.findByIdIncludingRemoved(template.getAccountId());
 +                _resourceLimitMgr.decrementResourceCount(template.getAccountId(), ResourceType.template);
 +                _resourceLimitMgr.recalculateResourceCount(template.getAccountId(), account.getDomainId(),
 +                        ResourceType.secondary_storage.getOrdinal());
 +            }
 +        }
 +        return success;
  
 -			s_logger.debug("Removed template: " + template.getName() + " because all of its template host refs were marked as destroyed.");
 -		}
  
 -		return success;
  	}
  
 -	public TemplateProfile prepareDelete(DeleteTemplateCmd cmd) {
 +	@Override
 +    public TemplateProfile prepareDelete(DeleteTemplateCmd cmd) {
  		TemplateProfile profile = super.prepareDelete(cmd);
--		VMTemplateVO template = (VMTemplateVO)profile.getTemplate();
++		VMTemplateVO template = profile.getTemplate();
  		Long zoneId = profile.getZoneId();
  
  		if (template.getTemplateType() == TemplateType.SYSTEM) {
@@@ -301,4 -416,4 +311,63 @@@
  
  		return profile;
  	}
++
++    @Override
++    public TemplateProfile prepareExtractTemplate(ExtractTemplateCmd extractcmd) {
++             TemplateProfile profile = super.prepareExtractTemplate(extractcmd);
++             VMTemplateVO template = profile.getTemplate();
++             Long zoneId = profile.getZoneId();
++             Long templateId = template.getId();
++
++             if (template.getHypervisorType() == HypervisorType.VMware) {
++                PrepareOVAPackingCommand cmd = null;
++                String zoneName="";
++                List<HostVO> secondaryStorageHosts;
++                if (!template.isCrossZones() && zoneId != null) {
++                        DataCenterVO zone = _dcDao.findById(zoneId);
++                        zoneName = zone.getName();
++                List<DataStore> imageStores = this.storeMgr.getImageStoresByScope(new ZoneScope(profile.getZoneId()));
++                if (imageStores == null || imageStores.size() == 0) {
++                    throw new CloudRuntimeException("Unable to find image store to download template " + profile.getTemplate());
++                }
++
++                    s_logger.debug("Attempting to mark template host refs for template: " + template.getName() + " as destroyed in zone: " + zoneName);
++
++                // Make sure the template is downloaded to all the necessary secondary storage hosts
++
++                for (DataStore store : imageStores) {
++                    long storeId = store.getId();
++                    List<TemplateDataStoreVO> templateStoreVOs = _tmpltStoreDao.listByTemplateStore(templateId, storeId);
++                    for (TemplateDataStoreVO templateStoreVO : templateStoreVOs) {
++                        if (templateStoreVO.getDownloadState() == Status.DOWNLOAD_IN_PROGRESS) {
++                                 String errorMsg = "Please specify a template that is not currently being downloaded.";
++                            s_logger.debug("Template: " + template.getName() + " is currently being downloaded to secondary storage host: " + store.getName() + ".");
++                                 throw new CloudRuntimeException(errorMsg);
++                        }
++                        String installPath = templateStoreVO.getInstallPath();
++                        if (installPath != null) {
++                            EndPoint ep = _epSelector.select(store);
++                            if (ep == null) {
++                                s_logger.warn("prepareOVAPacking (hyervisorTemplateAdapter): There is no secondary storage VM for secondary storage host " + store.getName());
++                                 throw new CloudRuntimeException("PrepareExtractTemplate: can't locate ssvm for SecStorage Host.");
++                              }
++                           //Answer answer = _agentMgr.sendToSecStorage(secondaryStorageHost, new PrepareOVAPackingCommand(secondaryStorageHost.getStorageUrl(), installPath));
++                            cmd = new PrepareOVAPackingCommand(store.getUri(), installPath);
++                            cmd.setContextParam("hypervisor", HypervisorType.VMware.toString());
++                            Answer answer = ep.sendMessage(cmd);
++
++                                  if (answer == null || !answer.getResult()) {
++                                      s_logger.debug("Failed to create OVA for template " + templateStoreVO + " due to " + ((answer == null) ? "answer is null" : answer.getDetails()));
++                                      throw new CloudRuntimeException("PrepareExtractTemplate: Failed to create OVA for template extraction. ");
++                                  }
++                       }
++              }
++           }
++         }  else {
++            s_logger.debug("Failed to create OVA for template " + template + " due to zone non-existing.");
++                        throw new CloudRuntimeException("PrepareExtractTemplate: Failed to create OVA for template extraction. ");
++        }
++         }
++        return profile;
++        }
  }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/30479293/server/src/com/cloud/template/TemplateAdapter.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/template/TemplateAdapter.java
index 766afa8,9a2d877..54096fc
--- a/server/src/com/cloud/template/TemplateAdapter.java
+++ b/server/src/com/cloud/template/TemplateAdapter.java
@@@ -56,8 -57,10 +57,10 @@@ public interface TemplateAdapter extend
  
  	public TemplateProfile prepareDelete(DeleteIsoCmd cmd);
  
+ 	public TemplateProfile prepareExtractTemplate(ExtractTemplateCmd cmd);
+ 
  	public boolean delete(TemplateProfile profile);
 -	
 +
  	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,

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/30479293/server/src/com/cloud/template/TemplateAdapterBase.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/template/TemplateAdapterBase.java
index f65b364,0940d3e..aeea8b9
--- a/server/src/com/cloud/template/TemplateAdapterBase.java
+++ b/server/src/com/cloud/template/TemplateAdapterBase.java
@@@ -26,8 -26,10 +26,10 @@@ import org.apache.cloudstack.api.comman
  import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
  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.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;
@@@ -82,7 -85,8 +86,8 @@@ public abstract class TemplateAdapterBa
  	protected @Inject ResourceLimitService _resourceLimitMgr;
  	protected @Inject DataStoreManager storeMgr;
  	@Inject TemplateManager templateMgr;
- 
 -    @Inject ConfigurationServer _configServer;
++	@Inject ConfigurationServer _configServer;
+ 	
  	@Override
  	public boolean stop() {
  		return true;
@@@ -159,8 -171,8 +164,9 @@@
  		if (url.toLowerCase().contains("file://")) {
  			throw new InvalidParameterValueException("File:// type urls are currently unsupported");
  		}
 +
- 		boolean allowPublicUserTemplates = Boolean.parseBoolean(_configDao.getValue("allow.public.user.templates"));
+ 		// check whether owner can create public templates
+ 		boolean allowPublicUserTemplates = Boolean.parseBoolean(_configServer.getConfigValue(Config.AllowPublicUserTemplates.key(), Config.ConfigurationParameterScope.account.toString(), templateOwner.getId()));
  		if (!isAdmin && !allowPublicUserTemplates && isPublic) {
  			throw new InvalidParameterValueException("Only private templates/ISO can be created.");
  		}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/30479293/server/src/com/cloud/template/TemplateManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/template/TemplateManagerImpl.java
index 20cdce1,a8729e1..3a259eb
--- a/server/src/com/cloud/template/TemplateManagerImpl.java
+++ b/server/src/com/cloud/template/TemplateManagerImpl.java
@@@ -80,7 -75,13 +80,8 @@@ import com.cloud.agent.AgentManager
  import com.cloud.agent.api.Answer;
  import com.cloud.agent.api.AttachIsoCommand;
  import com.cloud.agent.api.ComputeChecksumCommand;
 -import com.cloud.agent.api.DownloadTemplateFromSwiftToSecondaryStorageCommand;
 -import com.cloud.agent.api.UploadTemplateToSwiftFromSecondaryStorageCommand;
 -import com.cloud.agent.api.storage.DestroyCommand;
 -import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
 -import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
 -import com.cloud.agent.api.to.SwiftTO;
+ 
 +import com.cloud.agent.api.storage.DestroyCommand;
  import com.cloud.api.ApiDBUtils;
  import com.cloud.async.AsyncJobManager;
  import com.cloud.async.AsyncJobVO;
@@@ -232,23 -241,26 +234,25 @@@ public class TemplateManagerImpl extend
      @Inject LaunchPermissionDao _launchPermissionDao;
      @Inject ProjectManager _projectMgr;
      @Inject
 -    VolumeDataFactory volFactory;
 +    VolumeDataFactory _volFactory;
      @Inject
 -    ImageDataFactory tmplFactory;
 +    TemplateDataFactory _tmplFactory;
      @Inject
 -    SnapshotDataFactory snapshotFactory;
 +    SnapshotDataFactory _snapshotFactory;
      @Inject
 -    ImageService imageSvr;
 +    TemplateService _tmpltSvr;
      @Inject
 -    DataStoreManager dataStoreMgr;
 +    DataStoreManager _dataStoreMgr;
      @Inject
      protected ResourceManager _resourceMgr;
 -    @Inject VolumeManager volumeMgr;
 -    @Inject VMTemplateHostDao templateHostDao;
 +    @Inject VolumeManager _volumeMgr;
 +    @Inject ImageStoreDao _imageStoreDao;
 +    @Inject EndPointSelector _epSelector;
 +
+     @Inject
+     ConfigurationServer _configServer;
  
 -    
      int _primaryStorageDownloadWait;
 -    protected SearchBuilder<VMTemplateHostVO> HostTemplateStatesSearch;
 -    
      int _storagePoolMaxWaitSeconds = 3600;
      boolean _disableExtraction = false;
      ExecutorService _preloadExecutor;
@@@ -261,10 -276,10 +265,10 @@@
      	if (type == HypervisorType.BareMetal) {
      		adapter = AdapterBase.getAdapterByName(_adapters, TemplateAdapterType.BareMetal.getName());
      	} else {
-     		// see HyervisorTemplateAdapter
+     		// see HypervisorTemplateAdapter
      		adapter =  AdapterBase.getAdapterByName(_adapters, TemplateAdapterType.Hypervisor.getName());
      	}
 -    	
 +
      	if (adapter == null) {
      		throw new CloudRuntimeException("Cannot find template adapter for " + type.toString());
      	}
@@@ -352,10 -367,17 +356,17 @@@
          String mode = cmd.getMode();
          Long eventId = cmd.getStartEventId();
  
+         VirtualMachineTemplate template = getTemplate(templateId);
+         if (template == null) {
+             throw new InvalidParameterValueException("unable to find template with id " + templateId);
+         }
+         TemplateAdapter adapter = getAdapter(template.getHypervisorType());
+         TemplateProfile profile = adapter.prepareExtractTemplate(cmd);
+ 
          // FIXME: async job needs fixing
 -        Long uploadId = extract(caller, templateId, url, zoneId, mode, eventId, false, null, _asyncMgr);
 -        if (uploadId != null){
 -        	return uploadId;
 +        Pair<Long, String> uploadPair = extract(caller, templateId, url, zoneId, mode, eventId, false, null, _asyncMgr);
 +        if (uploadPair != null){
 +        	return uploadPair;
          }else {
          	throw new CloudRuntimeException("Failed to extract the teamplate");
          }
@@@ -1353,7 -1732,7 +1365,6 @@@
              if (snapshotId != null) {
                  snapshot = _snapshotDao.findById(snapshotId);
                  zoneId = snapshot.getDataCenterId();
- 
 -                
              } else if (volumeId != null) {
                  volume = _volumeDao.findById(volumeId);
                  zoneId = volume.getDataCenterId();
@@@ -1363,14 -1742,13 +1374,13 @@@
              if (store.size() > 1) {
                  throw new CloudRuntimeException("muliple image data store, don't know which one to use");
              }
 -            AsyncCallFuture<CommandResult> future = null;
 +            AsyncCallFuture<TemplateApiResult> future = null;
              if (snapshotId != null) {
 -                SnapshotInfo snapInfo = this.snapshotFactory.getSnapshot(snapshotId);
 -                future = this.imageSvr.createTemplateFromSnapshotAsync(snapInfo, tmplInfo, store.get(0));
 +                SnapshotInfo snapInfo = this._snapshotFactory.getSnapshot(snapshotId, DataStoreRole.Image);
 +                future = this._tmpltSvr.createTemplateFromSnapshotAsync(snapInfo, tmplInfo, store.get(0));
              } else if (volumeId != null) {
-                volume = _volumeDao.findById(volumeId);
 -               VolumeInfo volInfo = this.volFactory.getVolume(volumeId);
 -               future = this.imageSvr.createTemplateFromVolumeAsync(volInfo, tmplInfo, store.get(0));
 +               VolumeInfo volInfo = this._volFactory.getVolume(volumeId);
 +               future = this._tmpltSvr.createTemplateFromVolumeAsync(volInfo, tmplInfo, store.get(0));
              } else {
                  throw new CloudRuntimeException(
                          "Creating private Template need to specify snapshotId or volumeId");

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/30479293/server/src/com/cloud/vm/UserVmManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/vm/UserVmManagerImpl.java
index 000430f,bc25bed..125e89c
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@@ -2251,6 -2279,10 +2274,10 @@@ public class UserVmManagerImpl extends 
  
          // check if account/domain is with in resource limits to create a new vm
          boolean isIso = Storage.ImageFormat.ISO == template.getFormat();
 -        long size = _templateHostDao.findByTemplateId(template.getId()).getSize();
++        long size = _templateDao.findById(template.getId()).getSize();
+         if (diskOfferingId != null) {
+             size += _diskOfferingDao.findById(diskOfferingId).getDiskSize();
+         }
          resourceLimitCheck(owner, new Long(offering.getCpu()), new Long(offering.getRamSize()));
          _resourceLimitMgr.checkResourceLimit(owner, ResourceType.volume, (isIso
                  || diskOfferingId == null ? 1 : 2));

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/30479293/server/src/com/cloud/vm/VirtualMachineManagerImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/30479293/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java
----------------------------------------------------------------------
diff --cc services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java
index 0000000,b904254..d239742
mode 000000,100644..100644
--- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java
+++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java
@@@ -1,0 -1,246 +1,248 @@@
+ // Licensed to the Apache Software Foundation (ASF) under one
+ // or more contributor license agreements.  See the NOTICE file
+ // distributed with this work for additional information
+ // regarding copyright ownership.  The ASF licenses this file
+ // to you under the Apache License, Version 2.0 (the
+ // "License"); you may not use this file except in compliance
+ // with the License.  You may obtain a copy of the License at
+ //
+ //   http://www.apache.org/licenses/LICENSE-2.0
+ //
+ // Unless required by applicable law or agreed to in writing,
+ // software distributed under the License is distributed on an
+ // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ // KIND, either express or implied.  See the License for the
+ // specific language governing permissions and limitations
+ // under the License.
+ package org.apache.cloudstack.storage.resource;
+ 
+ import java.util.HashMap;
+ import java.util.Map;
+ 
+ import javax.naming.ConfigurationException;
+ 
++import org.apache.log4j.Logger;
++
++import org.apache.cloudstack.storage.command.DownloadCommand;
++import org.apache.cloudstack.storage.command.DownloadProgressCommand;
+ import org.apache.cloudstack.storage.template.DownloadManager;
+ import org.apache.cloudstack.storage.template.DownloadManagerImpl;
 -import org.apache.log4j.Logger;
+ 
+ import com.cloud.agent.api.Answer;
+ import com.cloud.agent.api.CheckHealthAnswer;
+ import com.cloud.agent.api.CheckHealthCommand;
+ import com.cloud.agent.api.Command;
+ import com.cloud.agent.api.ComputeChecksumCommand;
+ import com.cloud.agent.api.PingCommand;
+ import com.cloud.agent.api.PingStorageCommand;
+ import com.cloud.agent.api.ReadyAnswer;
+ import com.cloud.agent.api.ReadyCommand;
+ import com.cloud.agent.api.SecStorageSetupCommand;
+ import com.cloud.agent.api.StartupCommand;
+ import com.cloud.agent.api.StartupStorageCommand;
 -import com.cloud.agent.api.storage.DownloadCommand;
 -import com.cloud.agent.api.storage.DownloadProgressCommand;
+ import com.cloud.agent.api.storage.ListTemplateAnswer;
+ import com.cloud.agent.api.storage.ListTemplateCommand;
+ import com.cloud.agent.api.storage.ssCommand;
++import com.cloud.agent.api.to.NfsTO;
+ import com.cloud.host.Host;
+ import com.cloud.host.Host.Type;
+ import com.cloud.resource.ServerResourceBase;
+ import com.cloud.storage.Storage;
+ import com.cloud.storage.Storage.StoragePoolType;
+ import com.cloud.storage.StorageLayer;
 -import com.cloud.storage.template.TemplateInfo;
++import com.cloud.storage.template.TemplateProp;
+ import com.cloud.utils.component.ComponentContext;
+ 
+ public class LocalSecondaryStorageResource extends ServerResourceBase implements SecondaryStorageResource {
+     private static final Logger s_logger = Logger.getLogger(LocalSecondaryStorageResource.class);
+     int _timeout;
+ 
+     String _instance;
+     String _parent;
+ 
+     String _dc;
+     String _pod;
+     String _guid;
+ 
+     StorageLayer _storage;
+ 
+     DownloadManager _dlMgr;
+ 
+     @Override
+     public void disconnected() {
+     }
+ 
+ 
+     @Override
+     public String getRootDir(ssCommand cmd){
+         return getRootDir();
+ 
+     }
+ 
+     public String getRootDir() {
+         return _parent;
+     }
+ 
+     @Override
+     public Answer executeRequest(Command cmd) {
+         if (cmd instanceof DownloadProgressCommand) {
+             return _dlMgr.handleDownloadCommand(this, (DownloadProgressCommand)cmd);
+         } else if (cmd instanceof DownloadCommand) {
+             return _dlMgr.handleDownloadCommand(this, (DownloadCommand)cmd);
+         } else if (cmd instanceof CheckHealthCommand) {
+             return new CheckHealthAnswer((CheckHealthCommand)cmd, true);
+         } else if (cmd instanceof SecStorageSetupCommand){
+             return new Answer(cmd, true, "success");
+         } else if (cmd instanceof ReadyCommand) {
+             return new ReadyAnswer((ReadyCommand)cmd);
+         } else if (cmd instanceof ListTemplateCommand){
 -            return execute((ListTemplateCommand)cmd);   
++            return execute((ListTemplateCommand)cmd);
+         } else if (cmd instanceof ComputeChecksumCommand){
+             return execute((ComputeChecksumCommand)cmd);
+         } else {
+             return Answer.createUnsupportedCommandAnswer(cmd);
+         }
+     }
+ 
+     private Answer execute(ComputeChecksumCommand cmd) {
 -        return new Answer(cmd, false, null);   
++        return new Answer(cmd, false, null);
+     }
+ 
+ 
+     private Answer execute(ListTemplateCommand cmd) {
+         String root = getRootDir();
 -        Map<String, TemplateInfo> templateInfos = _dlMgr.gatherTemplateInfo(root);
 -        return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos);
++        Map<String, TemplateProp> templateInfos = _dlMgr.gatherTemplateInfo(root);
++        return new ListTemplateAnswer(((NfsTO)cmd.getDataStore()).getUrl(), templateInfos);
+     }
+ 
+     @Override
+     public Type getType() {
+         return Host.Type.LocalSecondaryStorage;
+     }
+ 
+     @Override
+     public PingCommand getCurrentStatus(final long id) {
+         return new PingStorageCommand(Host.Type.Storage, id, new HashMap<String, Boolean>());
+     }
+ 
+ 
+     @Override
+     @SuppressWarnings("unchecked")
+     public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+         super.configure(name, params);
+ 
+         _guid = (String)params.get("guid");
+         if (_guid == null) {
+             throw new ConfigurationException("Unable to find the guid");
+         }
+ 
+         _dc = (String)params.get("zone");
+         if (_dc == null) {
+             throw new ConfigurationException("Unable to find the zone");
+         }
+         _pod = (String)params.get("pod");
+ 
+         _instance = (String)params.get("instance");
+ 
+         _parent = (String)params.get("mount.path");
+         if (_parent == null) {
+             throw new ConfigurationException("No directory specified.");
+         }
+ 
+         _storage = (StorageLayer)params.get(StorageLayer.InstanceConfigKey);
+         if (_storage == null) {
+             String value = (String)params.get(StorageLayer.ClassConfigKey);
+             if (value == null) {
+                 value = "com.cloud.storage.JavaStorageLayer";
+             }
+ 
+             try {
+                 Class<StorageLayer> clazz = (Class<StorageLayer>)Class.forName(value);
+                 _storage = ComponentContext.inject(clazz);
+             } catch (ClassNotFoundException e) {
+                 throw new ConfigurationException("Unable to find class " + value);
+             }
+         }
+ 
+         if (!_storage.mkdirs(_parent)) {
+             s_logger.warn("Unable to create the directory " + _parent);
+             throw new ConfigurationException("Unable to create the directory " + _parent);
+         }
+ 
+         s_logger.info("Mount point established at " + _parent);
+ 
+         params.put("template.parent", _parent);
+         params.put(StorageLayer.InstanceConfigKey, _storage);
+ 
+         _dlMgr = new DownloadManagerImpl();
+         _dlMgr.configure("DownloadManager", params);
+ 
+         return true;
+     }
+ 
+     @Override
+     public boolean start() {
+         return true;
+     }
+ 
+     @Override
+     public boolean stop() {
+         return true;
+     }
+ 
+     @Override
+     public StartupCommand[] initialize() {
+ 
+         final StartupStorageCommand cmd = new StartupStorageCommand(_parent, StoragePoolType.Filesystem, 1024l*1024l*1024l*1024l, _dlMgr.gatherTemplateInfo(_parent));
+         cmd.setResourceType(Storage.StorageResourceType.LOCAL_SECONDARY_STORAGE);
+         cmd.setIqn("local://");
+         fillNetworkInformation(cmd);
+         cmd.setDataCenter(_dc);
+         cmd.setPod(_pod);
+         cmd.setGuid(_guid);
+         cmd.setName(_guid);
+         cmd.setVersion(LocalSecondaryStorageResource.class.getPackage().getImplementationVersion());
+ 
+         return new StartupCommand [] {cmd};
+     }
+ 
+     @Override
+     protected String getDefaultScriptsDir() {
+         return "scripts/storage/secondary";
+     }
+ 
+ 
+ 	@Override
+ 	public void setName(String name) {
+ 		// TODO Auto-generated method stub
 -		
++
+ 	}
+ 
+ 
+ 	@Override
+ 	public void setConfigParams(Map<String, Object> params) {
+ 		// TODO Auto-generated method stub
 -		
++
+ 	}
+ 
+ 
+ 	@Override
+ 	public Map<String, Object> getConfigParams() {
+ 		// TODO Auto-generated method stub
+ 		return null;
+ 	}
+ 
+ 
+ 	@Override
+ 	public int getRunLevel() {
+ 		// TODO Auto-generated method stub
+ 		return 0;
+ 	}
+ 
+ 
+ 	@Override
+ 	public void setRunLevel(int level) {
+ 		// TODO Auto-generated method stub
 -		
++
+ 	}
+ }


Mime
View raw message