You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ed...@apache.org on 2013/06/20 09:19:37 UTC

[04/50] [abbrv] git commit: updated refs/heads/master to 97f8c52

Move data store specific extract template/iso logic from
TemplateManager to data store driver.

Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/ef03d5a1
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/ef03d5a1
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/ef03d5a1

Branch: refs/heads/master
Commit: ef03d5a122ccce9ebd421f0060d5815ae532f3e2
Parents: 2473ceb
Author: Min Chen <mi...@citrix.com>
Authored: Tue Jun 4 11:50:43 2013 -0700
Committer: Min Chen <mi...@citrix.com>
Committed: Tue Jun 4 11:50:43 2013 -0700

----------------------------------------------------------------------
 .../com/cloud/template/TemplateApiService.java  |   8 +-
 .../cloudstack/api/ResponseGenerator.java       |   6 +-
 .../api/command/user/iso/ExtractIsoCmd.java     |  13 +--
 .../user/template/ExtractTemplateCmd.java       |  13 +--
 .../image/datastore/ImageStoreEntity.java       |   3 +
 .../storage/image/store/ImageStoreImpl.java     |   9 +-
 .../storage/image/ImageStoreDriver.java         |   4 +
 .../driver/CloudStackImageStoreDriverImpl.java  |  46 +++++++++
 .../driver/S3ImageStoreDriverImpl.java          |  27 +++++
 .../driver/SampleImageStoreDriverImpl.java      |   9 ++
 .../driver/SwiftImageStoreDriverImpl.java       |   7 ++
 server/src/com/cloud/api/ApiResponseHelper.java |  37 +++++--
 .../com/cloud/template/TemplateManagerImpl.java | 100 ++-----------------
 .../storage/template/DownloadManagerImpl.java   |  12 +--
 14 files changed, 156 insertions(+), 138 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ef03d5a1/api/src/com/cloud/template/TemplateApiService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/template/TemplateApiService.java b/api/src/com/cloud/template/TemplateApiService.java
index d907b10..26f3819 100755
--- a/api/src/com/cloud/template/TemplateApiService.java
+++ b/api/src/com/cloud/template/TemplateApiService.java
@@ -75,18 +75,18 @@ public interface TemplateApiService {
      *
      * @param cmd
      *            - the command specifying the mode and id of the ISO
-     * @return extractId.
+     * @return extractUrl extract url.
      */
-    Pair<Long, String> extract(ExtractIsoCmd cmd) throws InternalErrorException;
+    String extract(ExtractIsoCmd cmd) throws InternalErrorException;
 
     /**
      * Extracts a Template
      *
      * @param cmd
      *            - the command specifying the mode and id of the template
-     * @return extractId
+     * @return extractUrl  extract url
      */
-    Pair<Long, String> extract(ExtractTemplateCmd cmd) throws InternalErrorException;
+    String extract(ExtractTemplateCmd cmd) throws InternalErrorException;
 
     VirtualMachineTemplate getTemplate(long templateId);
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ef03d5a1/api/src/org/apache/cloudstack/api/ResponseGenerator.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/ResponseGenerator.java b/api/src/org/apache/cloudstack/api/ResponseGenerator.java
index 8cc9eaf..575a2ff 100644
--- a/api/src/org/apache/cloudstack/api/ResponseGenerator.java
+++ b/api/src/org/apache/cloudstack/api/ResponseGenerator.java
@@ -215,6 +215,8 @@ public interface ResponseGenerator {
 
     ExtractResponse createExtractResponse(Long uploadId, Long id, Long zoneId, Long accountId, String mode, String url);
 
+    ExtractResponse createExtractResponse(Long id, Long zoneId, Long accountId, String mode, String url);
+
     String toSerializedString(CreateCmdResponse response, String responseType);
 
     AsyncJobResponse createAsyncJobResponse(AsyncJob job);
@@ -360,7 +362,7 @@ public interface ResponseGenerator {
     public NicResponse createNicResponse(Nic result);
 
     ApplicationLoadBalancerResponse createLoadBalancerContainerReponse(ApplicationLoadBalancerRule lb, Map<Ip, UserVm> lbInstances);
-    
+
     AffinityGroupResponse createAffinityGroupResponse(AffinityGroup group);
 
     Long getAffinityGroupId(String name, long entityOwnerId);
@@ -370,7 +372,7 @@ public interface ResponseGenerator {
     PortableIpResponse createPortableIPResponse(PortableIp portableIp);
 
     InternalLoadBalancerElementResponse createInternalLbElementResponse(VirtualRouterProvider result);
-    
+
     IsolationMethodResponse createIsolationMethodResponse(IsolationType method);
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ef03d5a1/api/src/org/apache/cloudstack/api/command/user/iso/ExtractIsoCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/iso/ExtractIsoCmd.java b/api/src/org/apache/cloudstack/api/command/user/iso/ExtractIsoCmd.java
index c405f2d..dd0fc36 100644
--- a/api/src/org/apache/cloudstack/api/command/user/iso/ExtractIsoCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/iso/ExtractIsoCmd.java
@@ -124,16 +124,9 @@ public class ExtractIsoCmd extends BaseAsyncCmd {
     public void execute(){
         try {
             UserContext.current().setEventDetails(getEventDescription());
-            Pair<Long, String> uploadPair = _templateService.extract(this);
-            if (uploadPair != null){
-                ExtractResponse response = null;
-                if (uploadPair.second() != null ) {
-                    // region-wide image store
-                    response = _responseGenerator.createExtractResponse(null, id, zoneId, getEntityOwnerId(), mode, uploadPair.second());
-                } else {
-                    // nfs image store
-                    response = _responseGenerator.createExtractResponse(uploadPair.first(), id, zoneId, getEntityOwnerId(), mode, null);
-                }
+            String uploadUrl = _templateService.extract(this);
+            if (uploadUrl != null) {
+                ExtractResponse response = _responseGenerator.createExtractResponse(id, zoneId, getEntityOwnerId(), mode, uploadUrl);
                 response.setResponseName(getCommandName());
                 response.setObjectName("iso");
                 this.setResponseObject(response);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ef03d5a1/api/src/org/apache/cloudstack/api/command/user/template/ExtractTemplateCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/template/ExtractTemplateCmd.java b/api/src/org/apache/cloudstack/api/command/user/template/ExtractTemplateCmd.java
index 2ec957e..f2dc595 100644
--- a/api/src/org/apache/cloudstack/api/command/user/template/ExtractTemplateCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/template/ExtractTemplateCmd.java
@@ -126,16 +126,9 @@ public class ExtractTemplateCmd extends BaseAsyncCmd {
     public void execute(){
         try {
             UserContext.current().setEventDetails(getEventDescription());
-            Pair<Long, String> uploadPair = _templateService.extract(this);
-            if (uploadPair != null){
-                ExtractResponse response = null;
-                if (uploadPair.second() != null ) {
-                    // region-wide image store
-                    response = _responseGenerator.createExtractResponse(null, id, zoneId, getEntityOwnerId(), mode, uploadPair.second());
-                } else {
-                    // nfs image store
-                    response = _responseGenerator.createExtractResponse(uploadPair.first(), id, zoneId, getEntityOwnerId(), mode, null);
-                }
+            String uploadUrl = _templateService.extract(this);
+            if (uploadUrl != null) {
+                ExtractResponse response = _responseGenerator.createExtractResponse(id, zoneId, getEntityOwnerId(), mode, uploadUrl);
                 response.setResponseName(getCommandName());
                 this.setResponseObject(response);
             } else {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ef03d5a1/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java b/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java
index 636941c..90deff9 100644
--- a/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java
+++ b/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java
@@ -27,6 +27,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
 
 import com.cloud.storage.ImageStore;
+import com.cloud.storage.Storage.ImageFormat;
 
 public interface ImageStoreEntity extends DataStore, ImageStore {
     TemplateInfo getTemplate(long templateId);
@@ -40,4 +41,6 @@ public interface ImageStoreEntity extends DataStore, ImageStore {
     Set<TemplateInfo> listTemplates();
 
     String getMountPoint(); // get the mount point on ssvm.
+
+    String createEntityExtractUrl(String installPath, ImageFormat format);  // get the entity download URL
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ef03d5a1/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
index c6840d7..a3da304 100644
--- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
+++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
@@ -42,6 +42,7 @@ import org.apache.log4j.Logger;
 
 import com.cloud.agent.api.to.DataStoreTO;
 import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.Storage.ImageFormat;
 import com.cloud.storage.dao.VMTemplateDao;
 import com.cloud.utils.component.ComponentContext;
 
@@ -189,7 +190,13 @@ public class ImageStoreImpl implements ImageStoreEntity {
 
     @Override
     public String getMountPoint() {
-        return this.imageDataStoreVO.getParent();
+        return imageDataStoreVO.getParent();
     }
 
+    @Override
+    public String createEntityExtractUrl(String installPath, ImageFormat format) {
+        return driver.createEntityExtractUrl(this, installPath, format);
+    }
+
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ef03d5a1/engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.java b/engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.java
index 712e186..85a42ff 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.java
@@ -18,7 +18,11 @@
  */
 package org.apache.cloudstack.storage.image;
 
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
 
+import com.cloud.storage.Storage.ImageFormat;
+
 public interface ImageStoreDriver extends DataStoreDriver {
+    String createEntityExtractUrl(DataStore store, String installPath, ImageFormat format);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ef03d5a1/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java
----------------------------------------------------------------------
diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java
index 862af19..243017f 100644
--- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java
+++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java
@@ -21,6 +21,7 @@ package org.apache.cloudstack.storage.datastore.driver;
 import java.util.Date;
 import java.util.List;
 import java.util.Set;
+import java.util.UUID;
 
 import javax.inject.Inject;
 
@@ -40,6 +41,7 @@ import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
 import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
 import org.apache.cloudstack.storage.image.ImageStoreDriver;
+import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
 import org.apache.cloudstack.storage.image.store.ImageStoreImpl;
 import org.apache.cloudstack.storage.image.store.TemplateObject;
 import org.apache.cloudstack.storage.snapshot.SnapshotObject;
@@ -48,6 +50,7 @@ import org.apache.log4j.Logger;
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.DeleteSnapshotBackupCommand2;
+import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
 import com.cloud.agent.api.storage.DeleteTemplateCommand;
 import com.cloud.agent.api.storage.DeleteVolumeCommand;
 import com.cloud.agent.api.storage.DownloadAnswer;
@@ -55,12 +58,18 @@ import com.cloud.agent.api.to.DataObjectType;
 import com.cloud.agent.api.to.DataStoreTO;
 import com.cloud.agent.api.to.DataTO;
 import com.cloud.agent.api.to.NfsTO;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.dao.ConfigurationDao;
 import com.cloud.event.EventTypes;
 import com.cloud.event.UsageEventUtils;
 import com.cloud.host.dao.HostDao;
 import com.cloud.storage.DataStoreRole;
 import com.cloud.storage.SnapshotVO;
 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.VMTemplateStorageResourceAssoc;
 import com.cloud.storage.VMTemplateVO;
 import com.cloud.storage.VMTemplateZoneVO;
@@ -99,6 +108,8 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver {
     @Inject
     AccountDao _accountDao;
     @Inject
+    ConfigurationDao _configDao;
+    @Inject
     SecondaryStorageVmManager _ssvmMgr;
     @Inject
     TemplateDataStoreDao _templateStoreDao;
@@ -405,4 +416,39 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver {
 
     }
 
+    @Override
+    public String createEntityExtractUrl(DataStore store, String installPath, ImageFormat format) {
+        // find an endpoint to send command
+        EndPoint ep = _epSelector.select(store);
+        // Create Symlink at ssvm
+        String path = installPath;
+        String uuid = UUID.randomUUID().toString() + "." + format.getFileExtension();
+        CreateEntityDownloadURLCommand cmd = new CreateEntityDownloadURLCommand(((ImageStoreEntity) store).getMountPoint(), path, uuid);
+        Answer ans = ep.sendMessage(cmd);
+        if (ans == null || !ans.getResult()) {
+            String errorString = "Unable to create a link for entity at " + installPath + " on ssvm," + ans.getDetails();
+            s_logger.error(errorString);
+            throw new CloudRuntimeException(errorString);
+        }
+        // Construct actual URL locally now that the symlink exists at SSVM
+        return generateCopyUrl(ep.getPublicAddr(), uuid);
+    }
+
+    private String generateCopyUrl(String ipAddress, String uuid){
+
+        String hostname = ipAddress;
+        String scheme = "http";
+        boolean _sslCopy = false;
+        String sslCfg = _configDao.getValue(Config.SecStorageEncryptCopy.toString());
+        if ( sslCfg != null ){
+            _sslCopy = Boolean.parseBoolean(sslCfg);
+        }
+        if (_sslCopy) {
+            hostname = ipAddress.replace(".", "-");
+            hostname = hostname + ".realhostip.com";
+            scheme = "https";
+        }
+        return scheme + "://" + hostname + "/userdata/" + uuid;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ef03d5a1/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java
----------------------------------------------------------------------
diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java
index 6f50067..8cf4835 100644
--- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java
+++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java
@@ -48,6 +48,7 @@ import org.apache.cloudstack.storage.image.store.TemplateObject;
 import org.apache.cloudstack.storage.snapshot.SnapshotObject;
 import org.apache.log4j.Logger;
 
+import com.amazonaws.services.s3.model.CannedAccessControlList;
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.DeleteSnapshotBackupCommand2;
@@ -78,6 +79,7 @@ import com.cloud.storage.secondary.SecondaryStorageVmManager;
 import com.cloud.storage.snapshot.SnapshotManager;
 import com.cloud.user.Account;
 import com.cloud.user.dao.AccountDao;
+import com.cloud.utils.S3Utils;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.vm.dao.UserVmDao;
 
@@ -422,4 +424,29 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver {
 
     }
 
+    @Override
+    public String createEntityExtractUrl(DataStore store, String installPath, ImageFormat format) {
+        // for S3, no need to do anything, just return template url for
+        // extract template. but we need to set object acl as public_read to
+        // make the url accessible
+        S3TO s3 = (S3TO)getStoreTO(store);
+        String key = installPath;
+        try {
+            S3Utils.setObjectAcl(s3, s3.getBucketName(), key, CannedAccessControlList.PublicRead);
+        } catch (Exception ex) {
+            s_logger.error("Failed to set ACL on S3 object " + key + " to PUBLIC_READ", ex);
+            throw new CloudRuntimeException("Failed to set ACL on S3 object " + key + " to PUBLIC_READ");
+        }
+        // construct the url from s3
+        StringBuffer s3url = new StringBuffer();
+        s3url.append(s3.isHttps() ? "https://" : "http://");
+        s3url.append(s3.getEndPoint());
+        s3url.append("/");
+        s3url.append(s3.getBucketName());
+        s3url.append("/");
+        s3url.append(key);
+        return s3url.toString();
+    }
+
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ef03d5a1/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java
----------------------------------------------------------------------
diff --git a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java
index 27e6081..abc8741 100644
--- a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java
+++ b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java
@@ -37,6 +37,7 @@ import org.apache.cloudstack.storage.image.ImageStoreDriver;
 import com.cloud.agent.api.to.DataObjectType;
 import com.cloud.agent.api.to.DataStoreTO;
 import com.cloud.agent.api.to.DataTO;
+import com.cloud.storage.Storage.ImageFormat;
 import com.cloud.storage.dao.VMTemplateDao;
 
 //http-read-only based image store
@@ -134,4 +135,12 @@ public class SampleImageStoreDriverImpl implements ImageStoreDriver {
         // TODO Auto-generated method stub
 
     }
+
+    @Override
+    public String createEntityExtractUrl(DataStore store, String installPath, ImageFormat format) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ef03d5a1/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java
----------------------------------------------------------------------
diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java
index e5d40d1..bd48c44 100644
--- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java
+++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java
@@ -61,6 +61,7 @@ import com.cloud.agent.api.to.SwiftTO;
 import com.cloud.api.query.dao.UserVmJoinDao;
 import com.cloud.event.EventTypes;
 import com.cloud.event.UsageEventUtils;
+import com.cloud.exception.UnsupportedServiceException;
 import com.cloud.host.dao.HostDao;
 import com.cloud.storage.Storage.ImageFormat;
 import com.cloud.storage.DataStoreRole;
@@ -424,4 +425,10 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver {
 
     }
 
+    @Override
+    public String createEntityExtractUrl(DataStore store, String installPath, ImageFormat format) {
+        throw new UnsupportedServiceException("Extract entity url is not yet supported for Swift image store provider");
+    }
+
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ef03d5a1/server/src/com/cloud/api/ApiResponseHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java
index 1cb425a..310b353 100755
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -16,9 +16,6 @@
 // under the License.
 package com.cloud.api;
 
-import static java.util.Collections.emptyList;
-import static java.util.Collections.singletonList;
-
 import java.text.DecimalFormat;
 import java.util.ArrayList;
 import java.util.Calendar;
@@ -40,7 +37,6 @@ import org.apache.cloudstack.affinity.AffinityGroup;
 import org.apache.cloudstack.affinity.AffinityGroupResponse;
 import org.apache.cloudstack.api.ApiConstants.HostDetails;
 import org.apache.cloudstack.api.ApiConstants.VMDetails;
-import org.apache.cloudstack.api.BaseCmd;
 import org.apache.cloudstack.api.ResponseGenerator;
 import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd;
 import org.apache.cloudstack.api.response.AccountResponse;
@@ -184,7 +180,6 @@ import com.cloud.configuration.ResourceLimit;
 import com.cloud.dao.EntityManager;
 import com.cloud.dc.ClusterVO;
 import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenterVO;
 import com.cloud.dc.HostPodVO;
 import com.cloud.dc.Pod;
 import com.cloud.dc.StorageNetworkIpRange;
@@ -266,16 +261,10 @@ import com.cloud.storage.S3;
 import com.cloud.storage.Snapshot;
 import com.cloud.storage.SnapshotVO;
 import com.cloud.storage.Upload;
-import com.cloud.storage.Storage.ImageFormat;
 import com.cloud.storage.Storage.StoragePoolType;
-import com.cloud.storage.Storage.TemplateType;
 import com.cloud.storage.StoragePool;
 import com.cloud.storage.Swift;
 import com.cloud.storage.UploadVO;
-import com.cloud.storage.VMTemplateHostVO;
-import com.cloud.storage.VMTemplateS3VO;
-import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
-import com.cloud.storage.VMTemplateSwiftVO;
 import com.cloud.storage.VMTemplateVO;
 import com.cloud.storage.Volume;
 import com.cloud.storage.VolumeVO;
@@ -1601,6 +1590,29 @@ public class ApiResponseHelper implements ResponseGenerator {
         return listSgs.get(0);
     }
 
+    //TODO: we need to deprecate uploadVO, since extract is done in a synchronous fashion
+    @Override
+    public ExtractResponse createExtractResponse(Long id, Long zoneId, Long accountId, String mode, String url) {
+
+        ExtractResponse response = new ExtractResponse();
+        response.setObjectName("template");
+        VMTemplateVO template = ApiDBUtils.findTemplateById(id);
+        response.setId(template.getUuid());
+        response.setName(template.getName());
+        if (zoneId != null) {
+            DataCenter zone = ApiDBUtils.findZoneById(zoneId);
+            response.setZoneId(zone.getUuid());
+            response.setZoneName(zone.getName());
+        }
+        response.setMode(mode);
+            response.setUrl(url);
+            response.setState(Upload.Status.DOWNLOAD_URL_CREATED.toString());
+        Account account = ApiDBUtils.findAccountById(accountId);
+        response.setAccountId(account.getUuid());
+
+        return response;
+    }
+
     @Override
     public ExtractResponse createExtractResponse(Long uploadId, Long id, Long zoneId, Long accountId, String mode, String url) {
 
@@ -3480,6 +3492,7 @@ public class ApiResponseHelper implements ResponseGenerator {
         return response;
     }
 
+    @Override
     public NicSecondaryIpResponse createSecondaryIPToNicResponse(NicSecondaryIp result) {
         NicSecondaryIpResponse response = new NicSecondaryIpResponse();
         NicVO nic = _entityMgr.findById(NicVO.class, result.getNicId());
@@ -3492,6 +3505,7 @@ public class ApiResponseHelper implements ResponseGenerator {
         return response;
     }
 
+    @Override
     public NicResponse createNicResponse(Nic result) {
         NicResponse response = new NicResponse();
         NetworkVO network = _entityMgr.findById(NetworkVO.class, result.getNetworkId());
@@ -3713,6 +3727,7 @@ public class ApiResponseHelper implements ResponseGenerator {
     }
 
 
+    @Override
     public NetworkACLResponse createNetworkACLResponse(NetworkACL networkACL) {
         NetworkACLResponse response = new NetworkACLResponse();
         response.setId(networkACL.getUuid());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ef03d5a1/server/src/com/cloud/template/TemplateManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java
index 94193d5..b39936f 100755
--- a/server/src/com/cloud/template/TemplateManagerImpl.java
+++ b/server/src/com/cloud/template/TemplateManagerImpl.java
@@ -384,7 +384,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
 
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_ISO_EXTRACT, eventDescription = "extracting ISO", async = true)
-    public Pair<Long, String> extract(ExtractIsoCmd cmd) {
+    public String extract(ExtractIsoCmd cmd) {
         Account account = UserContext.current().getCaller();
         Long templateId = cmd.getId();
         Long zoneId = cmd.getZoneId();
@@ -392,18 +392,12 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
         String mode = cmd.getMode();
         Long eventId = cmd.getStartEventId();
 
-        // FIXME: async job needs fixing
-        Pair<Long, String> uploadPair = extract(account, templateId, url, zoneId, mode, eventId, true, null, _asyncMgr);
-        if (uploadPair != null) {
-            return uploadPair;
-        } else {
-            throw new CloudRuntimeException("Failed to extract the iso");
-        }
+        return extract(account, templateId, url, zoneId, mode, eventId, true);
     }
 
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_EXTRACT, eventDescription = "extracting template", async = true)
-    public Pair<Long, String> extract(ExtractTemplateCmd cmd) {
+    public String extract(ExtractTemplateCmd cmd) {
         Account caller = UserContext.current().getCaller();
         Long templateId = cmd.getId();
         Long zoneId = cmd.getZoneId();
@@ -418,13 +412,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
         TemplateAdapter adapter = getAdapter(template.getHypervisorType());
         TemplateProfile profile = adapter.prepareExtractTemplate(cmd);
 
-        // FIXME: async job needs fixing
-        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");
-        }
+        return extract(caller, templateId, url, zoneId, mode, eventId, false);
     }
 
     @Override
@@ -440,8 +428,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
         return vmTemplate;
     }
 
-    private Pair<Long, String> extract(Account caller, Long templateId, String url, Long zoneId, String mode, Long eventId, boolean isISO,
-            AsyncJobVO job, AsyncJobManager mgr) {
+    private String extract(Account caller, Long templateId, String url, Long zoneId, String mode, Long eventId, boolean isISO) {
         String desc = Upload.Type.TEMPLATE.toString();
         if (isISO) {
             desc = Upload.Type.ISO.toString();
@@ -505,82 +492,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
             throw new InvalidParameterValueException("The " + desc + " has not been downloaded ");
         }
 
-        if (tmpltStore.getProviderName().equalsIgnoreCase("Swift")) {
-            throw new UnsupportedServiceException("ExtractTemplate is not yet supported for Swift image store provider");
-        }
-
-        if (tmpltStore.getProviderName().equalsIgnoreCase("S3")) {
-            // for S3, no need to do anything, just return template url for
-            // extract template. but we need to set object acl as public_read to
-            // make the url accessible
-            S3TO s3 = (S3TO) tmpltStore.getTO();
-            String key = tmpltStoreRef.getLocalDownloadPath();
-            try {
-                S3Utils.setObjectAcl(s3, s3.getBucketName(), key, CannedAccessControlList.PublicRead);
-            } catch (Exception ex) {
-                s_logger.error("Failed to set ACL on S3 object " + key + " to PUBLIC_READ", ex);
-                throw new CloudRuntimeException("Failed to set ACL on S3 object " + key + " to PUBLIC_READ");
-            }
-            // construct the url from s3
-            StringBuffer s3url = new StringBuffer();
-            s3url.append(s3.isHttps() ? "https://" : "http://");
-            s3url.append(s3.getEndPoint());
-            s3url.append("/");
-            s3url.append(s3.getBucketName());
-            s3url.append("/");
-            s3url.append(key);
-
-            return new Pair<Long, String>(null, s3url.toString());
-        }
-
-        // for NFS image store case, control will come here
-        Upload.Mode extractMode;
-        if (mode == null
-                || (!mode.equalsIgnoreCase(Upload.Mode.FTP_UPLOAD.toString()) && !mode.equalsIgnoreCase(Upload.Mode.HTTP_DOWNLOAD.toString()))) {
-            throw new InvalidParameterValueException("Please specify a valid extract Mode. Supported modes: " + Upload.Mode.FTP_UPLOAD + ", "
-                    + Upload.Mode.HTTP_DOWNLOAD);
-        } else {
-            extractMode = mode.equalsIgnoreCase(Upload.Mode.FTP_UPLOAD.toString()) ? Upload.Mode.FTP_UPLOAD : Upload.Mode.HTTP_DOWNLOAD;
-        }
-
-        if (extractMode == Upload.Mode.FTP_UPLOAD) {
-            URI uri = null;
-            try {
-                uri = new URI(url);
-                if ((uri.getScheme() == null) || (!uri.getScheme().equalsIgnoreCase("ftp"))) {
-                    throw new InvalidParameterValueException("Unsupported scheme for url: " + url);
-                }
-            } catch (Exception ex) {
-                throw new InvalidParameterValueException("Invalid url given: " + url);
-            }
-
-            String host = uri.getHost();
-            try {
-                InetAddress hostAddr = InetAddress.getByName(host);
-                if (hostAddr.isAnyLocalAddress() || hostAddr.isLinkLocalAddress() || hostAddr.isLoopbackAddress() || hostAddr.isMulticastAddress()) {
-                    throw new InvalidParameterValueException("Illegal host specified in url");
-                }
-                if (hostAddr instanceof Inet6Address) {
-                    throw new InvalidParameterValueException("IPV6 addresses not supported (" + hostAddr.getHostAddress() + ")");
-                }
-            } catch (UnknownHostException uhe) {
-                throw new InvalidParameterValueException("Unable to resolve " + host);
-            }
-
-            if (_uploadMonitor.isTypeUploadInProgress(templateId, isISO ? Type.ISO : Type.TEMPLATE)) {
-                throw new IllegalArgumentException(template.getName()
-                        + " upload is in progress. Please wait for some time to schedule another upload for the same");
-            }
-
-            return new Pair<Long, String>(_uploadMonitor.extractTemplate(template, url, tmpltStoreRef, zoneId, eventId, job.getId(), mgr), null);
-        }
-
-        UploadVO vo = _uploadMonitor.createEntityDownloadURL(template, tmpltStoreRef, zoneId, eventId);
-        if (vo != null) {
-            return new Pair<Long, String>(vo.getId(), null);
-        } else {
-            return null;
-        }
+        return tmpltStore.createEntityExtractUrl(tmpltStoreRef.getInstallPath(), template.getFormat());
     }
 
     public void prepareTemplateInAllStoragePools(final VMTemplateVO template, long zoneId) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ef03d5a1/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java b/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
index 81ddd67..bf68b29 100755
--- a/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
+++ b/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
@@ -305,12 +305,12 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager
                 // status to trigger callback.
                 td.setStatus(Status.POST_DOWNLOAD_FINISHED);
                 // set template size for S3
-                if (td instanceof S3TemplateDownloader){
-                    long size = ((S3TemplateDownloader)td).totalBytes;
-                    DownloadJob dnld = jobs.get(jobId);
-                    dnld.setTemplatesize(size);
-                    dnld.setTemplatePhysicalSize(size);
-                }
+                S3TemplateDownloader std = (S3TemplateDownloader) td;
+                long size = std.totalBytes;
+                DownloadJob dnld = jobs.get(jobId);
+                dnld.setTemplatesize(size);
+                dnld.setTemplatePhysicalSize(size);
+                dnld.setTmpltPath(std.getDownloadLocalPath()); // update template path to include file name.
             }
             dj.cleanup();
             break;