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/01/15 03:57:10 UTC

[2/7] refactor api, based on suggestion from community

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8af85b04/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/DefaultPrimaryDataStoreDriverImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/DefaultPrimaryDataStoreDriverImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/DefaultPrimaryDataStoreDriverImpl.java
index 2855d4e..10b3713 100644
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/DefaultPrimaryDataStoreDriverImpl.java
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/DefaultPrimaryDataStoreDriverImpl.java
@@ -17,29 +17,27 @@
 package org.apache.cloudstack.storage.datastore.driver;
 
 import java.util.List;
-import java.util.Map;
+import java.util.Set;
 
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
 import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
 import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
 import org.apache.cloudstack.framework.async.AsyncRpcConext;
-import org.apache.cloudstack.storage.EndPoint;
-import org.apache.cloudstack.storage.command.CommandResult;
 import org.apache.cloudstack.storage.command.CreateVolumeAnswer;
 import org.apache.cloudstack.storage.command.CreateVolumeCommand;
-import org.apache.cloudstack.storage.command.CreateVolumeFromBaseImageCommand;
-import org.apache.cloudstack.storage.command.DeleteVolumeCommand;
+import org.apache.cloudstack.storage.command.DeleteCommand;
 import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
-import org.apache.cloudstack.storage.to.ImageOnPrimayDataStoreTO;
-import org.apache.cloudstack.storage.to.VolumeTO;
-import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo;
-import org.apache.cloudstack.storage.volume.VolumeObject;
+import org.apache.cloudstack.storage.snapshot.SnapshotInfo;
+import org.apache.cloudstack.storage.volume.PrimaryDataStoreDriver;
 import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
 
 import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.utils.exception.CloudRuntimeException;
+
 
 public class DefaultPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver {
     private static final Logger s_logger = Logger.getLogger(DefaultPrimaryDataStoreDriverImpl.class);
@@ -52,48 +50,28 @@ public class DefaultPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
         
     }
     
-    @Override
-    public void setDataStore(PrimaryDataStore dataStore) {
-        this.dataStore = dataStore;
-    }
-    
     private class CreateVolumeContext<T> extends AsyncRpcConext<T> {
-        private final VolumeObject volume;
+        private final DataObject volume;
         /**
          * @param callback
          */
-        public CreateVolumeContext(AsyncCompletionCallback<T> callback, VolumeObject volume) {
+        public CreateVolumeContext(AsyncCompletionCallback<T> callback, DataObject volume) {
             super(callback);
             this.volume = volume;
         }
         
-        public VolumeObject getVolume() {
+        public DataObject getVolume() {
             return this.volume;
         }
         
     }
     
-    @Override
-    public void createVolumeAsync(VolumeObject vol, AsyncCompletionCallback<CommandResult> callback) {
-        List<EndPoint> endPoints = vol.getDataStore().getEndPoints();
-        EndPoint ep = endPoints.get(0);
-        VolumeInfo volInfo = vol;
-        CreateVolumeCommand createCmd = new CreateVolumeCommand(this.dataStore.getVolumeTO(volInfo));
-        
-        CreateVolumeContext<CommandResult> context = new CreateVolumeContext<CommandResult>(callback, vol);
-        AsyncCallbackDispatcher<DefaultPrimaryDataStoreDriverImpl, Answer> caller = AsyncCallbackDispatcher.create(this);
-        caller.setContext(context)
-            .setCallback(caller.getTarget().createVolumeAsyncCallback(null, null));
-
-        ep.sendMessageAsync(createCmd, caller);
-    }
-    
-    public Void createVolumeAsyncCallback(AsyncCallbackDispatcher<DefaultPrimaryDataStoreDriverImpl, Answer> callback, CreateVolumeContext<CommandResult> context) {
+    public Void createAsyncCallback(AsyncCallbackDispatcher<DefaultPrimaryDataStoreDriverImpl, Answer> callback, CreateVolumeContext<CommandResult> context) {
         CommandResult result = new CommandResult();
         CreateVolumeAnswer volAnswer = (CreateVolumeAnswer) callback.getResult();
         if (volAnswer.getResult()) {
-            VolumeObject volume = context.getVolume();
-            volume.setPath(volAnswer.getVolumeUuid());
+            DataObject volume = context.getVolume();
+            //volume.setPath(volAnswer.getVolumeUuid());
         } else {
             result.setResult(volAnswer.getDetails());
         }
@@ -103,18 +81,18 @@ public class DefaultPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
     }
   
     @Override
-    public void deleteVolumeAsync(VolumeObject vo, AsyncCompletionCallback<CommandResult> callback) {
-        DeleteVolumeCommand cmd = new DeleteVolumeCommand(this.dataStore.getVolumeTO(vo));
-        List<EndPoint> endPoints = vo.getDataStore().getEndPoints();
+    public void deleteAsync(DataObject vo, AsyncCompletionCallback<CommandResult> callback) {
+        DeleteCommand cmd = new DeleteCommand(vo.getUri());
+        List<EndPoint> endPoints = null;
         EndPoint ep = endPoints.get(0);
         AsyncRpcConext<CommandResult> context = new AsyncRpcConext<CommandResult>(callback);
         AsyncCallbackDispatcher<DefaultPrimaryDataStoreDriverImpl, Answer> caller = AsyncCallbackDispatcher.create(this);
-        caller.setCallback(caller.getTarget().deleteVolumeCallback(null, null))
+        caller.setCallback(caller.getTarget().deleteCallback(null, null))
             .setContext(context);
         ep.sendMessageAsync(cmd, caller);
     }
     
-    public Void deleteVolumeCallback(AsyncCallbackDispatcher<DefaultPrimaryDataStoreDriverImpl, Answer> callback, AsyncRpcConext<CommandResult> context) {
+    public Void deleteCallback(AsyncCallbackDispatcher<DefaultPrimaryDataStoreDriverImpl, Answer> callback, AsyncRpcConext<CommandResult> context) {
         CommandResult result = new CommandResult();
         Answer answer = callback.getResult();
         if (!answer.getResult()) {
@@ -123,19 +101,7 @@ public class DefaultPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
         context.getParentCallback().complete(result);
         return null;
     }
-
-    @Override
-    public String grantAccess(VolumeObject vol, EndPoint ep) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean revokeAccess(VolumeObject vol, EndPoint ep) {
-        // TODO Auto-generated method stub
-        return true;
-    }
-    
+    /*
     private class CreateVolumeFromBaseImageContext<T> extends AsyncRpcConext<T> {
         private final VolumeObject volume;
       
@@ -149,12 +115,14 @@ public class DefaultPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
         }
         
     }
+
     @Override
-    public void createVolumeFromBaseImageAsync(VolumeObject volume, String template, AsyncCompletionCallback<CommandResult> callback) {
+    public void createVolumeFromBaseImageAsync(VolumeObject volume, TemplateInfo template, AsyncCompletionCallback<CommandResult> callback) {
         VolumeTO vol = this.dataStore.getVolumeTO(volume);
-        CreateVolumeFromBaseImageCommand cmd = new CreateVolumeFromBaseImageCommand(vol, template);
         List<EndPoint> endPoints = this.dataStore.getEndPoints();
         EndPoint ep = endPoints.get(0);
+        String templateUri = template.getDataStore().grantAccess(template, ep);
+        CreateVolumeFromBaseImageCommand cmd = new CreateVolumeFromBaseImageCommand(vol, templateUri);
         
         CreateVolumeFromBaseImageContext<CommandResult> context = new CreateVolumeFromBaseImageContext<CommandResult>(callback, volume);
         AsyncCallbackDispatcher<DefaultPrimaryDataStoreDriverImpl, Answer> caller = AsyncCallbackDispatcher.create(this);
@@ -162,10 +130,8 @@ public class DefaultPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
             .setCallback(caller.getTarget().createVolumeFromBaseImageAsyncCallback(null, null));
 
         ep.sendMessageAsync(cmd, caller);
-        
-       
-    }
-    
+    }*/
+    /*
     public Object createVolumeFromBaseImageAsyncCallback(AsyncCallbackDispatcher<DefaultPrimaryDataStoreDriverImpl, Answer> callback, CreateVolumeFromBaseImageContext<CommandResult> context) {
         CreateVolumeAnswer answer = (CreateVolumeAnswer)callback.getResult();
         CommandResult result = new CommandResult();
@@ -182,37 +148,69 @@ public class DefaultPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
         AsyncCompletionCallback<CommandResult> parentCall = context.getParentCallback();
         parentCall.complete(result);
         return null;
+    }*/
+
+    @Override
+    public void createAsync(DataObject vol,
+            AsyncCompletionCallback<CreateCmdResult> callback) {
+        List<EndPoint> endPoints = null;
+        EndPoint ep = endPoints.get(0);
+        CreateVolumeCommand createCmd = new CreateVolumeCommand(vol.getUri());
+        
+        CreateVolumeContext<CommandResult> context = null;
+        AsyncCallbackDispatcher<DefaultPrimaryDataStoreDriverImpl, Answer> caller = AsyncCallbackDispatcher.create(this);
+        caller.setContext(context)
+            .setCallback(caller.getTarget().createAsyncCallback(null, null));
+
+        ep.sendMessageAsync(createCmd, caller);
+        
     }
 
     @Override
-    public long getCapacity() {
+    public String grantAccess(DataObject vol, EndPoint ep) {
         // TODO Auto-generated method stub
-        return 0;
+        return null;
     }
 
     @Override
-    public long getAvailableCapacity() {
+    public boolean revokeAccess(DataObject vol, EndPoint ep) {
         // TODO Auto-generated method stub
-        return 0;
+        return false;
     }
 
     @Override
-    public boolean initialize(Map<String, String> params) {
+    public Set<DataObject> listObjects(DataStore store) {
         // TODO Auto-generated method stub
-        return false;
+        return null;
     }
 
     @Override
-    public boolean grantAccess(EndPoint ep) {
+    public void takeSnapshot(SnapshotInfo snapshot,
+            AsyncCompletionCallback<CommandResult> callback) {
         // TODO Auto-generated method stub
-        return false;
+        
+    }
+
+    @Override
+    public void revertSnapshot(SnapshotInfo snapshot,
+            AsyncCompletionCallback<CommandResult> callback) {
+        // TODO Auto-generated method stub
+        
     }
 
+    
+
     @Override
-    public boolean revokeAccess(EndPoint ep) {
+    public boolean canCopy(DataObject srcData, DataObject destData) {
         // TODO Auto-generated method stub
         return false;
     }
 
+    @Override
+    public void copyAsync(DataObject srcdata, DataObject destData,
+            AsyncCompletionCallback<CopyCommandResult> callback) {
+        // TODO Auto-generated method stub
+        
+    }
    
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8af85b04/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/PrimaryDataStoreDriver.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/PrimaryDataStoreDriver.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/PrimaryDataStoreDriver.java
index 3a9b13d..b248758 100644
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/PrimaryDataStoreDriver.java
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/PrimaryDataStoreDriver.java
@@ -14,36 +14,3 @@
 // KIND, either express or implied.  See the License for the
 // specific language governing permissions and limitations
 // under the License.
-package org.apache.cloudstack.storage.datastore.driver;
-
-import java.util.Map;
-
-import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
-import org.apache.cloudstack.storage.EndPoint;
-import org.apache.cloudstack.storage.command.CommandResult;
-import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
-import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo;
-import org.apache.cloudstack.storage.volume.VolumeObject;
-
-public interface PrimaryDataStoreDriver {
-    void createVolumeAsync(VolumeObject vol, AsyncCompletionCallback<CommandResult> callback);
-
-    void createVolumeFromBaseImageAsync(VolumeObject volume, String template, AsyncCompletionCallback<CommandResult> callback);
-
-    void deleteVolumeAsync(VolumeObject vo, AsyncCompletionCallback<CommandResult> callback);
-
-    String grantAccess(VolumeObject vol, EndPoint ep);
-
-    boolean revokeAccess(VolumeObject vol, EndPoint ep);
-    
-    long getCapacity();
-    
-    long getAvailableCapacity();
-    
-    
-    //Lifecycle API
-    boolean initialize(Map<String, String> params);
-    boolean grantAccess(EndPoint ep);
-    boolean revokeAccess(EndPoint ep);
-    void setDataStore(PrimaryDataStore dataStore);
-}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8af85b04/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/DefaultPrimaryDataStoreLifeCycleImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/DefaultPrimaryDataStoreLifeCycleImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/DefaultPrimaryDataStoreLifeCycleImpl.java
index 658d4db..c3372b7 100644
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/DefaultPrimaryDataStoreLifeCycleImpl.java
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/DefaultPrimaryDataStoreLifeCycleImpl.java
@@ -21,9 +21,10 @@ package org.apache.cloudstack.storage.datastore.lifecycle;
 import java.util.Map;
 
 import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
 import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle;
-import org.apache.cloudstack.storage.EndPoint;
+import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
 import org.apache.cloudstack.storage.command.AttachPrimaryDataStoreCmd;
 import org.apache.cloudstack.storage.datastore.DataStoreStatus;
 import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
@@ -38,29 +39,21 @@ public class DefaultPrimaryDataStoreLifeCycleImpl implements PrimaryDataStoreLif
     }
     
     @Override
-    public void setDataStore(PrimaryDataStoreInfo dataStore) {
-        this.dataStore = (PrimaryDataStore)dataStore;
-    }
-    
-    @Override
-    public boolean initialize(Map<String, String> dsInfos) {
-        PrimaryDataStoreVO dataStore = dataStoreDao.findById(this.dataStore.getId());
-        dataStore.setStatus(DataStoreStatus.Initialized);
-        dataStoreDao.update(this.dataStore.getId(), dataStore);
+    public boolean initialize(DataStore store, Map<String, String> dsInfos) {
         //TODO: add extension point for each data store
         return true;
     }
 
     protected void attachCluster() {
         //send down AttachPrimaryDataStoreCmd command to all the hosts in the cluster
-        AttachPrimaryDataStoreCmd cmd = new AttachPrimaryDataStoreCmd(this.dataStore.getDataStoreTO());
-        for (EndPoint ep : dataStore.getEndPoints()) {
+        AttachPrimaryDataStoreCmd cmd = new AttachPrimaryDataStoreCmd(this.dataStore.getUri());
+        /*for (EndPoint ep : dataStore.getEndPoints()) {
             ep.sendMessage(cmd);
-        } 
+        } */
     }
     
     @Override
-    public boolean attachCluster(ClusterScope scope) {
+    public boolean attachCluster(DataStore dataStore, ClusterScope scope) {
         PrimaryDataStoreVO dataStoreVO = dataStoreDao.findById(this.dataStore.getId());
         dataStoreVO.setDataCenterId(scope.getZoneId());
         dataStoreVO.setPodId(scope.getPodId());
@@ -107,4 +100,12 @@ public class DefaultPrimaryDataStoreLifeCycleImpl implements PrimaryDataStoreLif
         return false;
     }
 
+
+
+    @Override
+    public boolean attachZone(DataStore dataStore, ZoneScope scope) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8af85b04/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/DefaultXenPrimaryDataStoreLifeCycle.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/DefaultXenPrimaryDataStoreLifeCycle.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/DefaultXenPrimaryDataStoreLifeCycle.java
index bb255b0..da61825 100644
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/DefaultXenPrimaryDataStoreLifeCycle.java
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/DefaultXenPrimaryDataStoreLifeCycle.java
@@ -18,7 +18,7 @@
  */
 package org.apache.cloudstack.storage.datastore.lifecycle;
 
-import org.apache.cloudstack.storage.EndPoint;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
 import org.apache.cloudstack.storage.command.AttachPrimaryDataStoreCmd;
 import org.apache.cloudstack.storage.command.CreatePrimaryDataStoreCmd;
 import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
@@ -39,8 +39,9 @@ public class DefaultXenPrimaryDataStoreLifeCycle extends DefaultPrimaryDataStore
     
     @Override
     public void attachCluster() {
+        String result = null;
         //send one time is enough, as xenserver is clustered
-        CreatePrimaryDataStoreCmd cmd = new CreatePrimaryDataStoreCmd(this.dataStore.getDataStoreTO());
+        /*CreatePrimaryDataStoreCmd cmd = new CreatePrimaryDataStoreCmd(this.dataStore.getDataStoreTO());
         String result = null;
         for (EndPoint ep : dataStore.getEndPoints()) {
             Answer answer = ep.sendMessage(cmd);
@@ -48,7 +49,7 @@ public class DefaultXenPrimaryDataStoreLifeCycle extends DefaultPrimaryDataStore
                 return;
             }
             result = answer.getDetails();
-        }
+        }*/
         
         if (result != null)
             throw new CloudRuntimeException("AttachPrimaryDataStoreCmd failed: " + result);

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8af85b04/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/DefaultPrimaryDataStoreManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/DefaultPrimaryDataStoreManagerImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/DefaultPrimaryDataStoreManagerImpl.java
deleted file mode 100644
index 139da4d..0000000
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/DefaultPrimaryDataStoreManagerImpl.java
+++ /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.
- */
-package org.apache.cloudstack.storage.datastore.manager;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider;
-import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreVO;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreProviderDao;
-import org.apache.cloudstack.storage.datastore.provider.PrimaryDataStoreProviderManager;
-import org.springframework.stereotype.Component;
-
-@Component
-public class DefaultPrimaryDataStoreManagerImpl implements PrimaryDataStoreManager {
-    @Inject
-    PrimaryDataStoreProviderDao dataStoreProviderDao;
-    @Inject
-    PrimaryDataStoreProviderManager providerManager;
-    @Inject
-    PrimaryDataStoreDao dataStoreDao;
-
-    @Override
-    public PrimaryDataStore getPrimaryDataStore(long dataStoreId) {
-        PrimaryDataStoreVO dataStoreVO = dataStoreDao.findById(dataStoreId);
-        Long providerId = dataStoreVO.getStorageProviderId();
-        PrimaryDataStoreProvider provider = providerManager.getDataStoreProvider(providerId);
-        PrimaryDataStore dataStore = (PrimaryDataStore)provider.getDataStore(dataStoreId);
-        return dataStore;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8af85b04/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/DefaultPrimaryDataStoreProviderManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/DefaultPrimaryDataStoreProviderManagerImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/DefaultPrimaryDataStoreProviderManagerImpl.java
new file mode 100644
index 0000000..fd66ffb
--- /dev/null
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/DefaultPrimaryDataStoreProviderManagerImpl.java
@@ -0,0 +1,67 @@
+/*
+ * 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.datastore.manager;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.storage.datastore.DefaultPrimaryDataStore;
+import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
+import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager;
+import org.apache.cloudstack.storage.datastore.db.DataStoreProviderDao;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreVO;
+import org.apache.cloudstack.storage.datastore.provider.DataStoreProvider;
+import org.apache.cloudstack.storage.datastore.provider.DataStoreProviderManager;
+import org.apache.cloudstack.storage.volume.PrimaryDataStoreDriver;
+import org.springframework.stereotype.Component;
+
+@Component
+public class DefaultPrimaryDataStoreProviderManagerImpl implements PrimaryDataStoreProviderManager {
+    @Inject
+    DataStoreProviderDao dataStoreProviderDao;
+    @Inject
+    DataStoreProviderManager providerManager;
+    @Inject
+    PrimaryDataStoreDao dataStoreDao;
+    Map<String, PrimaryDataStoreDriver> driverMaps = new HashMap<String, PrimaryDataStoreDriver>();
+
+    @Override
+    public PrimaryDataStore getPrimaryDataStore(long dataStoreId) {
+        PrimaryDataStoreVO dataStoreVO = dataStoreDao.findById(dataStoreId);
+        long providerId = dataStoreVO.getStorageProviderId();
+        DataStoreProvider provider = providerManager.getDataStoreProviderById(providerId);
+        DefaultPrimaryDataStore dataStore = DefaultPrimaryDataStore.createDataStore(dataStoreVO, 
+                driverMaps.get(provider.getUuid()),
+                provider);
+
+        return dataStore;
+    }
+    
+    @Override
+    public boolean registerDriver(String uuid, PrimaryDataStoreDriver driver) {
+        if (driverMaps.get(uuid) != null) {
+            return false;
+        }
+        driverMaps.put(uuid, driver);
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8af85b04/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/PrimaryDataStoreManager.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/PrimaryDataStoreManager.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/PrimaryDataStoreManager.java
deleted file mode 100644
index f6b3625..0000000
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/PrimaryDataStoreManager.java
+++ /dev/null
@@ -1,27 +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.datastore.manager;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle;
-import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
-
-public interface PrimaryDataStoreManager {
-    public PrimaryDataStore getPrimaryDataStore(long dataStoreId);
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8af85b04/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/data model.ucls
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/data model.ucls b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/data model.ucls
new file mode 100644
index 0000000..2e09bd5
--- /dev/null
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/data model.ucls	
@@ -0,0 +1,57 @@
+<class-diagram version="1.0.11" icons="true" always-add-relationships="false" generalizations="true" realizations="true" 
+  associations="true" dependencies="false" nesting-relationships="true">  
+  <interface id="1" corner="BOTTOM_RIGHT" language="java" 
+    name="org.apache.cloudstack.engine.subsystem.api.storage.DataObject" project="cloud-engine-api" 
+    file="/cloud-engine-api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java" binary="false">    
+    <position height="-1" width="-1" x="311" y="101"/>    
+    <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
+      <attributes public="true" package="true" protected="true" private="true"/>      
+      <operations public="true" package="true" protected="true" private="true"/>    
+    </display>  
+  </interface>  
+  <interface id="2" corner="BOTTOM_RIGHT" language="java" 
+    name="org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo" project="cloud-engine-api" 
+    file="/cloud-engine-api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java" binary="false">    
+    <position height="-1" width="-1" x="146" y="279"/>    
+    <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
+      <attributes public="true" package="true" protected="true" private="true"/>      
+      <operations public="true" package="true" protected="true" private="true"/>    
+    </display>  
+  </interface>  
+  <interface id="3" corner="BOTTOM_RIGHT" language="java" name="org.apache.cloudstack.storage.snapshot.SnapshotInfo" 
+    project="cloud-engine-storage" 
+    file="/cloud-engine-storage/src/org/apache/cloudstack/storage/snapshot/SnapshotInfo.java" binary="false">    
+    <position height="-1" width="-1" x="361" y="282"/>    
+    <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
+      <attributes public="true" package="true" protected="true" private="true"/>      
+      <operations public="true" package="true" protected="true" private="true"/>    
+    </display>  
+  </interface>  
+  <interface id="4" corner="BOTTOM_RIGHT" language="java" name="org.apache.cloudstack.storage.image.TemplateInfo" 
+    project="cloud-engine-storage" 
+    file="/cloud-engine-storage/src/org/apache/cloudstack/storage/image/TemplateInfo.java" binary="false">    
+    <position height="-1" width="-1" x="573" y="292"/>    
+    <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
+      <attributes public="true" package="true" protected="true" private="true"/>      
+      <operations public="true" package="true" protected="true" private="true"/>    
+    </display>  
+  </interface>  
+  <generalization id="5">    
+    <end type="SOURCE" refId="3"/>    
+    <end type="TARGET" refId="1"/>  
+  </generalization>  
+  <generalization id="6">    
+    <end type="SOURCE" refId="4"/>    
+    <end type="TARGET" refId="1"/>  
+  </generalization>  
+  <generalization id="7">    
+    <end type="SOURCE" refId="2"/>    
+    <end type="TARGET" refId="1"/>  
+  </generalization>  
+  <classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" 
+    visibility="true">    
+    <attributes public="true" package="true" protected="true" private="true"/>    
+    <operations public="true" package="true" protected="true" private="true"/>  
+  </classifier-display>  
+  <association-display labels="true" multiplicity="true"/>
+</class-diagram>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8af85b04/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultPrimaryDatastoreProviderImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultPrimaryDatastoreProviderImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultPrimaryDatastoreProviderImpl.java
index 55966be..540ea63 100644
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultPrimaryDatastoreProviderImpl.java
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultPrimaryDatastoreProviderImpl.java
@@ -16,151 +16,56 @@
 // under the License.
 package org.apache.cloudstack.storage.datastore.provider;
 
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 
-import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider;
-import org.apache.cloudstack.storage.datastore.DefaultPrimaryDataStore;
-import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
-import org.apache.cloudstack.storage.datastore.configurator.PrimaryDataStoreConfigurator;
-import org.apache.cloudstack.storage.datastore.configurator.validator.StorageProtocolTransformer;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreProviderDao;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreProviderVO;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreVO;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle;
+import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager;
 import org.apache.cloudstack.storage.datastore.driver.DefaultPrimaryDataStoreDriverImpl;
-import org.apache.cloudstack.storage.datastore.driver.PrimaryDataStoreDriver;
 import org.apache.cloudstack.storage.datastore.lifecycle.DefaultPrimaryDataStoreLifeCycleImpl;
-import org.springframework.beans.factory.annotation.Qualifier;
+import org.apache.cloudstack.storage.volume.PrimaryDataStoreDriver;
 import org.springframework.stereotype.Component;
 
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.storage.Storage.StoragePoolType;
-import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.component.ComponentContext;
 
 @Component
 public class DefaultPrimaryDatastoreProviderImpl implements PrimaryDataStoreProvider {
     private final String providerName = "default primary data store provider";
     protected PrimaryDataStoreDriver driver;
-    private PrimaryDataStoreProviderVO providerVO;
     @Inject
-    protected PrimaryDataStoreDao dataStoreDao;
-    @Inject
-    protected PrimaryDataStoreProviderDao providerDao;
-    @Inject
-    protected ClusterDao clusterDao;
-    protected Map<String, PrimaryDataStoreConfigurator> configuratorMaps = new HashMap<String, PrimaryDataStoreConfigurator>();
-
-    @Inject
-    public DefaultPrimaryDatastoreProviderImpl(@Qualifier("defaultProvider") List<PrimaryDataStoreConfigurator> configurators) {
-        for (PrimaryDataStoreConfigurator configurator : configurators) {
-            String key = generateKey(configurator.getSupportedHypervisor(), configurator.getSupportedDataStoreType().toString());
-            configuratorMaps.put(key, configurator);
-        }
-    }
-    
-    // TODO: Remove this.  I put this in to get over the compilation problem.  Edison needs to look at Solidfire's implementation which requires this.
-    public DefaultPrimaryDatastoreProviderImpl() {
-        
-    }
-
-    protected String generateKey(HypervisorType hypervisor, String poolType) {
-        return hypervisor.toString().toLowerCase() + "_" + poolType.toString().toLowerCase();
-    }
-
+    PrimaryDataStoreProviderManager storeMgr;
+    protected DataStoreLifeCycle lifecyle;
+    protected String uuid;
+    protected long id;
     @Override
-    public PrimaryDataStore getDataStore(long dataStoreId) {
-        PrimaryDataStoreVO dsv = dataStoreDao.findById(dataStoreId);
-        if (dsv == null) {
-            return null;
-        }
-
-        String key = dsv.getKey();
-
-        PrimaryDataStoreConfigurator configurator = configuratorMaps.get(key);
-
-        DefaultPrimaryDataStore dataStore = (DefaultPrimaryDataStore)configurator.getDataStore(dataStoreId);
-        dataStore.setProvider(this);
-        return dataStore;
+    public String getName() {
+        return providerName;
     }
 
     @Override
-    public PrimaryDataStore registerDataStore(Map<String, String> dsInfos) {
-        String url = dsInfos.get("url");
-        URI uri = null;
-        try {
-            uri = new URI(url);
-        } catch (URISyntaxException e) {
-            throw new CloudRuntimeException("invalid url: " + e.toString());
-        }
-        String protocol = uri.getScheme();
-        Long cluster = null;
-        try {
-            cluster = Long.parseLong(dsInfos.get("clusterId"));
-        } catch (NumberFormatException e) {
-            throw new CloudRuntimeException("Failed to get clusterId");
-        }
-        ClusterVO clusterVO = clusterDao.findById(cluster);
-        if (clusterVO == null) {
-            throw new CloudRuntimeException("Can't find cluster: " + cluster); 
-        }
-        HypervisorType hypervisor = clusterVO.getHypervisorType();
-        String key = generateKey(hypervisor, protocol);
-        PrimaryDataStoreConfigurator configurator = configuratorMaps.get(key);
-        if (configurator == null) {
-            throw new CloudRuntimeException("can't find configurator from key: " + key);
-        }
-
-        StorageProtocolTransformer validator = configurator.getProtocolTransformer();
-        validator.normalizeUserInput(dsInfos);
-
-        PrimaryDataStoreVO dataStoreVO = dataStoreDao.findPoolByUUID(dsInfos.get("uuid"));
-        if (dataStoreVO != null) {
-            throw new CloudRuntimeException("duplicate uuid: " + dsInfos.get("uuid"));
-        }
-        
-        dataStoreVO = new PrimaryDataStoreVO();
-        dataStoreVO.setStorageProviderId(this.getId());
-        dataStoreVO.setHostAddress(dsInfos.get("server"));
-        dataStoreVO.setPath(dsInfos.get("path"));
-        dataStoreVO.setPoolType(protocol);
-        dataStoreVO.setPort(Integer.parseInt(dsInfos.get("port")));
-        dataStoreVO.setKey(key);
-        dataStoreVO.setName(dsInfos.get("name"));
-        dataStoreVO.setUuid(dsInfos.get("uuid"));
-        dataStoreVO = dataStoreDao.persist(dataStoreVO);
-
-        DefaultPrimaryDataStore dataStore = (DefaultPrimaryDataStore)configurator.getDataStore(dataStoreVO.getId());
-        dataStore.setProvider(this);
-        
-        PrimaryDataStoreLifeCycle lifeCycle = dataStore.getLifeCycle();
-        lifeCycle.initialize(dsInfos);
-        return getDataStore(dataStore.getId());
+    public DataStoreLifeCycle getLifeCycle() {
+        return this.lifecyle;
     }
 
     @Override
-    public long getId() {
-        return this.providerVO.getId();
+    public boolean configure(Map<String, Object> params) {
+        lifecyle = ComponentContext.inject(DefaultPrimaryDataStoreLifeCycleImpl.class);
+        driver = ComponentContext.inject(DefaultPrimaryDataStoreDriverImpl.class);
+        uuid = (String)params.get("uuid");
+        id = (Long)params.get("id");
+        storeMgr.registerDriver(uuid, this.driver);
+        return true;
     }
 
     @Override
-    public boolean configure() {
-        this.providerVO = providerDao.findByName(this.providerName);
-        return true;
+    public String getUuid() {
+        return this.uuid;
     }
 
     @Override
-    public String getName() {
-        return providerName;
+    public long getId() {
+        return this.id;
     }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8af85b04/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/PrimaryDataStoreProviderManager.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/PrimaryDataStoreProviderManager.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/PrimaryDataStoreProviderManager.java
index c77f7a3..b248758 100644
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/PrimaryDataStoreProviderManager.java
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/PrimaryDataStoreProviderManager.java
@@ -14,16 +14,3 @@
 // KIND, either express or implied.  See the License for the
 // specific language governing permissions and limitations
 // under the License.
-package org.apache.cloudstack.storage.datastore.provider;
-
-import java.util.List;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider;
-
-import com.cloud.utils.component.Manager;
-
-public interface PrimaryDataStoreProviderManager extends Manager {
-    public PrimaryDataStoreProvider getDataStoreProvider(Long providerId);
-    public PrimaryDataStoreProvider getDataStoreProvider(String name);
-    public List<PrimaryDataStoreProvider> getDataStoreProviders();
-}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8af85b04/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/PrimaryDataStoreProviderManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/PrimaryDataStoreProviderManagerImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/PrimaryDataStoreProviderManagerImpl.java
deleted file mode 100644
index 33d98db..0000000
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/PrimaryDataStoreProviderManagerImpl.java
+++ /dev/null
@@ -1,106 +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.datastore.provider;
-
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreProviderDao;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreProviderVO;
-import org.springframework.stereotype.Component;
-
-import com.cloud.utils.db.DB;
-
-@Component
-public class PrimaryDataStoreProviderManagerImpl implements PrimaryDataStoreProviderManager {
-    @Inject
-    List<PrimaryDataStoreProvider> providers;
-    @Inject
-    PrimaryDataStoreProviderDao providerDao;
-    
-    @Override
-    public PrimaryDataStoreProvider getDataStoreProvider(Long providerId) {
-        for (PrimaryDataStoreProvider provider : providers) {
-            if (provider.getId() == providerId) {
-                return provider;
-            }
-        }
-        return null;
-    }
-
-    @Override
-    @DB
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        List<PrimaryDataStoreProviderVO> providerVos = providerDao.listAll();
-        for (PrimaryDataStoreProvider provider : providers) {
-            boolean existingProvider = false;
-            for (PrimaryDataStoreProviderVO providerVo : providerVos) {
-                if (providerVo.getName().equalsIgnoreCase(provider.getName())) {
-                    existingProvider = true;
-                    break;
-                }
-            }
-            if (!existingProvider) {
-                PrimaryDataStoreProviderVO dataStoreProvider = new PrimaryDataStoreProviderVO();
-                dataStoreProvider.setName(provider.getName());
-                dataStoreProvider = providerDao.persist(dataStoreProvider);
-            }
-            
-            provider.configure();
-        }
-        return true;
-    }
-
-    @Override
-    public boolean start() {
-        // TODO Auto-generated method stub
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        // TODO Auto-generated method stub
-        return true;
-    }
-
-    @Override
-    public String getName() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public PrimaryDataStoreProvider getDataStoreProvider(String name) {
-        for (PrimaryDataStoreProvider provider : providers) {
-            if (provider.getName().equalsIgnoreCase(name)) {
-                return provider;
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public List<PrimaryDataStoreProvider> getDataStoreProviders() {
-        return providers;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8af85b04/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateInstallStrategy.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateInstallStrategy.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateInstallStrategy.java
new file mode 100644
index 0000000..7679bb3
--- /dev/null
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateInstallStrategy.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.storage.volume;
+
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
+import org.apache.cloudstack.storage.image.TemplateInfo;
+import org.apache.cloudstack.storage.volume.VolumeServiceImpl.CreateBaseImageResult;
+
+public interface TemplateInstallStrategy {
+    public Void installAsync(TemplateInfo template, PrimaryDataStore store, AsyncCompletionCallback<CreateBaseImageResult> callback);
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8af85b04/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateInstallStrategyImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateInstallStrategyImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateInstallStrategyImpl.java
new file mode 100644
index 0000000..ec6b032
--- /dev/null
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateInstallStrategyImpl.java
@@ -0,0 +1,293 @@
+/*
+ * 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.volume;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
+import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+import org.apache.cloudstack.framework.async.AsyncRpcConext;
+import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
+import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
+import org.apache.cloudstack.storage.db.ObjectInDataStoreVO;
+import org.apache.cloudstack.storage.image.ImageDataFactory;
+import org.apache.cloudstack.storage.image.TemplateInfo;
+import org.apache.cloudstack.storage.motion.DataMotionService;
+import org.apache.cloudstack.storage.volume.VolumeServiceImpl.CreateBaseImageResult;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.NoTransitionException;
+
+@Component
+public class TemplateInstallStrategyImpl implements TemplateInstallStrategy {
+    private static final Logger s_logger = Logger
+            .getLogger(TemplateInstallStrategyImpl.class);
+    @Inject
+    ObjectInDataStoreManager objectInDataStoreMgr;
+    @Inject
+    DataMotionService motionSrv;
+    @Inject
+    ImageDataFactory imageFactory;
+    protected long waitingTime = 1800; // half an hour
+    protected long waitingRetries = 10;
+
+    protected TemplateInfo waitingForTemplateDownload(TemplateInfo template,
+            PrimaryDataStore dataStore) {
+        long retries = this.waitingRetries;
+        ObjectInDataStoreVO obj = null;
+        do {
+            try {
+                Thread.sleep(waitingTime);
+            } catch (InterruptedException e) {
+                s_logger.debug("sleep interrupted", e);
+                throw new CloudRuntimeException("sleep interrupted", e);
+            }
+
+            obj = objectInDataStoreMgr.findObject(template.getId(),
+                    template.getType(), dataStore.getId(), dataStore.getRole());
+            if (obj == null) {
+                s_logger.debug("can't find object in db, maybe it's cleaned up already, exit waiting");
+                break;
+            }
+            if (obj.getState() == ObjectInDataStoreStateMachine.State.Ready) {
+                break;
+            }
+            retries--;
+        } while (retries > 0);
+
+        if (obj == null || retries <= 0) {
+            s_logger.debug("waiting too long for template downloading, marked it as failed");
+            throw new CloudRuntimeException(
+                    "waiting too long for template downloading, marked it as failed");
+        }
+        return imageFactory.getTemplate(template.getId(), dataStore);
+    }
+
+    class InstallContext<T> extends AsyncRpcConext<T> {
+        final TemplateInfo destTemplate;
+        final TemplateInfo srcTemplate;
+
+        public InstallContext(AsyncCompletionCallback<T> callback,
+                TemplateInfo destTemplate, TemplateInfo srcTemplate) {
+            super(callback);
+            this.destTemplate = destTemplate;
+            this.srcTemplate = srcTemplate;
+        }
+
+    }
+
+    @Override
+    public Void installAsync(TemplateInfo template, PrimaryDataStore store,
+            AsyncCompletionCallback<CreateBaseImageResult> callback) {
+        ObjectInDataStoreVO obj = objectInDataStoreMgr.findObject(
+                template.getId(), template.getType(), store.getId(),
+                store.getRole());
+        TemplateInfo templateOnPrimaryStoreObj = null;
+        boolean freshNewTemplate = false;
+        if (obj == null) {
+            try {
+                templateOnPrimaryStoreObj = objectInDataStoreMgr.create(
+                        template, store);
+                freshNewTemplate = true;
+            } catch (Throwable e) {
+                obj = objectInDataStoreMgr.findObject(template.getId(),
+                        template.getType(), store.getId(), store.getRole());
+                if (obj == null) {
+                    CreateBaseImageResult result = new CreateBaseImageResult(
+                            null);
+                    result.setSucess(false);
+                    result.setResult(e.toString());
+                    callback.complete(result);
+                    return null;
+                }
+            }
+        }
+
+        if (!freshNewTemplate
+                && obj.getState() != ObjectInDataStoreStateMachine.State.Ready) {
+            try {
+                templateOnPrimaryStoreObj = waitingForTemplateDownload(
+                        template, store);
+            } catch (Exception e) {
+                CreateBaseImageResult result = new CreateBaseImageResult(null);
+                result.setSucess(false);
+                result.setResult(e.toString());
+                callback.complete(result);
+                return null;
+            }
+
+            CreateBaseImageResult result = new CreateBaseImageResult(
+                    templateOnPrimaryStoreObj);
+            callback.complete(result);
+            return null;
+        }
+
+        try {
+            objectInDataStoreMgr.update(templateOnPrimaryStoreObj,
+                    ObjectInDataStoreStateMachine.Event.CreateRequested);
+        } catch (NoTransitionException e) {
+            try {
+                objectInDataStoreMgr.update(templateOnPrimaryStoreObj,
+                        ObjectInDataStoreStateMachine.Event.OperationFailed);
+            } catch (NoTransitionException e1) {
+                s_logger.debug("state transation failed", e1);
+            }
+            CreateBaseImageResult result = new CreateBaseImageResult(null);
+            result.setSucess(false);
+            result.setResult(e.toString());
+            callback.complete(result);
+            return null;
+        }
+
+        InstallContext<CreateBaseImageResult> context = new InstallContext<CreateBaseImageResult>(
+                callback, templateOnPrimaryStoreObj, template);
+        AsyncCallbackDispatcher<TemplateInstallStrategyImpl, CreateCmdResult> caller = AsyncCallbackDispatcher
+                .create(this);
+        caller.setCallback(
+                caller.getTarget().installTemplateCallback(null, null))
+                .setContext(context);
+
+        store.getDriver().createAsync(templateOnPrimaryStoreObj, caller);
+        return null;
+    }
+
+    class CopyTemplateContext<T> extends AsyncRpcConext<T> {
+        TemplateInfo template;
+
+        public CopyTemplateContext(AsyncCompletionCallback<T> callback,
+                TemplateInfo template) {
+            super(callback);
+            this.template = template;
+        }
+    }
+
+    protected Void installTemplateCallback(
+            AsyncCallbackDispatcher<TemplateInstallStrategyImpl, CreateCmdResult> callback,
+            InstallContext<CreateBaseImageResult> context) {
+        CreateCmdResult result = callback.getResult();
+        TemplateInfo templateOnPrimaryStoreObj = context.destTemplate;
+        CreateBaseImageResult upResult = new CreateBaseImageResult(
+                templateOnPrimaryStoreObj);
+        if (result.isFailed()) {
+            upResult.setResult(result.getResult());
+            context.getParentCallback().complete(upResult);
+            return null;
+        }
+
+        ObjectInDataStoreVO obj = objectInDataStoreMgr.findObject(
+                templateOnPrimaryStoreObj.getId(), templateOnPrimaryStoreObj
+                        .getType(), templateOnPrimaryStoreObj.getDataStore()
+                        .getId(), templateOnPrimaryStoreObj.getDataStore()
+                        .getRole());
+
+        obj.setInstallPath(result.getPath());
+        try {
+            objectInDataStoreMgr.update(templateOnPrimaryStoreObj,
+                    ObjectInDataStoreStateMachine.Event.OperationSuccessed);
+        } catch (NoTransitionException e) {
+            try {
+                objectInDataStoreMgr.update(templateOnPrimaryStoreObj,
+                        ObjectInDataStoreStateMachine.Event.OperationFailed);
+            } catch (NoTransitionException e1) {
+                s_logger.debug("failed to change state", e1);
+            }
+
+            upResult.setResult(e.toString());
+            context.getParentCallback().complete(upResult);
+            return null;
+        }
+
+        moveTemplate(context.srcTemplate, templateOnPrimaryStoreObj, obj,
+                context.getParentCallback());
+        return null;
+    }
+
+    protected void moveTemplate(TemplateInfo srcTemplate,
+            TemplateInfo destTemplate, ObjectInDataStoreVO obj,
+            AsyncCompletionCallback<CreateBaseImageResult> callback) {
+        // move template into primary storage
+        try {
+            objectInDataStoreMgr.update(destTemplate,
+                    ObjectInDataStoreStateMachine.Event.CopyingRequested);
+        } catch (NoTransitionException e) {
+            s_logger.debug("failed to change state", e);
+            try {
+                objectInDataStoreMgr.update(destTemplate,
+                        ObjectInDataStoreStateMachine.Event.OperationFailed);
+            } catch (NoTransitionException e1) {
+
+            }
+            CreateBaseImageResult res = new CreateBaseImageResult(destTemplate);
+            res.setResult("Failed to change state: " + e.toString());
+            callback.complete(res);
+        }
+
+        CopyTemplateContext<CreateBaseImageResult> anotherCall = new CopyTemplateContext<CreateBaseImageResult>(
+                callback, destTemplate);
+        AsyncCallbackDispatcher<TemplateInstallStrategyImpl, CopyCommandResult> caller = AsyncCallbackDispatcher
+                .create(this);
+        caller.setCallback(caller.getTarget().copyTemplateCallback(null, null))
+                .setContext(anotherCall);
+
+        motionSrv.copyAsync(srcTemplate, destTemplate, caller);
+    }
+
+    protected Void copyTemplateCallback(
+            AsyncCallbackDispatcher<TemplateInstallStrategyImpl, CopyCommandResult> callback,
+            CopyTemplateContext<CreateBaseImageResult> context) {
+        CopyCommandResult result = callback.getResult();
+        TemplateInfo templateOnPrimaryStoreObj = context.template;
+        if (result.isFailed()) {
+            CreateBaseImageResult res = new CreateBaseImageResult(
+                    templateOnPrimaryStoreObj);
+            res.setResult(result.getResult());
+            context.getParentCallback().complete(res);
+        }
+        ObjectInDataStoreVO obj = objectInDataStoreMgr.findObject(
+                templateOnPrimaryStoreObj.getId(), templateOnPrimaryStoreObj
+                        .getType(), templateOnPrimaryStoreObj.getDataStore()
+                        .getId(), templateOnPrimaryStoreObj.getDataStore()
+                        .getRole());
+
+        obj.setInstallPath(result.getPath());
+        CreateBaseImageResult res = new CreateBaseImageResult(
+                templateOnPrimaryStoreObj);
+        try {
+            objectInDataStoreMgr.update(templateOnPrimaryStoreObj,
+                    ObjectInDataStoreStateMachine.Event.OperationSuccessed);
+        } catch (NoTransitionException e) {
+            s_logger.debug("Failed to update copying state: ", e);
+            try {
+                objectInDataStoreMgr.update(templateOnPrimaryStoreObj,
+                        ObjectInDataStoreStateMachine.Event.OperationFailed);
+            } catch (NoTransitionException e1) {
+            }
+
+            res.setResult("Failed to update copying state: " + e.toString());
+            context.getParentCallback().complete(res);
+        }
+        context.getParentCallback().complete(res);
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8af85b04/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateOnPrimaryDataStoreObject.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateOnPrimaryDataStoreObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateOnPrimaryDataStoreObject.java
deleted file mode 100644
index 9221fb4..0000000
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateOnPrimaryDataStoreObject.java
+++ /dev/null
@@ -1,87 +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.volume;
-
-import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
-import org.apache.cloudstack.storage.image.TemplateInfo;
-import org.apache.cloudstack.storage.volume.ObjectInDataStoreStateMachine.Event;
-import org.apache.cloudstack.storage.volume.ObjectInDataStoreStateMachine.State;
-import org.apache.cloudstack.storage.volume.db.TemplatePrimaryDataStoreDao;
-import org.apache.cloudstack.storage.volume.db.TemplatePrimaryDataStoreVO;
-
-import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.fsm.NoTransitionException;
-import com.cloud.utils.fsm.StateMachine2;
-
-public class TemplateOnPrimaryDataStoreObject implements TemplateOnPrimaryDataStoreInfo {
-    protected PrimaryDataStore dataStore;
-    protected TemplateInfo template;
-    protected TemplatePrimaryDataStoreVO vo;
-    protected TemplatePrimaryDataStoreDao templateStoreDao;
-    protected TemplatePrimaryDataStoreManager mgr;
-    protected StateMachine2<State, Event, TemplatePrimaryDataStoreVO> stateMachine;
-
-    public TemplateOnPrimaryDataStoreObject(PrimaryDataStore primaryDataStore, TemplateInfo template, TemplatePrimaryDataStoreVO vo,
-    		TemplatePrimaryDataStoreDao templateStoreDao, TemplatePrimaryDataStoreManager mgr) {
-        this.dataStore = primaryDataStore;
-        this.template = template;
-        this.vo = vo;
-        this.templateStoreDao = templateStoreDao;
-        this.mgr = mgr;
-        this.stateMachine = mgr.getStateMachine();
-    }
-
-    @Override
-    public String getPath() {
-        return vo.getInstallPath();
-    }
-
-    @Override
-    public void setPath(String path) {
-        this.vo.setInstallPath(path);
-    }
-
-    @Override
-    public PrimaryDataStore getPrimaryDataStore() {
-        return this.dataStore;
-    }
-
-    @Override
-    public TemplateInfo getTemplate() {
-        return this.template;
-    }
-
-    public void updateStatus(Status status) {
-        vo.setDownloadState(status);
-        templateStoreDao.update(vo.getId(), vo);
-        vo = templateStoreDao.findById(vo.getId());
-    }
-    
-    public void stateTransit(ObjectInDataStoreStateMachine.Event event) {
-        try {
-            this.stateMachine.transitTo(vo, event, null, templateStoreDao);
-            vo = templateStoreDao.findById(vo.getId());
-        } catch (NoTransitionException e) {
-           throw new CloudRuntimeException("Failed change state", e);
-        } catch (Exception e) {
-            throw new CloudRuntimeException("Failed change state", e);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8af85b04/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplatePrimaryDataStoreManager.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplatePrimaryDataStoreManager.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplatePrimaryDataStoreManager.java
deleted file mode 100644
index 5978424..0000000
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplatePrimaryDataStoreManager.java
+++ /dev/null
@@ -1,35 +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.volume;
-
-import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
-import org.apache.cloudstack.storage.image.TemplateInfo;
-import org.apache.cloudstack.storage.volume.ObjectInDataStoreStateMachine.Event;
-import org.apache.cloudstack.storage.volume.ObjectInDataStoreStateMachine.State;
-import org.apache.cloudstack.storage.volume.db.TemplatePrimaryDataStoreVO;
-
-import com.cloud.utils.fsm.StateMachine2;
-
-public interface TemplatePrimaryDataStoreManager {
-    public TemplateOnPrimaryDataStoreInfo createTemplateOnPrimaryDataStore(TemplateInfo template, PrimaryDataStore dataStore);
-
-    public TemplateOnPrimaryDataStoreInfo findTemplateOnPrimaryDataStore(TemplateInfo template, PrimaryDataStore dataStore);
-    
-    public StateMachine2<State, Event, TemplatePrimaryDataStoreVO> getStateMachine();
-}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8af85b04/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplatePrimaryDataStoreManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplatePrimaryDataStoreManagerImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplatePrimaryDataStoreManagerImpl.java
deleted file mode 100644
index fc4e4fd..0000000
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplatePrimaryDataStoreManagerImpl.java
+++ /dev/null
@@ -1,129 +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.volume;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
-import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
-import org.apache.cloudstack.storage.image.TemplateInfo;
-import org.apache.cloudstack.storage.volume.ObjectInDataStoreStateMachine.Event;
-import org.apache.cloudstack.storage.volume.ObjectInDataStoreStateMachine.State;
-import org.apache.cloudstack.storage.volume.db.TemplatePrimaryDataStoreDao;
-import org.apache.cloudstack.storage.volume.db.TemplatePrimaryDataStoreVO;
-import org.springframework.stereotype.Component;
-
-import com.cloud.storage.VMTemplateStorageResourceAssoc;
-import com.cloud.utils.db.SearchCriteria2;
-import com.cloud.utils.db.SearchCriteriaService;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.fsm.StateMachine2;
-
-@Component
-public class TemplatePrimaryDataStoreManagerImpl implements TemplatePrimaryDataStoreManager {
-    @Inject
-    TemplatePrimaryDataStoreDao templateStoreDao;
-    protected long waitingTime = 1800; //half an hour
-    protected long waitingReties = 10;
-    protected StateMachine2<State, Event, TemplatePrimaryDataStoreVO> stateMachines;
-    public TemplatePrimaryDataStoreManagerImpl() {
-        stateMachines = new StateMachine2<State, Event, TemplatePrimaryDataStoreVO>();
-        stateMachines.addTransition(ObjectInDataStoreStateMachine.State.Allocated, Event.CreateRequested, ObjectInDataStoreStateMachine.State.Creating);
-        stateMachines.addTransition(ObjectInDataStoreStateMachine.State.Creating, Event.OperationSuccessed, ObjectInDataStoreStateMachine.State.Ready);
-        stateMachines.addTransition(ObjectInDataStoreStateMachine.State.Creating, Event.OperationFailed, ObjectInDataStoreStateMachine.State.Failed);
-        stateMachines.addTransition(ObjectInDataStoreStateMachine.State.Failed, Event.CreateRequested, ObjectInDataStoreStateMachine.State.Creating);
-        stateMachines.addTransition(ObjectInDataStoreStateMachine.State.Ready, Event.DestroyRequested, ObjectInDataStoreStateMachine.State.Destroying);
-        stateMachines.addTransition(ObjectInDataStoreStateMachine.State.Destroying, Event.OperationSuccessed, ObjectInDataStoreStateMachine.State.Destroyed);
-        stateMachines.addTransition(ObjectInDataStoreStateMachine.State.Destroying, Event.OperationFailed, ObjectInDataStoreStateMachine.State.Destroying);
-        stateMachines.addTransition(ObjectInDataStoreStateMachine.State.Destroying, Event.DestroyRequested, ObjectInDataStoreStateMachine.State.Destroying);
-    }
-    
-    private TemplatePrimaryDataStoreVO waitingForTemplateDownload(TemplateInfo template, PrimaryDataStoreInfo dataStore) {
-        //the naive version, polling.
-        long retries = waitingReties;
-        TemplatePrimaryDataStoreVO templateStoreVO = null;
-        do {
-            try {
-                Thread.sleep(waitingTime);
-            } catch (InterruptedException e) {
-                
-            }
-            
-            templateStoreVO = templateStoreDao.findByTemplateIdAndPoolIdAndReady(template.getId(), dataStore.getId());
-            if (templateStoreVO != null) {
-                break;
-            }
-            retries--;
-        } while (retries > 0);
-        
-        if (templateStoreVO == null) {
-            throw new CloudRuntimeException("waiting too long for template downloading, marked it as failed");
-        }
-        
-        return templateStoreVO;
-    }
-    @Override
-    public TemplateOnPrimaryDataStoreObject createTemplateOnPrimaryDataStore(TemplateInfo template, PrimaryDataStore dataStore) {
-        TemplatePrimaryDataStoreVO templateStoreVO = null;
-        boolean freshNewTemplate = false;
-        templateStoreVO = templateStoreDao.findByTemplateIdAndPoolId(template.getId(), dataStore.getId());
-        if (templateStoreVO == null) {
-            try {
-                templateStoreVO = new TemplatePrimaryDataStoreVO(dataStore.getId(), template.getId());
-                templateStoreVO = templateStoreDao.persist(templateStoreVO);
-                freshNewTemplate = true;
-            } catch (Throwable th) {
-                templateStoreVO = templateStoreDao.findByTemplateIdAndPoolId(template.getId(), dataStore.getId());
-                if (templateStoreVO == null) {
-                    throw new CloudRuntimeException("Failed create db entry: " + th.toString());
-                }
-            }
-        }
-        
-        //If it's not a fresh template downloading, waiting for other people downloading finished.
-        if (!freshNewTemplate && templateStoreVO.getState() != ObjectInDataStoreStateMachine.State.Ready) {
-            templateStoreVO = waitingForTemplateDownload(template, dataStore);
-        }
-
-        TemplateOnPrimaryDataStoreObject templateStoreObject = new TemplateOnPrimaryDataStoreObject(dataStore, template, templateStoreVO, templateStoreDao, this);
-        return templateStoreObject;
-    }
-
-    @Override
-    public TemplateOnPrimaryDataStoreObject findTemplateOnPrimaryDataStore(TemplateInfo template, PrimaryDataStore dataStore) {
-        SearchCriteriaService<TemplatePrimaryDataStoreVO, TemplatePrimaryDataStoreVO> sc = SearchCriteria2.create(TemplatePrimaryDataStoreVO.class);
-        sc.addAnd(sc.getEntity().getTemplateId(), Op.EQ, template.getId());
-        sc.addAnd(sc.getEntity().getPoolId(), Op.EQ, dataStore.getId());
-        sc.addAnd(sc.getEntity().getDownloadState(), Op.EQ, VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
-        TemplatePrimaryDataStoreVO templateStoreVO = sc.find();
-        if (templateStoreVO == null) {
-        	return null;
-        }
-        
-        TemplateOnPrimaryDataStoreObject templateStoreObject = new TemplateOnPrimaryDataStoreObject(dataStore, template, templateStoreVO, templateStoreDao, this);
-        return templateStoreObject;
-    }
-    
-    @Override
-    public StateMachine2<State, Event, TemplatePrimaryDataStoreVO> getStateMachine() {
-        return stateMachines;
-    }
-     
-}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8af85b04/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeDataFactoryImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeDataFactoryImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeDataFactoryImpl.java
new file mode 100644
index 0000000..38c35f8
--- /dev/null
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeDataFactoryImpl.java
@@ -0,0 +1,53 @@
+/*
+ * 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.volume;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.storage.datastore.DataStoreManager;
+import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
+import org.apache.cloudstack.storage.datastore.VolumeDataFactory;
+import org.apache.cloudstack.storage.db.ObjectInDataStoreVO;
+import org.apache.cloudstack.storage.volume.db.VolumeDao2;
+import org.apache.cloudstack.storage.volume.db.VolumeVO;
+import org.springframework.stereotype.Component;
+
+@Component
+public class VolumeDataFactoryImpl implements VolumeDataFactory {
+    @Inject
+    VolumeDao2 volumeDao;
+    @Inject
+    ObjectInDataStoreManager objMap;
+    @Inject
+    DataStoreManager storeMgr;
+    @Override
+    public VolumeInfo getVolume(long volumeId, DataStore store) {
+        VolumeVO volumeVO = volumeDao.findById(volumeId);
+        ObjectInDataStoreVO obj = objMap.findObject(volumeId, DataObjectType.VOLUME, store.getId(), store.getRole());
+        if (obj == null) {
+            return null;
+        }
+        VolumeObject vol = VolumeObject.getVolumeObject(store, volumeVO);
+        return vol;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8af85b04/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeEntityImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeEntityImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeEntityImpl.java
new file mode 100644
index 0000000..14d7417
--- /dev/null
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeEntityImpl.java
@@ -0,0 +1,207 @@
+/*
+ * 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.volume;
+
+import java.lang.reflect.Method;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+
+import org.apache.cloudstack.engine.cloud.entity.api.SnapshotEntity;
+import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity;
+import org.apache.cloudstack.engine.datacenter.entity.api.StorageEntity;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat;
+import org.apache.cloudstack.engine.subsystem.api.storage.type.VolumeType;
+import org.apache.cloudstack.framework.async.AsyncCallFuture;
+import org.apache.cloudstack.storage.datastore.PrimaryDataStoreEntityImpl;
+import org.apache.cloudstack.storage.volume.VolumeService.VolumeApiResult;
+
+import com.cloud.utils.exception.CloudRuntimeException;
+
+public class VolumeEntityImpl implements VolumeEntity {
+    private VolumeInfo volumeInfo;
+    private final VolumeService vs;
+    private VolumeApiResult result;
+    
+    protected VolumeEntityImpl() {
+        this.vs = null;
+    }
+    
+    public VolumeEntityImpl(VolumeInfo volumeObject, VolumeService vs) {
+        this.volumeInfo = volumeObject;
+        this.vs = vs;
+    }
+
+    public VolumeInfo getVolumeInfo() {
+        return volumeInfo;
+    }
+
+    @Override 
+    public String getUuid() {
+        return volumeInfo.getUuid();
+    }
+
+    @Override
+    public long getId() {
+        return volumeInfo.getId();
+    }
+
+    public String getExternalId() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getCurrentState() {
+        return null;
+    }
+
+    @Override
+    public String getDesiredState() {
+        return null;
+    }
+
+    @Override
+    public Date getCreatedTime() {
+        return null;
+    }
+
+    @Override
+    public Date getLastUpdatedTime() {
+        return null;
+    }
+
+    @Override
+    public String getOwner() {
+        return null;
+    }
+
+  
+    @Override
+    public List<Method> getApplicableActions() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public SnapshotEntity takeSnapshotOf(boolean full) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String reserveForMigration(long expirationTime) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void migrate(String reservationToken) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public VolumeEntity setupForCopy() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void copy(VolumeEntity dest) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void attachTo(String vm, long deviceId) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void detachFrom() {
+        // TODO Auto-generated method stub
+
+    }
+
+
+    @Override
+    public long getSize() {
+        return volumeInfo.getSize();
+    }
+
+    @Override
+    public DiskFormat getDiskType() {
+         return null;
+    }
+
+    @Override
+    public VolumeType getType() {
+        return null;
+    }
+
+    @Override
+    public StorageEntity getDataStore() {
+        return new PrimaryDataStoreEntityImpl((PrimaryDataStoreInfo) volumeInfo.getDataStore());
+    }
+
+    @Override
+    public void destroy() {
+        AsyncCallFuture<VolumeApiResult> future = vs.deleteVolumeAsync(volumeInfo);
+        try {
+            result = future.get();
+            if (!result.isSuccess()) {
+                throw new CloudRuntimeException("Failed to create volume:" + result.getResult());
+            }
+        } catch (InterruptedException e) {
+           throw new CloudRuntimeException("wait to delete volume info failed", e);
+        } catch (ExecutionException e) {
+            throw new CloudRuntimeException("wait to delete volume failed", e);
+        }
+    }
+
+	@Override
+	public Map<String, String> getDetails() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public void addDetail(String name, String value) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public void delDetail(String name, String value) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public void updateDetail(String name, String value) {
+		// TODO Auto-generated method stub
+		
+	}
+
+}