cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From edi...@apache.org
Subject [2/3] git commit: updated refs/heads/object_store to 1c448cd
Date Thu, 11 Apr 2013 18:01:50 GMT
add cache storage


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

Branch: refs/heads/object_store
Commit: e5bf38ed051df248e5aaa5e362679fbaf368d2e0
Parents: dcbeea0
Author: Edison Su <edison.su@citrix.com>
Authored: Wed Apr 10 23:36:39 2013 -0700
Committer: Edison Su <edison.su@citrix.com>
Committed: Thu Apr 11 10:52:53 2013 -0700

----------------------------------------------------------------------
 api/src/com/cloud/storage/StorageService.java      |    3 +
 .../command/admin/storage/CreateCacheStoreCmd.java |  123 +++
 .../subsystem/api/storage/DataMotionService.java   |   26 +
 .../subsystem/api/storage/DataMotionStrategy.java  |   28 +
 .../subsystem/api/storage/DataStoreManager.java    |    1 +
 .../subsystem/api/storage/DataStoreProvider.java   |    3 +-
 .../api/storage/DataStoreProviderManager.java      |    1 +
 .../subsystem/api/storage/StorageCacheManager.java |   24 +
 .../storage/datastore/db/ImageStoreVO.java         |   14 +
 engine/pom.xml                                     |    4 +-
 engine/storage/backup/pom.xml                      |   50 -
 .../storage/backup/BackupMotionService.java        |   23 -
 .../cloudstack/storage/backup/BackupService.java   |   26 -
 engine/storage/cache/pom.xml                       |   50 +
 .../cache/allocator/StorageCacheAllocator.java     |   26 +
 .../allocator/StorageCacheRandomAllocator.java     |   51 +
 .../cache/manager/StorageCacheManagerImpl.java     |  100 ++
 engine/storage/datamotion/pom.xml                  |   62 ++
 .../storage/motion/AncientDataMotionStrategy.java  |  726 +++++++++++++++
 .../storage/motion/DataMotionDriver.java           |   25 +
 .../storage/motion/DataMotionServiceImpl.java      |   63 ++
 .../manager/ImageStoreProviderManagerImpl.java     |   24 +
 engine/storage/imagemotion/pom.xml                 |   62 --
 .../image/motion/DefaultImageMotionStrategy.java   |  140 ---
 .../image/motion/ImageMotionServiceImpl.java       |   70 --
 .../storage/image/motion/ImageMotionStrategy.java  |   24 -
 .../storage/test/MockStorageMotionStrategy.java    |    2 +-
 .../snapshot/strategy/AncientSnapshotStrategy.java |   13 +-
 .../storage/datastore/DataObjectManagerImpl.java   |    2 +-
 .../storage/datastore/DataStoreManagerImpl.java    |    7 +-
 .../datastore/ObjectInDataStoreManagerImpl.java    |    4 -
 .../provider/DataStoreProviderManagerImpl.java     |   27 +-
 .../storage/image/datastore/ImageStoreHelper.java  |    3 +
 .../image/datastore/ImageStoreProviderManager.java |    1 +
 .../storage/motion/AncientDataMotionStrategy.java  |  725 --------------
 .../storage/motion/DataMotionDriver.java           |   25 -
 .../storage/motion/DataMotionService.java          |   28 -
 .../storage/motion/DataMotionServiceImpl.java      |   61 --
 .../storage/motion/DataMotionStrategy.java         |   30 -
 .../volume/TemplateInstallStrategyImpl.java        |    2 +-
 .../storage/volume/VolumeServiceImpl.java          |    3 +-
 .../provider/CloudStackImageStoreProviderImpl.java |    1 +
 .../src/com/cloud/storage/StorageManagerImpl.java  |   70 ++
 tools/apidoc/gen_toc.py                            |    1 +
 44 files changed, 1462 insertions(+), 1292 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/api/src/com/cloud/storage/StorageService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/storage/StorageService.java b/api/src/com/cloud/storage/StorageService.java
index ee1a956..869b296 100644
--- a/api/src/com/cloud/storage/StorageService.java
+++ b/api/src/com/cloud/storage/StorageService.java
@@ -20,6 +20,7 @@ import java.net.UnknownHostException;
 
 import org.apache.cloudstack.api.command.admin.storage.AddImageStoreCmd;
 import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaintenanceCmd;
+import org.apache.cloudstack.api.command.admin.storage.CreateCacheStoreCmd;
 import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd;
 import org.apache.cloudstack.api.command.admin.storage.DeleteImageStoreCmd;
 import org.apache.cloudstack.api.command.admin.storage.DeletePoolCmd;
@@ -47,6 +48,8 @@ public interface StorageService{
      */
     StoragePool createPool(CreateStoragePoolCmd cmd) throws ResourceInUseException, IllegalArgumentException,
     UnknownHostException, ResourceUnavailableException;
+    
+    ImageStore createCacheStore(CreateCacheStoreCmd cmd);
 
     /**
      * Delete the storage pool

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/api/src/org/apache/cloudstack/api/command/admin/storage/CreateCacheStoreCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/CreateCacheStoreCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/CreateCacheStoreCmd.java
new file mode 100644
index 0000000..ff01a40
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/admin/storage/CreateCacheStoreCmd.java
@@ -0,0 +1,123 @@
+/*
+ * 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.api.command.admin.storage;
+
+import java.util.Map;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.BaseCmd.CommandType;
+import org.apache.cloudstack.api.response.ImageStoreResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.log4j.Logger;
+
+import com.cloud.exception.DiscoveryException;
+import com.cloud.storage.ImageStore;
+import com.cloud.user.Account;
+
+@APICommand(name = "createCacheStore", description="create cache store.", responseObject=ImageStoreResponse.class)
+public class CreateCacheStoreCmd extends BaseCmd {
+    public static final Logger s_logger = Logger.getLogger(AddImageStoreCmd.class.getName());
+    private static final String s_name = "createcachestoreresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name=ApiConstants.URL, type=CommandType.STRING, required=true, description="the URL for the cache store")
+    private String url;
+
+    @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType=ZoneResponse.class,
+            description="the Zone ID for the image store")
+    private Long zoneId;
+
+
+    @Parameter(name=ApiConstants.DETAILS, type=CommandType.MAP, description="the details for the image store")
+    private Map<String, String> details;
+
+    @Parameter(name=ApiConstants.SCOPE, type=CommandType.STRING,
+            required=false, description="the scope of the image store: zone only for now")
+    private String scope;
+
+    @Parameter(name=ApiConstants.PROVIDER, type=CommandType.STRING,
+            required=false, description="the cache store provider name")
+    private String providerName;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getUrl() {
+        return url;
+    }
+
+    public Long getZoneId() {
+        return zoneId;
+    }
+
+     public Map<String, String> getDetails() {
+        return details;
+    }
+
+    public String getScope() {
+        return this.scope;
+     }
+
+    public String getProviderName() {
+        return this.providerName;
+    }
+
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        return Account.ACCOUNT_ID_SYSTEM;
+    }
+
+    @Override
+    public void execute(){
+        try{
+            ImageStore result = _storageService.createCacheStore(this);
+            ImageStoreResponse storeResponse = null;
+            if (result != null ) {
+                    storeResponse = _responseGenerator.createImageStoreResponse(result);
+                    storeResponse.setResponseName(getCommandName());
+                    storeResponse.setObjectName("secondarystorage");
+                    this.setResponseObject(storeResponse);
+            } else {
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add secondary storage");
+            }
+        } catch (Exception ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionService.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionService.java
new file mode 100644
index 0000000..adeeecb
--- /dev/null
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionService.java
@@ -0,0 +1,26 @@
+/*
+ * 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.engine.subsystem.api.storage;
+
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+
+public interface DataMotionService {
+    public void copyAsync(DataObject srcData, DataObject destData,
+            AsyncCompletionCallback<CopyCommandResult> callback);
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionStrategy.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionStrategy.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionStrategy.java
new file mode 100644
index 0000000..e2cc2a0
--- /dev/null
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionStrategy.java
@@ -0,0 +1,28 @@
+/*
+ * 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.engine.subsystem.api.storage;
+
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+
+public interface DataMotionStrategy {
+    public boolean canHandle(DataObject srcData, DataObject destData);
+
+    public Void copyAsync(DataObject srcData, DataObject destData,
+            AsyncCompletionCallback<CopyCommandResult> callback);
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreManager.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreManager.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreManager.java
index def3b96..1a36c8c 100644
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreManager.java
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreManager.java
@@ -28,5 +28,6 @@ public interface DataStoreManager {
     public DataStore getDataStore(String uuid, DataStoreRole role);
     public List<DataStore> getImageStoresByScope(ZoneScope scope);
     public List<DataStore> getImageStoresByProvider(String provider);
+    public List<DataStore> getImageCacheStores(Scope scope);
     public DataStore registerDataStore(Map<String, String> params, String providerUuid);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProvider.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProvider.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProvider.java
index 083c7d3..c0c1f76 100644
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProvider.java
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProvider.java
@@ -27,7 +27,8 @@ import java.util.Set;
 public interface DataStoreProvider {
     public static enum DataStoreProviderType {
         PRIMARY,
-        IMAGE
+        IMAGE,
+        ImageCache
     }
     public DataStoreLifeCycle getDataStoreLifeCycle();
     public DataStoreDriver getDataStoreDriver();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProviderManager.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProviderManager.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProviderManager.java
index 8dd8c3a..6872bdf 100644
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProviderManager.java
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProviderManager.java
@@ -27,6 +27,7 @@ public interface DataStoreProviderManager extends Manager, DataStoreProviderApiS
     public DataStoreProvider getDataStoreProvider(String name);
     public DataStoreProvider getDefaultPrimaryDataStoreProvider();
     public DataStoreProvider getDefaultImageDataStoreProvider();
+    public DataStoreProvider getDefaultCacheDataStoreProvider();
     public List<DataStoreProvider> getDataStoreProviders();
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageCacheManager.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageCacheManager.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageCacheManager.java
new file mode 100644
index 0000000..0fdec11
--- /dev/null
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageCacheManager.java
@@ -0,0 +1,24 @@
+/*
+ * 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.engine.subsystem.api.storage;
+
+
+public interface StorageCacheManager {
+    public DataStore getCacheStorage(Scope scope);
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreVO.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreVO.java
index 7f95036..5503df0 100644
--- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreVO.java
+++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreVO.java
@@ -28,6 +28,8 @@ import javax.persistence.Id;
 import javax.persistence.Table;
 import javax.persistence.TableGenerator;
 
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole;
+
 
 
 import com.cloud.storage.ImageStore;
@@ -69,6 +71,18 @@ public class ImageStoreVO implements ImageStore {
 
     @Column(name=GenericDao.REMOVED_COLUMN)
     private Date removed;
+    
+    @Column(name = "role")
+    @Enumerated(value = EnumType.STRING)
+    private DataStoreRole role;
+
+    public DataStoreRole getRole() {
+        return role;
+    }
+
+    public void setRole(DataStoreRole role) {
+        this.role = role;
+    }
 
     public long getId() {
         return this.id;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/pom.xml
----------------------------------------------------------------------
diff --git a/engine/pom.xml b/engine/pom.xml
index 1a3d896..3b686f2 100644
--- a/engine/pom.xml
+++ b/engine/pom.xml
@@ -39,8 +39,8 @@
     <module>storage</module>
     <module>storage/volume</module>
     <module>storage/image</module>
-    <module>storage/imagemotion</module>
-    <module>storage/backup</module>
+    <module>storage/datamotion</module>
+    <module>storage/cache</module>
     <module>storage/snapshot</module>
     <module>storage/integration-test</module>
     <module>components-api</module>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/storage/backup/pom.xml
----------------------------------------------------------------------
diff --git a/engine/storage/backup/pom.xml b/engine/storage/backup/pom.xml
deleted file mode 100644
index 019e09c..0000000
--- a/engine/storage/backup/pom.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<!-- 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. -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <artifactId>cloud-engine-storage-backup</artifactId>
-  <name>Apache CloudStack Engine Storage Backup Component</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloud-engine</artifactId>
-    <version>4.2.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>mysql</groupId>
-      <artifactId>mysql-connector-java</artifactId>
-      <version>${cs.mysql.version}</version>
-      <scope>provided</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.mockito</groupId>
-      <artifactId>mockito-all</artifactId>
-      <version>1.9.5</version>
-    </dependency>
-    <dependency>
-      <groupId>javax.inject</groupId>
-      <artifactId>javax.inject</artifactId>
-      <version>1</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <defaultGoal>install</defaultGoal>
-    <sourceDirectory>src</sourceDirectory>
-    <testSourceDirectory>test</testSourceDirectory>
-  </build>
-</project>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/storage/backup/src/org/apache/cloudstack/storage/backup/BackupMotionService.java
----------------------------------------------------------------------
diff --git a/engine/storage/backup/src/org/apache/cloudstack/storage/backup/BackupMotionService.java b/engine/storage/backup/src/org/apache/cloudstack/storage/backup/BackupMotionService.java
deleted file mode 100644
index cb49027..0000000
--- a/engine/storage/backup/src/org/apache/cloudstack/storage/backup/BackupMotionService.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.backup;
-
-public interface BackupMotionService {
-    boolean copySnapshot(String snapshotUri, String destSnapshotUri);
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/storage/backup/src/org/apache/cloudstack/storage/backup/BackupService.java
----------------------------------------------------------------------
diff --git a/engine/storage/backup/src/org/apache/cloudstack/storage/backup/BackupService.java b/engine/storage/backup/src/org/apache/cloudstack/storage/backup/BackupService.java
deleted file mode 100644
index 67924d2..0000000
--- a/engine/storage/backup/src/org/apache/cloudstack/storage/backup/BackupService.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.backup;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
-
-public interface BackupService {
-	public boolean backupSnapshot(SnapshotInfo snapshot, long backupStoreId);
-	public SnapshotOnBackupStoreInfo getSnapshot(long snapshotId);
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/storage/cache/pom.xml
----------------------------------------------------------------------
diff --git a/engine/storage/cache/pom.xml b/engine/storage/cache/pom.xml
new file mode 100644
index 0000000..f00f6cd
--- /dev/null
+++ b/engine/storage/cache/pom.xml
@@ -0,0 +1,50 @@
+<!-- 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. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>cloud-engine-storage-cache</artifactId>
+  <name>Apache CloudStack Engine Storage Cache Component</name>
+  <parent>
+    <groupId>org.apache.cloudstack</groupId>
+    <artifactId>cloud-engine</artifactId>
+    <version>4.2.0-SNAPSHOT</version>
+    <relativePath>../../pom.xml</relativePath>
+  </parent>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-engine-storage</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>mysql</groupId>
+      <artifactId>mysql-connector-java</artifactId>
+      <version>${cs.mysql.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-all</artifactId>
+      <version>1.9.5</version>
+    </dependency>
+    <dependency>
+      <groupId>javax.inject</groupId>
+      <artifactId>javax.inject</artifactId>
+      <version>1</version>
+    </dependency>
+  </dependencies>
+  <build>
+    <defaultGoal>install</defaultGoal>
+    <sourceDirectory>src</sourceDirectory>
+    <testSourceDirectory>test</testSourceDirectory>
+  </build>
+</project>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheAllocator.java
----------------------------------------------------------------------
diff --git a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheAllocator.java b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheAllocator.java
new file mode 100644
index 0000000..4259d9e
--- /dev/null
+++ b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheAllocator.java
@@ -0,0 +1,26 @@
+/*
+ * 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.cache.allocator;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
+
+public interface StorageCacheAllocator {
+    DataStore getCacheStore(Scope scope);
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java
----------------------------------------------------------------------
diff --git a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java
new file mode 100644
index 0000000..c357d23
--- /dev/null
+++ b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java
@@ -0,0 +1,51 @@
+/*
+ * 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.cache.allocator;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+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.Scope;
+
+import com.cloud.storage.ScopeType;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+import edu.emory.mathcs.backport.java.util.Collections;
+
+public class StorageCacheRandomAllocator implements StorageCacheAllocator {
+    @Inject
+    DataStoreManager dataStoreMgr;
+    @Override
+    public DataStore getCacheStore(Scope scope) {
+        if (scope.getScopeType() != ScopeType.ZONE) {
+            throw new CloudRuntimeException("Can only support zone wide cache storage");
+        }
+       
+        List<DataStore> cacheStores = dataStoreMgr.getImageCacheStores(scope);
+        if (cacheStores.size() <= 0) {
+            throw new CloudRuntimeException("Can't find cache storage in zone: " + scope.getScopeId());
+        }
+        
+        Collections.shuffle(cacheStores);
+        return cacheStores.get(0);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java
new file mode 100644
index 0000000..c85565d
--- /dev/null
+++ b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java
@@ -0,0 +1,100 @@
+/*
+ * 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.cache.manager;
+
+import java.util.List;
+import java.util.Map;
+
+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.Scope;
+import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager;
+import org.apache.cloudstack.storage.cache.allocator.StorageCacheAllocator;
+
+import com.cloud.utils.component.Manager;
+
+public class StorageCacheManagerImpl implements StorageCacheManager, Manager {
+    @Inject
+    List<StorageCacheAllocator> storageCacheAllocator;
+    @Override
+    public DataStore getCacheStorage(Scope scope) {
+        for (StorageCacheAllocator allocator : storageCacheAllocator) {
+            DataStore store = allocator.getCacheStore(scope);
+            if (store != null) {
+                return store;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public String getName() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @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
+        
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        // TODO Auto-generated method stub
+        return true;
+    }
+
+    @Override
+    public boolean start() {
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        // TODO Auto-generated method stub
+        return true;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/storage/datamotion/pom.xml
----------------------------------------------------------------------
diff --git a/engine/storage/datamotion/pom.xml b/engine/storage/datamotion/pom.xml
new file mode 100644
index 0000000..8a3698c
--- /dev/null
+++ b/engine/storage/datamotion/pom.xml
@@ -0,0 +1,62 @@
+<!-- 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. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>cloud-engine-storage-datamotion</artifactId>
+  <name>Apache CloudStack Engine Storage Data Motion Component</name>
+  <parent>
+    <groupId>org.apache.cloudstack</groupId>
+    <artifactId>cloud-engine</artifactId>
+    <version>4.2.0-SNAPSHOT</version>
+    <relativePath>../../pom.xml</relativePath>
+  </parent>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-engine-storage</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-engine-storage-volume</artifactId>
+      <version>${project.version}</version>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-engine-storage-image</artifactId>
+      <version>${project.version}</version>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>mysql</groupId>
+      <artifactId>mysql-connector-java</artifactId>
+      <version>${cs.mysql.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-all</artifactId>
+      <version>1.9.5</version>
+    </dependency>
+    <dependency>
+      <groupId>javax.inject</groupId>
+      <artifactId>javax.inject</artifactId>
+      <version>1</version>
+    </dependency>
+  </dependencies>
+  <build>
+    <defaultGoal>install</defaultGoal>
+    <sourceDirectory>src</sourceDirectory>
+    <testSourceDirectory>test</testSourceDirectory>
+  </build>
+</project>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
----------------------------------------------------------------------
diff --git a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
new file mode 100644
index 0000000..1d164cd
--- /dev/null
+++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
@@ -0,0 +1,726 @@
+/*
+ * 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.motion;
+
+import java.util.Date;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType;
+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.SnapshotInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.BackupSnapshotAnswer;
+import com.cloud.agent.api.BackupSnapshotCommand;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
+import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
+import com.cloud.agent.api.CreateVolumeFromSnapshotAnswer;
+import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
+import com.cloud.agent.api.UpgradeSnapshotCommand;
+import com.cloud.agent.api.storage.CopyVolumeAnswer;
+import com.cloud.agent.api.storage.CopyVolumeCommand;
+import com.cloud.agent.api.storage.CreateAnswer;
+import com.cloud.agent.api.storage.CreateCommand;
+import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer;
+import com.cloud.agent.api.to.S3TO;
+import com.cloud.agent.api.to.StorageFilerTO;
+import com.cloud.agent.api.to.SwiftTO;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.dao.ConfigurationDao;
+import com.cloud.exception.StorageUnavailableException;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.storage.DiskOfferingVO;
+import com.cloud.storage.SnapshotVO;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.StorageManager;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.VMTemplateHostVO;
+import com.cloud.storage.VMTemplateStoragePoolVO;
+import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.VolumeHostVO;
+import com.cloud.storage.VolumeManager;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.DiskOfferingDao;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VMTemplateHostDao;
+import com.cloud.storage.dao.VMTemplatePoolDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.storage.dao.VolumeHostDao;
+import com.cloud.storage.s3.S3Manager;
+import com.cloud.storage.snapshot.SnapshotManager;
+import com.cloud.storage.swift.SwiftManager;
+import com.cloud.template.TemplateManager;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.DiskProfile;
+
+@Component
+public class AncientDataMotionStrategy implements DataMotionStrategy {
+    private static final Logger s_logger = Logger
+            .getLogger(AncientDataMotionStrategy.class);
+    @Inject
+    TemplateManager templateMgr;
+    @Inject
+    VolumeHostDao volumeHostDao;
+    @Inject
+    HostDao hostDao;
+    @Inject
+    ConfigurationDao configDao;
+    @Inject
+    StorageManager storageMgr;
+    @Inject
+    VolumeDao volDao;
+    @Inject
+    VMTemplateDao templateDao;
+    @Inject
+    SnapshotManager snapshotMgr;
+    @Inject
+    SnapshotDao snapshotDao;
+    @Inject
+    PrimaryDataStoreDao primaryDataStoreDao;
+    @Inject
+    DataStoreManager dataStoreMgr;
+    @Inject
+    VMTemplateHostDao templateHostDao;
+    @Inject DiskOfferingDao diskOfferingDao;
+    @Inject VMTemplatePoolDao templatePoolDao;
+    @Inject
+    VolumeManager volumeMgr;
+    @Inject
+    private SwiftManager _swiftMgr;
+    @Inject 
+    private S3Manager _s3Mgr;
+
+    @Override
+    public boolean canHandle(DataObject srcData, DataObject destData) {
+        // TODO Auto-generated method stub
+        return true;
+    }
+
+    @DB
+    protected Answer copyVolumeFromImage(DataObject srcData, DataObject destData) {
+        String value = configDao.getValue(Config.RecreateSystemVmEnabled.key());
+        int _copyvolumewait = NumbersUtil.parseInt(value,
+                Integer.parseInt(Config.CopyVolumeWait.getDefaultValue()));
+
+        VolumeHostVO volumeHostVO = volumeHostDao.findByVolumeId(srcData
+                .getId());
+        HostVO secStorage = hostDao.findById(volumeHostVO.getHostId());
+        String secondaryStorageURL = secStorage.getStorageUrl();
+        String[] volumePath = volumeHostVO.getInstallPath().split("/");
+        String volumeUUID = volumePath[volumePath.length - 1].split("\\.")[0];
+        StoragePool destPool = (StoragePool) destData.getDataStore();
+        CopyVolumeCommand cvCmd = new CopyVolumeCommand(srcData.getId(),
+                volumeUUID, destPool, secondaryStorageURL, false,
+                _copyvolumewait);
+        CopyVolumeAnswer cvAnswer = null;
+        String errMsg = null;
+        try {
+            cvAnswer = (CopyVolumeAnswer) this.storageMgr.sendToPool(destPool,
+                    cvCmd);
+        } catch (StorageUnavailableException e1) {
+            s_logger.debug("Failed to copy volume " + srcData.getId() + " to "
+                    + destData.getId(), e1);
+            errMsg = e1.toString();
+        }
+
+        if (cvAnswer == null || !cvAnswer.getResult()) {
+            errMsg = cvAnswer.getDetails();
+        }
+
+        VolumeVO vol = this.volDao.findById(destData.getId());
+        Transaction txn = Transaction.currentTxn();
+        txn.start();
+        vol.setPath(cvAnswer.getVolumePath());
+        vol.setFolder(destPool.getPath());
+        vol.setPodId(destPool.getPodId());
+        vol.setPoolId(destPool.getId());
+        vol.setPodId(destPool.getPodId());
+
+        this.volDao.update(vol.getId(), vol);
+        volumeHostDao.remove(volumeHostVO.getId());
+        txn.commit();
+        return cvAnswer;
+    }
+
+    private Answer copyTemplate(DataObject srcData, DataObject destData) {
+        VMTemplateVO template = this.templateDao.findById(srcData.getId());
+        templateMgr.prepareTemplateForCreate(template,
+                (StoragePool) destData.getDataStore());
+        return null;
+    }
+
+    protected Answer copyFromSnapshot(DataObject snapObj, DataObject volObj) {
+        SnapshotVO snapshot = this.snapshotDao.findById(snapObj.getId());
+        StoragePool pool = (StoragePool) volObj.getDataStore();
+        String vdiUUID = null;
+        Long snapshotId = snapshot.getId();
+        Long volumeId = snapshot.getVolumeId();
+        Long dcId = snapshot.getDataCenterId();
+        String secondaryStoragePoolUrl = this.snapshotMgr
+                .getSecondaryStorageURL(snapshot);
+        long accountId = snapshot.getAccountId();
+
+        String backedUpSnapshotUuid = snapshot.getBackupSnapshotId();
+        snapshot = snapshotDao.findById(snapshotId);
+        if (snapshot.getVersion().trim().equals("2.1")) {
+            VolumeVO volume = this.volDao.findByIdIncludingRemoved(volumeId);
+            if (volume == null) {
+                throw new CloudRuntimeException("failed to upgrade snapshot "
+                        + snapshotId + " due to unable to find orignal volume:"
+                        + volumeId + ", try it later ");
+            }
+            if (volume.getTemplateId() == null) {
+                snapshotDao.updateSnapshotVersion(volumeId, "2.1", "2.2");
+            } else {
+                VMTemplateVO template = templateDao
+                        .findByIdIncludingRemoved(volume.getTemplateId());
+                if (template == null) {
+                    throw new CloudRuntimeException(
+                            "failed to upgrade snapshot "
+                                    + snapshotId
+                                    + " due to unalbe to find orignal template :"
+                                    + volume.getTemplateId()
+                                    + ", try it later ");
+                }
+                Long templateId = template.getId();
+                Long tmpltAccountId = template.getAccountId();
+                if (!snapshotDao.lockInLockTable(snapshotId.toString(), 10)) {
+                    throw new CloudRuntimeException(
+                            "failed to upgrade snapshot "
+                                    + snapshotId
+                                    + " due to this snapshot is being used, try it later ");
+                }
+                UpgradeSnapshotCommand cmd = new UpgradeSnapshotCommand(null,
+                        secondaryStoragePoolUrl, dcId, accountId, volumeId,
+                        templateId, tmpltAccountId, null,
+                        snapshot.getBackupSnapshotId(), snapshot.getName(),
+                        "2.1");
+                Answer answer = null;
+                try {
+                    answer = this.storageMgr.sendToPool(pool, cmd);
+                } catch (StorageUnavailableException e) {
+                } finally {
+                    snapshotDao.unlockFromLockTable(snapshotId.toString());
+                }
+                if ((answer != null) && answer.getResult()) {
+                    snapshotDao.updateSnapshotVersion(volumeId, "2.1", "2.2");
+                } else {
+                    throw new CloudRuntimeException("Unable to upgrade snapshot from 2.1 to 2.2 for "
+                            + snapshot.getId());
+                }
+            }
+        }
+        String basicErrMsg = "Failed to create volume from "
+                + snapshot.getName() + " on pool " + pool;
+
+        try {
+            if (snapshot.getSwiftId() != null && snapshot.getSwiftId() != 0) {
+                snapshotMgr.downloadSnapshotsFromSwift(snapshot);
+            } else if (snapshot.getS3Id() != null && snapshot.getS3Id() != 0) {
+                snapshotMgr.downloadSnapshotsFromS3(snapshot);
+            }
+            String value = configDao
+                    .getValue(Config.CreateVolumeFromSnapshotWait.toString());
+            int _createVolumeFromSnapshotWait = NumbersUtil.parseInt(value,
+                    Integer.parseInt(Config.CreateVolumeFromSnapshotWait
+                            .getDefaultValue()));
+            CreateVolumeFromSnapshotCommand createVolumeFromSnapshotCommand = new CreateVolumeFromSnapshotCommand(
+                    pool, secondaryStoragePoolUrl, dcId, accountId, volumeId,
+                    backedUpSnapshotUuid, snapshot.getName(),
+                    _createVolumeFromSnapshotWait);
+            CreateVolumeFromSnapshotAnswer answer;
+            if (!snapshotDao.lockInLockTable(snapshotId.toString(), 10)) {
+                throw new CloudRuntimeException("failed to create volume from "
+                        + snapshotId
+                        + " due to this snapshot is being used, try it later ");
+            }
+            answer = (CreateVolumeFromSnapshotAnswer) this.storageMgr
+                    .sendToPool(pool, createVolumeFromSnapshotCommand);
+            if (answer != null && answer.getResult()) {
+                vdiUUID = answer.getVdi();
+                VolumeVO vol = this.volDao.findById(volObj.getId());
+                vol.setPath(vdiUUID);
+                this.volDao.update(vol.getId(), vol);
+                return null;
+            } else {
+                s_logger.error(basicErrMsg + " due to "
+                        + ((answer == null) ? "null" : answer.getDetails()));
+                throw new CloudRuntimeException(basicErrMsg);
+            }
+        } catch (StorageUnavailableException e) {
+            s_logger.error(basicErrMsg, e);
+            throw new CloudRuntimeException(basicErrMsg);
+        } finally {
+            if (snapshot.getSwiftId() != null) {
+                snapshotMgr.deleteSnapshotsDirForVolume(
+                        secondaryStoragePoolUrl, dcId, accountId, volumeId);
+            }
+        }
+    }
+    
+    protected Answer cloneVolume(DataObject template, DataObject volume) {
+        VolumeInfo volInfo = (VolumeInfo)volume;
+        DiskOfferingVO offering = diskOfferingDao.findById(volInfo.getDiskOfferingId());
+        VMTemplateStoragePoolVO  tmpltStoredOn =  templatePoolDao.findByPoolTemplate(template.getDataStore().getId(), template.getId());
+        
+        DiskProfile diskProfile = new DiskProfile(volInfo, offering,
+                null);
+        CreateCommand cmd = new CreateCommand(diskProfile,
+                tmpltStoredOn.getLocalDownloadPath(),
+                new StorageFilerTO((StoragePool)template.getDataStore()));
+        Answer answer = null;
+        StoragePool pool = (StoragePool)volume.getDataStore();
+        String errMsg = null;
+        try {
+            answer = storageMgr.sendToPool(pool, null, cmd);
+        } catch (StorageUnavailableException e) {
+            s_logger.debug("Failed to send to storage pool", e);
+            throw new CloudRuntimeException("Failed to send to storage pool", e);
+        }
+        
+        if (answer.getResult()) {
+            VolumeVO vol = this.volDao.findById(volume.getId());
+            CreateAnswer createAnswer = (CreateAnswer) answer;
+            vol.setFolder(pool.getPath());
+            vol.setPath(createAnswer.getVolume().getPath());
+            vol.setSize(createAnswer.getVolume().getSize());
+            vol.setPoolType(pool.getPoolType());
+            vol.setPoolId(pool.getId());
+            vol.setPodId(pool.getPodId());
+            this.volDao.update(vol.getId(), vol);
+           
+        } else {
+            if (tmpltStoredOn != null
+                    && (answer instanceof CreateAnswer)
+                    && ((CreateAnswer) answer)
+                            .templateReloadRequested()) {
+                if (!templateMgr
+                        .resetTemplateDownloadStateOnPool(tmpltStoredOn
+                                .getId())) {
+                   
+                }
+            }
+            errMsg = answer.getDetails();
+        }
+        
+        return answer;
+    }
+    
+    protected Answer copyVolumeBetweenPools(DataObject srcData, DataObject destData) {
+        VolumeInfo volume = (VolumeInfo)srcData;
+        VolumeInfo destVolume = (VolumeInfo)destData;
+        String secondaryStorageURL = this.templateMgr.getSecondaryStorageURL(volume
+                .getDataCenterId());
+        StoragePool srcPool = (StoragePool)this.dataStoreMgr.getDataStore(volume
+                .getPoolId(), DataStoreRole.Primary);
+        
+        StoragePool destPool = (StoragePool)this.dataStoreMgr.getDataStore(destVolume.getPoolId(), DataStoreRole.Primary);
+        
+        String value = this.configDao.getValue(Config.CopyVolumeWait.toString());
+        int _copyvolumewait = NumbersUtil.parseInt(value,
+                Integer.parseInt(Config.CopyVolumeWait.getDefaultValue()));
+        CopyVolumeCommand cvCmd = new CopyVolumeCommand(volume.getId(),
+                volume.getPath(), srcPool, secondaryStorageURL, true,
+                _copyvolumewait);
+        CopyVolumeAnswer cvAnswer;
+        try {
+            cvAnswer = (CopyVolumeAnswer) this.storageMgr.sendToPool(srcPool, cvCmd);
+        } catch (StorageUnavailableException e1) {
+            throw new CloudRuntimeException(
+                    "Failed to copy the volume from the source primary storage pool to secondary storage.",
+                    e1);
+        }
+
+        if (cvAnswer == null || !cvAnswer.getResult()) {
+            throw new CloudRuntimeException(
+                    "Failed to copy the volume from the source primary storage pool to secondary storage.");
+        }
+
+        String secondaryStorageVolumePath = cvAnswer.getVolumePath();
+        
+        cvCmd = new CopyVolumeCommand(volume.getId(),
+                secondaryStorageVolumePath, destPool,
+                secondaryStorageURL, false, _copyvolumewait);
+        try {
+            cvAnswer = (CopyVolumeAnswer) this.storageMgr.sendToPool(destPool, cvCmd);
+        } catch (StorageUnavailableException e1) {
+            throw new CloudRuntimeException(
+                    "Failed to copy the volume from secondary storage to the destination primary storage pool.");
+        }
+
+        if (cvAnswer == null || !cvAnswer.getResult()) {
+            throw new CloudRuntimeException(
+                    "Failed to copy the volume from secondary storage to the destination primary storage pool.");
+        }
+        
+        VolumeVO destVol = this.volDao.findById(destVolume.getId());
+        destVol.setPath(cvAnswer.getVolumePath());
+        this.volDao.update(destVol.getId(), destVol);
+        return cvAnswer;
+    }
+
+    @Override
+    public Void copyAsync(DataObject srcData, DataObject destData,
+            AsyncCompletionCallback<CopyCommandResult> callback) {
+        Answer answer = null;
+        String errMsg = null;
+        try {
+            if (destData.getType() == DataObjectType.VOLUME
+                    && srcData.getType() == DataObjectType.VOLUME && srcData.getDataStore().getRole() == DataStoreRole.Image) {
+            	answer = copyVolumeFromImage(srcData, destData);
+            } else if (destData.getType() == DataObjectType.TEMPLATE
+                    && srcData.getType() == DataObjectType.TEMPLATE) {
+            	answer = copyTemplate(srcData, destData);
+            } else if (srcData.getType() == DataObjectType.SNAPSHOT
+                    && destData.getType() == DataObjectType.VOLUME) {
+            	answer = copyFromSnapshot(srcData, destData);
+            } else if (srcData.getType() == DataObjectType.SNAPSHOT
+                    && destData.getType() == DataObjectType.TEMPLATE) {
+            	answer = createTemplateFromSnashot(srcData, destData);
+            } else if (srcData.getType() == DataObjectType.VOLUME
+                    && destData.getType() == DataObjectType.TEMPLATE) {
+            	answer = createTemplateFromVolume(srcData, destData);
+            } else if (srcData.getType() == DataObjectType.TEMPLATE 
+                    && destData.getType() == DataObjectType.VOLUME) {
+            	answer = cloneVolume(srcData, destData);
+            } else if (destData.getType() == DataObjectType.VOLUME
+                    && srcData.getType() == DataObjectType.VOLUME && srcData.getDataStore().getRole() == DataStoreRole.Primary) {
+            	answer = copyVolumeBetweenPools(srcData, destData);
+            } else if (srcData.getType() == DataObjectType.SNAPSHOT &&
+            		destData.getType() == DataObjectType.SNAPSHOT) {
+            	answer = copySnapshot(srcData, destData);
+            }
+        } catch (Exception e) {
+            s_logger.debug("copy failed", e);
+            errMsg = e.toString();
+        }
+        CopyCommandResult result = new CopyCommandResult(null, answer);
+        result.setResult(errMsg);
+        callback.complete(result);
+
+        return null;
+    }
+
+    @DB
+    protected Answer createTemplateFromSnashot(DataObject srcData,
+            DataObject destData) {
+        long snapshotId = srcData.getId();
+        SnapshotVO snapshot = snapshotDao.findById(snapshotId);
+        if (snapshot == null) {
+            throw new CloudRuntimeException("Unable to find Snapshot for Id "
+                    + srcData.getId());
+        }
+        Long zoneId = snapshot.getDataCenterId();
+        HostVO secondaryStorageHost = this.templateMgr
+                .getSecondaryStorageHost(zoneId);
+        String secondaryStorageURL = snapshotMgr
+                .getSecondaryStorageURL(snapshot);
+        VMTemplateVO template = this.templateDao.findById(destData.getId());
+        String name = template.getName();
+        String backupSnapshotUUID = snapshot.getBackupSnapshotId();
+        if (backupSnapshotUUID == null) {
+            throw new CloudRuntimeException(
+                    "Unable to create private template from snapshot "
+                            + snapshotId
+                            + " due to there is no backupSnapshotUUID for this snapshot");
+        }
+
+        Long dcId = snapshot.getDataCenterId();
+        Long accountId = snapshot.getAccountId();
+        Long volumeId = snapshot.getVolumeId();
+
+        String origTemplateInstallPath = null;
+        List<StoragePoolVO> pools = this.storageMgr
+                .ListByDataCenterHypervisor(zoneId,
+                        snapshot.getHypervisorType());
+        if (pools == null || pools.size() == 0) {
+            throw new CloudRuntimeException(
+                    "Unable to find storage pools in zone " + zoneId);
+        }
+        StoragePoolVO poolvo = pools.get(0);
+        StoragePool pool = (StoragePool) this.dataStoreMgr.getDataStore(
+                poolvo.getId(), DataStoreRole.Primary);
+        if (snapshot.getVersion() != null
+                && snapshot.getVersion().equalsIgnoreCase("2.1")) {
+            VolumeVO volume = this.volDao.findByIdIncludingRemoved(volumeId);
+            if (volume == null) {
+                throw new CloudRuntimeException("failed to upgrade snapshot "
+                        + snapshotId + " due to unable to find orignal volume:"
+                        + volumeId + ", try it later ");
+            }
+            if (volume.getTemplateId() == null) {
+                snapshotDao.updateSnapshotVersion(volumeId, "2.1", "2.2");
+            } else {
+                template = templateDao.findByIdIncludingRemoved(volume
+                        .getTemplateId());
+                if (template == null) {
+                    throw new CloudRuntimeException(
+                            "failed to upgrade snapshot "
+                                    + snapshotId
+                                    + " due to unalbe to find orignal template :"
+                                    + volume.getTemplateId()
+                                    + ", try it later ");
+                }
+                Long origTemplateId = template.getId();
+                Long origTmpltAccountId = template.getAccountId();
+                if (!this.volDao.lockInLockTable(volumeId.toString(), 10)) {
+                    throw new CloudRuntimeException(
+                            "failed to upgrade snapshot " + snapshotId
+                                    + " due to volume:" + volumeId
+                                    + " is being used, try it later ");
+                }
+                UpgradeSnapshotCommand cmd = new UpgradeSnapshotCommand(null,
+                        secondaryStorageURL, dcId, accountId, volumeId,
+                        origTemplateId, origTmpltAccountId, null,
+                        snapshot.getBackupSnapshotId(), snapshot.getName(),
+                        "2.1");
+                if (!this.volDao.lockInLockTable(volumeId.toString(), 10)) {
+                    throw new CloudRuntimeException(
+                            "Creating template failed due to volume:"
+                                    + volumeId
+                                    + " is being used, try it later ");
+                }
+                Answer answer = null;
+                try {
+                    answer = this.storageMgr.sendToPool(pool, cmd);
+                    cmd = null;
+                } catch (StorageUnavailableException e) {
+                } finally {
+                    this.volDao.unlockFromLockTable(volumeId.toString());
+                }
+                if ((answer != null) && answer.getResult()) {
+                    snapshotDao.updateSnapshotVersion(volumeId, "2.1", "2.2");
+                } else {
+                    throw new CloudRuntimeException(
+                            "Unable to upgrade snapshot");
+                }
+            }
+        }
+        if (snapshot.getSwiftId() != null && snapshot.getSwiftId() != 0) {
+            snapshotMgr.downloadSnapshotsFromSwift(snapshot);
+        }
+        String value = configDao
+                .getValue(Config.CreatePrivateTemplateFromSnapshotWait
+                        .toString());
+        int _createprivatetemplatefromsnapshotwait = NumbersUtil.parseInt(
+                value, Integer
+                        .parseInt(Config.CreatePrivateTemplateFromSnapshotWait
+                                .getDefaultValue()));
+
+        CreatePrivateTemplateFromSnapshotCommand cmd = new CreatePrivateTemplateFromSnapshotCommand(
+                pool, secondaryStorageURL, dcId, accountId,
+                snapshot.getVolumeId(), backupSnapshotUUID, snapshot.getName(),
+                origTemplateInstallPath, template.getId(), name,
+                _createprivatetemplatefromsnapshotwait);
+
+        return sendCommand(cmd, pool, template.getId(), dcId,
+                secondaryStorageHost.getId());
+    }
+
+    @DB
+    protected Answer sendCommand(Command cmd, StoragePool pool,
+            long templateId, long zoneId, long hostId) {
+
+        CreatePrivateTemplateAnswer answer = null;
+        try {
+            answer = (CreatePrivateTemplateAnswer) this.storageMgr.sendToPool(
+                    pool, cmd);
+        } catch (StorageUnavailableException e) {
+            throw new CloudRuntimeException(
+                    "Failed to execute CreatePrivateTemplateFromSnapshotCommand",
+                    e);
+        }
+
+        if (answer == null || !answer.getResult()) {
+        	return answer;
+        }
+
+        VMTemplateVO privateTemplate = templateDao.findById(templateId);
+        String answerUniqueName = answer.getUniqueName();
+        if (answerUniqueName != null) {
+            privateTemplate.setUniqueName(answerUniqueName);
+        }
+        ImageFormat format = answer.getImageFormat();
+        if (format != null) {
+            privateTemplate.setFormat(format);
+        } else {
+            // This never occurs.
+            // Specify RAW format makes it unusable for snapshots.
+            privateTemplate.setFormat(ImageFormat.RAW);
+        }
+
+        String checkSum = this.templateMgr
+                .getChecksum(hostId, answer.getPath());
+
+        Transaction txn = Transaction.currentTxn();
+
+        txn.start();
+
+        privateTemplate.setChecksum(checkSum);
+        templateDao.update(privateTemplate.getId(), privateTemplate);
+
+        // add template zone ref for this template
+        templateDao.addTemplateToZone(privateTemplate, zoneId);
+        VMTemplateHostVO templateHostVO = new VMTemplateHostVO(hostId,
+                privateTemplate.getId());
+        templateHostVO.setDownloadPercent(100);
+        templateHostVO.setDownloadState(Status.DOWNLOADED);
+        templateHostVO.setInstallPath(answer.getPath());
+        templateHostVO.setLastUpdated(new Date());
+        templateHostVO.setSize(answer.getVirtualSize());
+        templateHostVO.setPhysicalSize(answer.getphysicalSize());
+        templateHostDao.persist(templateHostVO);
+        txn.close();
+        return answer;
+    }
+
+    private Answer createTemplateFromVolume(DataObject srcObj,
+            DataObject destObj) {
+        long volumeId = srcObj.getId();
+        VolumeVO volume = this.volDao.findById(volumeId);
+        if (volume == null) {
+            throw new CloudRuntimeException("Unable to find volume for Id "
+                    + volumeId);
+        }
+        long accountId = volume.getAccountId();
+
+        String vmName = this.volumeMgr.getVmNameOnVolume(volume);
+        Long zoneId = volume.getDataCenterId();
+        HostVO secondaryStorageHost = this.templateMgr
+                .getSecondaryStorageHost(zoneId);
+        if (secondaryStorageHost == null) {
+            throw new CloudRuntimeException(
+                    "Can not find the secondary storage for zoneId " + zoneId);
+        }
+        String secondaryStorageURL = secondaryStorageHost.getStorageUrl();
+        VMTemplateVO template = this.templateDao.findById(destObj.getId());
+        StoragePool pool = (StoragePool) this.dataStoreMgr.getDataStore(
+                volume.getPoolId(), DataStoreRole.Primary);
+        String value = configDao
+                .getValue(Config.CreatePrivateTemplateFromVolumeWait.toString());
+        int _createprivatetemplatefromvolumewait = NumbersUtil.parseInt(value,
+                Integer.parseInt(Config.CreatePrivateTemplateFromVolumeWait
+                        .getDefaultValue()));
+
+        CreatePrivateTemplateFromVolumeCommand cmd = new CreatePrivateTemplateFromVolumeCommand(
+                pool, secondaryStorageURL, destObj.getId(), accountId,
+                template.getName(), template.getUniqueName(), volume.getPath(),
+                vmName, _createprivatetemplatefromvolumewait);
+
+        return sendCommand(cmd, pool, template.getId(), zoneId,
+                secondaryStorageHost.getId());
+    }
+    
+    private HostVO getSecHost(long volumeId, long dcId) {
+        Long id = snapshotDao.getSecHostId(volumeId);
+        if ( id != null) { 
+            return hostDao.findById(id);
+        }
+        return this.templateMgr.getSecondaryStorageHost(dcId);
+    }
+    
+    protected Answer copySnapshot(DataObject srcObject, DataObject destObject) {
+    	SnapshotInfo srcSnapshot = (SnapshotInfo)srcObject;
+    	VolumeInfo baseVolume = srcSnapshot.getBaseVolume();
+    	 Long dcId = baseVolume.getDataCenterId();
+         Long accountId = baseVolume.getAccountId();
+         
+         HostVO secHost = getSecHost(baseVolume.getId(), baseVolume.getDataCenterId());
+         Long secHostId = secHost.getId();
+         String secondaryStoragePoolUrl = secHost.getStorageUrl();
+         String snapshotUuid = srcSnapshot.getPath();
+         // In order to verify that the snapshot is not empty,
+         // we check if the parent of the snapshot is not the same as the parent of the previous snapshot.
+         // We pass the uuid of the previous snapshot to the plugin to verify this.
+         SnapshotVO prevSnapshot = null;
+         String prevSnapshotUuid = null;
+         String prevBackupUuid = null;
+
+
+         SwiftTO swift = _swiftMgr.getSwiftTO();
+         S3TO s3 = _s3Mgr.getS3TO();
+         
+         long prevSnapshotId = srcSnapshot.getPrevSnapshotId();
+         if (prevSnapshotId > 0) {
+             prevSnapshot = snapshotDao.findByIdIncludingRemoved(prevSnapshotId);
+             if ( prevSnapshot.getBackupSnapshotId() != null && swift == null) {
+                 if (prevSnapshot.getVersion() != null && prevSnapshot.getVersion().equals("2.2")) {                   
+                     prevBackupUuid = prevSnapshot.getBackupSnapshotId();
+                     prevSnapshotUuid = prevSnapshot.getPath();
+                 }
+             } else if ((prevSnapshot.getSwiftId() != null && swift != null)
+                     || (prevSnapshot.getS3Id() != null && s3 != null)) {
+                 prevBackupUuid = prevSnapshot.getBackupSnapshotId();
+                 prevSnapshotUuid = prevSnapshot.getPath();
+             }
+         }
+         boolean isVolumeInactive = this.volumeMgr.volumeInactive(baseVolume);
+         String vmName = this.volumeMgr.getVmNameOnVolume(baseVolume);
+         StoragePool srcPool = (StoragePool)dataStoreMgr.getPrimaryDataStore(baseVolume.getPoolId());
+         String value = configDao.getValue(Config.BackupSnapshotWait.toString());
+         int _backupsnapshotwait = NumbersUtil.parseInt(value, Integer.parseInt(Config.BackupSnapshotWait.getDefaultValue()));
+         BackupSnapshotCommand backupSnapshotCommand = new BackupSnapshotCommand(secondaryStoragePoolUrl, dcId, accountId, baseVolume.getId(), srcSnapshot.getId(), secHostId, baseVolume.getPath(), srcPool, snapshotUuid,
+        		 srcSnapshot.getName(), prevSnapshotUuid, prevBackupUuid, isVolumeInactive, vmName, _backupsnapshotwait);
+
+         if ( swift != null ) {
+             backupSnapshotCommand.setSwift(swift);
+         } else if (s3 != null) {
+             backupSnapshotCommand.setS3(s3);
+         }
+         BackupSnapshotAnswer answer = (BackupSnapshotAnswer) this.snapshotMgr.sendToPool(baseVolume, backupSnapshotCommand);
+         if (answer != null && answer.getResult()) {
+        	 SnapshotVO snapshotVO = this.snapshotDao.findById(srcSnapshot.getId());
+        	 if (backupSnapshotCommand.getSwift() != null ) {
+        		 snapshotVO.setSwiftId(swift.getId());
+        		 snapshotVO.setBackupSnapshotId(answer.getBackupSnapshotName());
+        	 } else if (backupSnapshotCommand.getS3() != null) {
+        		 snapshotVO.setS3Id(s3.getId());
+        		 snapshotVO.setBackupSnapshotId(answer.getBackupSnapshotName());
+        	 } else {
+        		 snapshotVO.setSecHostId(secHost.getId());
+        		 snapshotVO.setBackupSnapshotId(answer.getBackupSnapshotName());
+        	 }
+ 			if (answer.isFull()) {
+ 				snapshotVO.setPrevSnapshotId(0L);
+			}
+        	 this.snapshotDao.update(srcSnapshot.getId(), snapshotVO);
+         }
+         return answer;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionDriver.java
----------------------------------------------------------------------
diff --git a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionDriver.java b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionDriver.java
new file mode 100644
index 0000000..3a59b21
--- /dev/null
+++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionDriver.java
@@ -0,0 +1,25 @@
+/*
+ * 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.motion;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
+
+public interface DataMotionDriver {
+    public void copy(DataObject srcObj, DataObject destObj);
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java
new file mode 100644
index 0000000..93ab412
--- /dev/null
+++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java
@@ -0,0 +1,63 @@
+/*
+ * 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.motion;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+import org.springframework.stereotype.Component;
+
+import com.cloud.utils.exception.CloudRuntimeException;
+
+@Component
+public class DataMotionServiceImpl implements DataMotionService {
+    @Inject
+    List<DataMotionStrategy> strategies;
+
+    @Override
+    public void copyAsync(DataObject srcData, DataObject destData,
+            AsyncCompletionCallback<CopyCommandResult> callback) {
+
+        if (srcData.getDataStore().getDriver().canCopy(srcData, destData)) {
+            srcData.getDataStore().getDriver()
+                    .copyAsync(srcData, destData, callback);
+            return;
+        } else if (destData.getDataStore().getDriver()
+                .canCopy(srcData, destData)) {
+            destData.getDataStore().getDriver()
+                    .copyAsync(srcData, destData, callback);
+            return;
+        }
+
+        for (DataMotionStrategy strategy : strategies) {
+            if (strategy.canHandle(srcData, destData)) {
+                strategy.copyAsync(srcData, destData, callback);
+                return;
+            }
+        }
+        throw new CloudRuntimeException("can't find strategy to move data");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageStoreProviderManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageStoreProviderManagerImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageStoreProviderManagerImpl.java
index dbcfb76..a1096d3 100644
--- a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageStoreProviderManagerImpl.java
+++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageStoreProviderManagerImpl.java
@@ -28,6 +28,7 @@ import javax.inject.Inject;
 
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole;
 import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider;
 import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
 import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
@@ -37,12 +38,18 @@ import org.apache.cloudstack.storage.image.ImageStoreDriver;
 import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
 import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager;
 import org.apache.cloudstack.storage.image.store.ImageStoreImpl;
+import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
+import com.cloud.storage.ScopeType;
 import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.SearchCriteria2;
+import com.cloud.utils.db.SearchCriteriaService;
 
 @Component
 public class ImageStoreProviderManagerImpl implements ImageStoreProviderManager {
+	private static final Logger s_logger = Logger.getLogger(ImageStoreProviderManagerImpl.class);
     @Inject
     ImageStoreDao dataStoreDao;
     @Inject
@@ -115,4 +122,21 @@ public class ImageStoreProviderManagerImpl implements ImageStoreProviderManager
 
 
 
+    @Override
+    public List<DataStore> listImageCacheStores(Scope scope) {
+        List<DataStore> imageStores = new ArrayList<DataStore>();
+        if (scope.getScopeType() != ScopeType.ZONE) {
+            s_logger.debug("only support zone wide image cache stores");
+            return imageStores;
+        }
+        SearchCriteriaService<ImageStoreVO, ImageStoreVO> sc = SearchCriteria2.create(ImageStoreVO.class);
+        sc.addAnd(sc.getEntity().getScope(), Op.EQ, ScopeType.ZONE);
+        sc.addAnd(sc.getEntity().getDataCenterId(), Op.EQ, scope.getScopeId());
+        sc.addAnd(sc.getEntity().getRole(), Op.EQ, DataStoreRole.ImageCache);
+        List<ImageStoreVO> cacheStores = sc.list();
+        for (ImageStoreVO store : cacheStores) {
+            imageStores.add(getImageStore(store.getId()));
+        }
+        return imageStores;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/storage/imagemotion/pom.xml
----------------------------------------------------------------------
diff --git a/engine/storage/imagemotion/pom.xml b/engine/storage/imagemotion/pom.xml
deleted file mode 100644
index 9a7f3e0..0000000
--- a/engine/storage/imagemotion/pom.xml
+++ /dev/null
@@ -1,62 +0,0 @@
-<!-- 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. -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <artifactId>cloud-engine-storage-imagemotion</artifactId>
-  <name>Apache CloudStack Engine Storage Image Motion Component</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloud-engine</artifactId>
-    <version>4.2.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-volume</artifactId>
-      <version>${project.version}</version>
-      <scope>runtime</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-image</artifactId>
-      <version>${project.version}</version>
-      <scope>runtime</scope>
-    </dependency>
-    <dependency>
-      <groupId>mysql</groupId>
-      <artifactId>mysql-connector-java</artifactId>
-      <version>${cs.mysql.version}</version>
-      <scope>provided</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.mockito</groupId>
-      <artifactId>mockito-all</artifactId>
-      <version>1.9.5</version>
-    </dependency>
-    <dependency>
-      <groupId>javax.inject</groupId>
-      <artifactId>javax.inject</artifactId>
-      <version>1</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <defaultGoal>install</defaultGoal>
-    <sourceDirectory>src</sourceDirectory>
-    <testSourceDirectory>test</testSourceDirectory>
-  </build>
-</project>


Mime
View raw message