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/02/21 20:15:16 UTC

[26/45] squash changes into one giant patch

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/00df9727/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
index 9e04909..87951ce 100644
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
@@ -16,19 +16,23 @@
 // under the License.
 package org.apache.cloudstack.storage.volume;
 
+import java.util.Date;
+
 import javax.inject.Inject;
 
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
 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.DataStoreRole;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat;
 import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
-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.apache.log4j.Logger;
 
 import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.VolumeDao;
 import com.cloud.utils.component.ComponentContext;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.utils.fsm.NoTransitionException;
@@ -38,17 +42,16 @@ import com.cloud.utils.storage.encoding.EncodingType;
 public class VolumeObject implements VolumeInfo {
     private static final Logger s_logger = Logger.getLogger(VolumeObject.class);
     protected VolumeVO volumeVO;
-    private StateMachine2<Volume.State, Volume.Event, VolumeVO> _volStateMachine;
+    private StateMachine2<Volume.State, Volume.Event, Volume> _volStateMachine;
     protected DataStore dataStore;
     @Inject
-    VolumeDao2 volumeDao;
-    @Inject
-    VolumeManager volumeMgr;
+    VolumeDao volumeDao;
     @Inject
     ObjectInDataStoreManager ojbectInStoreMgr;
+    private Object payload;
 
     protected VolumeObject() {
-      
+        _volStateMachine = Volume.State.getStateMachine();
     }
     
     protected void configure(DataStore dataStore, VolumeVO volumeVO) {
@@ -88,12 +91,11 @@ public class VolumeObject implements VolumeInfo {
     public long getVolumeId() {
         return volumeVO.getId();
     }
-
     public boolean stateTransit(Volume.Event event) {
         boolean result = false;
-        _volStateMachine = volumeMgr.getStateMachine();
         try {
             result = _volStateMachine.transitTo(volumeVO, event, null, volumeDao);
+            volumeVO = volumeDao.findById(volumeVO.getId());
         } catch (NoTransitionException e) {
             String errorMessage = "Failed to transit volume: " + this.getVolumeId() + ", due to: " + e.toString();
             s_logger.debug(errorMessage);
@@ -122,7 +124,7 @@ public class VolumeObject implements VolumeInfo {
         if (this.dataStore == null) {
             throw new CloudRuntimeException("datastore must be set before using this object");
         }
-        ObjectInDataStoreVO obj = ojbectInStoreMgr.findObject(this.volumeVO.getId(), DataObjectType.VOLUME, this.dataStore.getId(), this.dataStore.getRole());
+        DataObjectInStore obj = ojbectInStoreMgr.findObject(this.volumeVO.getUuid(), DataObjectType.VOLUME, this.dataStore.getUuid(), this.dataStore.getRole());
         if (obj.getState() != ObjectInDataStoreStateMachine.State.Ready) {
             return this.dataStore.getUri() + 
                     "&" + EncodingType.OBJTYPE + "=" + DataObjectType.VOLUME + 
@@ -145,4 +147,167 @@ public class VolumeObject implements VolumeInfo {
         // TODO Auto-generated method stub
         return null;
     }
+
+    @Override
+    public void processEvent(
+            ObjectInDataStoreStateMachine.Event event) {
+        if (this.dataStore == null) {
+            return;
+        }
+        try {
+            Volume.Event volEvent = null;
+            if (this.dataStore.getRole() == DataStoreRole.Image) {
+                ojbectInStoreMgr.update(this, event);
+                if (event == ObjectInDataStoreStateMachine.Event.CreateRequested) {
+                    volEvent = Volume.Event.UploadRequested;
+                } else if (event == ObjectInDataStoreStateMachine.Event.OperationSuccessed) {
+                    volEvent = Volume.Event.CopySucceeded;
+                } else if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) {
+                    volEvent = Volume.Event.CopyFailed;
+                }
+            } else {
+                if (event == ObjectInDataStoreStateMachine.Event.CreateRequested ||
+                        event == ObjectInDataStoreStateMachine.Event.CreateOnlyRequested) {
+                    volEvent = Volume.Event.CreateRequested;
+                } else if (event == ObjectInDataStoreStateMachine.Event.CopyingRequested) {
+                    volEvent = Volume.Event.CopyRequested;
+                }
+            }
+            
+            if (event == ObjectInDataStoreStateMachine.Event.DestroyRequested) {
+                volEvent = Volume.Event.DestroyRequested;
+            } else if (event == ObjectInDataStoreStateMachine.Event.ExpungeRequested) {
+                volEvent = Volume.Event.ExpungingRequested;
+            } else if (event == ObjectInDataStoreStateMachine.Event.OperationSuccessed) {
+                volEvent = Volume.Event.OperationSucceeded;
+            } else if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) {
+                volEvent = Volume.Event.OperationFailed;
+            }
+            this.stateTransit(volEvent);
+        } catch (Exception e) {
+            s_logger.debug("Failed to update state", e);
+            throw new CloudRuntimeException("Failed to update state:" + e.toString());
+        }
+
+    }
+
+    @Override
+    public String getName() {
+        return this.volumeVO.getName();
+    }
+
+    @Override
+    public Long getInstanceId() {
+        return this.volumeVO.getInstanceId();
+    }
+
+    @Override
+    public String getFolder() {
+        return this.volumeVO.getFolder();
+    }
+
+    @Override
+    public String getPath() {
+        return this.volumeVO.getPath();
+    }
+
+    @Override
+    public Long getPodId() {
+        return this.volumeVO.getPodId();
+    }
+
+    @Override
+    public long getDataCenterId() {
+        return this.volumeVO.getDataCenterId();
+    }
+
+    @Override
+    public Type getVolumeType() {
+        return this.volumeVO.getVolumeType();
+    }
+
+    @Override
+    public Long getPoolId() {
+        return this.volumeVO.getPoolId();
+    }
+
+    @Override
+    public Date getAttached() {
+        return this.volumeVO.getAttached();
+    }
+
+    @Override
+    public Long getDeviceId() {
+        return this.volumeVO.getDeviceId();
+    }
+
+    @Override
+    public Date getCreated() {
+        return this.volumeVO.getCreated();
+    }
+
+    @Override
+    public long getDiskOfferingId() {
+        return this.volumeVO.getDiskOfferingId();
+    }
+
+    @Override
+    public String getChainInfo() {
+        return this.volumeVO.getChainInfo();
+    }
+
+    @Override
+    public boolean isRecreatable() {
+        return this.volumeVO.isRecreatable();
+    }
+
+    @Override
+    public long getUpdatedCount() {
+        return this.volumeVO.getUpdatedCount();
+    }
+
+    @Override
+    public void incrUpdatedCount() {
+        this.volumeVO.incrUpdatedCount();
+    }
+
+    @Override
+    public Date getUpdated() {
+        return this.volumeVO.getUpdated();
+    }
+
+    @Override
+    public String getReservationId() {
+        return this.volumeVO.getReservationId();
+    }
+
+    @Override
+    public void setReservationId(String reserv) {
+        this.volumeVO.setReservationId(reserv);
+    }
+
+    @Override
+    public long getAccountId() {
+        return this.volumeVO.getAccountId();
+    }
+
+    @Override
+    public long getDomainId() {
+        return this.volumeVO.getDomainId();
+    }
+
+    @Override
+    public Long getTemplateId() {
+        return this.volumeVO.getTemplateId();
+    }
+
+    @Override
+    public void addPayload(Object data) {
+        this.payload = data;
+    }
+
+    @Override
+    public Object getpayload() {
+       return this.payload;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/00df9727/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
index 8cfbae4..891ad12 100644
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
@@ -22,12 +22,16 @@ import javax.inject.Inject;
 
 import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity;
 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.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.type.VolumeType;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
 import org.apache.cloudstack.framework.async.AsyncCallFuture;
 import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
 import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
@@ -36,22 +40,29 @@ import org.apache.cloudstack.storage.datastore.DataObjectManager;
 import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
 import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
 import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager;
-import org.apache.cloudstack.storage.image.TemplateInfo;
-import org.apache.cloudstack.storage.image.motion.ImageMotionService;
-import org.apache.cloudstack.storage.volume.db.VolumeDao2;
-import org.apache.cloudstack.storage.volume.db.VolumeVO;
+import org.apache.cloudstack.storage.motion.DataMotionService;
+import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
+import com.cloud.exception.ConcurrentOperationException;
 import com.cloud.storage.Volume;
+import com.cloud.storage.Volume.Type;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.storage.snapshot.SnapshotManager;
 import com.cloud.utils.db.DB;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.dao.VMInstanceDao;
 
 //1. change volume state
 //2. orchestrator of volume, control most of the information of volume, storage pool id, voluem state, scope etc.
 
 @Component
 public class VolumeServiceImpl implements VolumeService {
+    private static final Logger s_logger = Logger
+            .getLogger(VolumeServiceImpl.class);
     @Inject
-    VolumeDao2 volDao;
+    VolumeDao volDao;
     @Inject
     PrimaryDataStoreProviderManager dataStoreMgr;
     @Inject
@@ -59,27 +70,31 @@ public class VolumeServiceImpl implements VolumeService {
     @Inject
     DataObjectManager dataObjectMgr;
     @Inject
-    ImageMotionService imageMotion;
+    DataMotionService motionSrv;
     @Inject
     TemplateInstallStrategy templateInstallStrategy;
+    @Inject
+    VolumeDataFactory volFactory;
+    @Inject SnapshotManager snapshotMgr;
+    @Inject VMInstanceDao vmDao;
 
     public VolumeServiceImpl() {
     }
     
     private class CreateVolumeContext<T> extends AsyncRpcConext<T> {
 
-        private VolumeObject volume;
+        private DataObject volume;
         private AsyncCallFuture<VolumeApiResult> future;
         /**
          * @param callback
          */
-        public CreateVolumeContext(AsyncCompletionCallback<T> callback, VolumeObject volume, AsyncCallFuture<VolumeApiResult> future) {
+        public CreateVolumeContext(AsyncCompletionCallback<T> callback, DataObject volume, AsyncCallFuture<VolumeApiResult> future) {
             super(callback);
             this.volume = volume;
             this.future = future;
         }
         
-        public VolumeObject getVolume() {
+        public DataObject getVolume() {
             return this.volume;
         }
         
@@ -89,49 +104,35 @@ public class VolumeServiceImpl implements VolumeService {
         
     }
     
-    
-    
     @Override
-    public AsyncCallFuture<VolumeApiResult> createVolumeAsync(VolumeInfo volume, long dataStoreId) {
-        PrimaryDataStore dataStore = dataStoreMgr.getPrimaryDataStore(dataStoreId);
+    public AsyncCallFuture<VolumeApiResult> createVolumeAsync(VolumeInfo volume, DataStore dataStore) {
         AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
-        VolumeApiResult result = new VolumeApiResult(volume);
-        
-        if (dataStore == null) {
-            result.setResult("Can't find dataStoreId: " + dataStoreId);
-            future.complete(result);
-            return future;
-        }
-
-        if (dataStore.exists(volume)) {
-            result.setResult("Volume: " + volume.getId() + " already exists on primary data store: " + dataStoreId);
-            future.complete(result);
-            return future;
-        }
-
-        VolumeObject vo = (VolumeObject) volume;
-        vo.stateTransit(Volume.Event.CreateRequested);
+        DataObject volumeOnStore = dataStore.create(volume);
+        volumeOnStore.processEvent(Event.CreateOnlyRequested);
 
-        CreateVolumeContext<VolumeApiResult> context = new CreateVolumeContext<VolumeApiResult>(null, vo, future);
+        CreateVolumeContext<VolumeApiResult> context = new CreateVolumeContext<VolumeApiResult>(null, volumeOnStore, future);
         AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
         caller.setCallback(caller.getTarget().createVolumeCallback(null, null))
         .setContext(context);
         
-        dataObjectMgr.createAsync(volume, dataStore, caller, true);
+        dataStore.getDriver().createAsync(volumeOnStore, caller);
         return future;
     }
     
     protected Void createVolumeCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> callback, CreateVolumeContext<VolumeApiResult> context) {
         CreateCmdResult result = callback.getResult();
-        VolumeObject vo = context.getVolume();
-        VolumeApiResult volResult = new VolumeApiResult(vo);
+        DataObject vo = context.getVolume();
+        String errMsg = null;
         if (result.isSuccess()) {
-            vo.stateTransit(Volume.Event.OperationSucceeded);
+            vo.processEvent(Event.OperationSuccessed);
         } else {
-            vo.stateTransit(Volume.Event.OperationFailed);
-            volResult.setResult(result.getResult());
+            vo.processEvent(Event.OperationFailed);
+            errMsg = result.getResult();
+        }
+        VolumeApiResult volResult = new VolumeApiResult((VolumeObject)vo);
+        if (errMsg != null) {
+            volResult.setResult(errMsg);
         }
-        
         context.getFuture().complete(volResult);
         return null;
     }
@@ -159,26 +160,47 @@ public class VolumeServiceImpl implements VolumeService {
 
     @DB
     @Override
-    public  AsyncCallFuture<VolumeApiResult> deleteVolumeAsync(VolumeInfo volume) {
-        VolumeObject vo = (VolumeObject)volume;
+    public  AsyncCallFuture<VolumeApiResult> expungeVolumeAsync(VolumeInfo volume) {
         AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
         VolumeApiResult result = new VolumeApiResult(volume);
+        if (volume.getDataStore() == null) {
+            this.volDao.remove(volume.getId());
+            future.complete(result);
+            return future;
+        }
         
-        DataStore dataStore = vo.getDataStore();
-        vo.stateTransit(Volume.Event.DestroyRequested);
-        if (dataStore == null) {
-            vo.stateTransit(Volume.Event.OperationSucceeded);
-            volDao.remove(vo.getId());
+        String vmName = null;
+        VolumeVO vol = this.volDao.findById(volume.getId());
+        if (vol.getVolumeType() == Type.ROOT && vol.getInstanceId() != null) {
+            VirtualMachine vm = vmDao.findByIdIncludingRemoved(vol
+                    .getInstanceId());
+            if (vm != null) {
+                vmName = vm.getInstanceName();
+            }
+        }
+
+        String volumePath = vol.getPath();
+        Long poolId = vol.getPoolId();
+        if (poolId == null || volumePath == null || volumePath.trim().isEmpty()) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Marking volume that was never created as destroyed: "
+                        + vol);
+            }
+            this.volDao.remove(vol.getId());
             future.complete(result);
             return future;
         }
+        VolumeObject vo = (VolumeObject)volume;
+      
+        volume.processEvent(Event.ExpungeRequested);
+      
         
         DeleteVolumeContext<VolumeApiResult> context = new DeleteVolumeContext<VolumeApiResult>(null, vo, future);
         AsyncCallbackDispatcher<VolumeServiceImpl, CommandResult> caller = AsyncCallbackDispatcher.create(this);
         caller.setCallback(caller.getTarget().deleteVolumeCallback(null, null))
             .setContext(context);
         
-        dataObjectMgr.deleteAsync(volume, caller);
+        volume.getDataStore().getDriver().deleteAsync(volume, caller);
         return future;
     }
     
@@ -187,10 +209,10 @@ public class VolumeServiceImpl implements VolumeService {
         VolumeObject vo = context.getVolume();
         VolumeApiResult apiResult = new VolumeApiResult(vo);
         if (result.isSuccess()) {
-            vo.stateTransit(Volume.Event.OperationSucceeded);
+            vo.processEvent(Event.OperationSuccessed);
             volDao.remove(vo.getId());
         } else {
-            vo.stateTransit(Volume.Event.OperationFailed);
+            vo.processEvent(Event.OperationFailed);
             apiResult.setResult(result.getResult());
         }
         context.getFuture().complete(apiResult);
@@ -204,24 +226,6 @@ public class VolumeServiceImpl implements VolumeService {
     }
 
     @Override
-    public boolean createVolumeFromSnapshot(long volumeId, long snapshotId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean rokeAccess(long volumeId, long endpointId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public VolumeEntity allocateVolumeInDb(long size, VolumeType type, String volName, Long templateId) {
-        VolumeVO vo = volDao.allocVolume(size, type, volName, templateId);
-        return new VolumeEntityImpl(VolumeObject.getVolumeObject(null, vo), this);
-    }
-
-    @Override
     public VolumeEntity getVolumeEntity(long volumeId) {
         VolumeVO vo = volDao.findById(volumeId);
         if (vo == null) {
@@ -236,25 +240,21 @@ public class VolumeServiceImpl implements VolumeService {
         }
     }
 
-    @Override
-    public String grantAccess(VolumeInfo volume, EndPoint endpointId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
     class CreateBaseImageContext<T> extends AsyncRpcConext<T> {
         private final VolumeInfo volume;
         private final PrimaryDataStore dataStore;
         private final TemplateInfo srcTemplate;
         private final AsyncCallFuture<VolumeApiResult> future;
+        final DataObject destObj;
         public CreateBaseImageContext(AsyncCompletionCallback<T> callback, VolumeInfo volume, PrimaryDataStore datastore, 
                 TemplateInfo srcTemplate,
-                AsyncCallFuture<VolumeApiResult> future) {
+                AsyncCallFuture<VolumeApiResult> future, DataObject destObj) {
             super(callback);
             this.volume = volume;
             this.dataStore = datastore;
             this.future = future;
             this.srcTemplate = srcTemplate;
+            this.destObj = destObj;
         }
         
         public VolumeInfo getVolume() {
@@ -285,33 +285,45 @@ public class VolumeServiceImpl implements VolumeService {
     
     @DB
     protected void createBaseImageAsync(VolumeInfo volume, PrimaryDataStore dataStore, TemplateInfo template, AsyncCallFuture<VolumeApiResult> future) {
+       
+        DataObject templateOnPrimaryStoreObj = dataStore.create(template);
         CreateBaseImageContext<CreateCmdResult> context = new CreateBaseImageContext<CreateCmdResult>(null, volume, 
                 dataStore,
                 template,
-                future);
-        
-        AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
+                future, templateOnPrimaryStoreObj);
+        AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
         caller.setCallback(caller.getTarget().copyBaseImageCallback(null, null))
         .setContext(context);
-        DataObject templateOnPrimaryStoreObj = dataObjectMgr.createInternalStateOnly(template, dataStore);
+        
+        templateOnPrimaryStoreObj.processEvent(Event.CreateOnlyRequested);
      
-        dataObjectMgr.copyAsync(context.srcTemplate, templateOnPrimaryStoreObj, caller);
+        try {
+            motionSrv.copyAsync(template, templateOnPrimaryStoreObj, caller);
+        } catch (Exception e) {
+            s_logger.debug("failed to create template on storage", e);
+            templateOnPrimaryStoreObj.processEvent(Event.OperationFailed);
+            VolumeApiResult result = new VolumeApiResult(volume);
+            result.setResult(e.toString());
+            caller.complete(result);
+        }
         return;
     }
     
     @DB
-    protected Void copyBaseImageCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> callback, CreateBaseImageContext<VolumeApiResult> context) {
-        CreateCmdResult result = callback.getResult();
+    protected Void copyBaseImageCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CreateBaseImageContext<VolumeApiResult> context) {
+        CopyCommandResult result = callback.getResult();
         VolumeApiResult res = new VolumeApiResult(context.getVolume());
         
         AsyncCallFuture<VolumeApiResult> future = context.getFuture();
+        DataObject templateOnPrimaryStoreObj = context.destObj;
         if (!result.isSuccess()) {
+            templateOnPrimaryStoreObj.processEvent(Event.OperationFailed);
             res.setResult(result.getResult());
             future.complete(res);
             return null;
         }
-        DataObject templateOnPrimaryStoreObj = objectInDataStoreMgr.get(context.srcTemplate, context.dataStore);
-
+        
+        templateOnPrimaryStoreObj.processEvent(Event.OperationSuccessed);
         createVolumeFromBaseImageAsync(context.volume, templateOnPrimaryStoreObj, context.dataStore, future);
         return null;
     }
@@ -332,10 +344,7 @@ public class VolumeServiceImpl implements VolumeService {
             this.templateOnStore = templateOnStore;
         }
         
-        public VolumeObject getVolumeObject() {
-            return this.vo;
-        }
-        
+
         public AsyncCallFuture<VolumeApiResult> getFuture() {
             return this.future;
         }
@@ -343,39 +352,32 @@ public class VolumeServiceImpl implements VolumeService {
     
     @DB
     protected void createVolumeFromBaseImageAsync(VolumeInfo volume, DataObject templateOnPrimaryStore, PrimaryDataStore pd, AsyncCallFuture<VolumeApiResult> future) {
-        VolumeObject vo = (VolumeObject) volume;
-        try {
-            vo.stateTransit(Volume.Event.CreateRequested);
-        } catch (Exception e) {
-            VolumeApiResult result = new VolumeApiResult(volume);
-            result.setResult(e.toString());
-            future.complete(result);
-            return;
-        }
-
+        VolumeObject vo = (VolumeObject)volume;
         CreateVolumeFromBaseImageContext<VolumeApiResult> context = new CreateVolumeFromBaseImageContext<VolumeApiResult>(null, vo, pd, templateOnPrimaryStore, future);
-        AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> caller =  AsyncCallbackDispatcher.create(this);
+        AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller =  AsyncCallbackDispatcher.create(this);
         caller.setCallback(caller.getTarget().copyBaseImageCallBack(null, null))
         .setContext(context);
 
-        DataObject volumeOnPrimaryStorage = dataObjectMgr.createInternalStateOnly(volume, pd);
-        dataObjectMgr.copyAsync(context.templateOnStore, volumeOnPrimaryStorage, caller);
+        DataObject volumeOnPrimaryStorage = pd.create(volume);
+        volume.processEvent(Event.CreateOnlyRequested);
+
+        motionSrv.copyAsync(context.templateOnStore, volumeOnPrimaryStorage, caller);
         return;
     }
     
     @DB
-    public Void copyBaseImageCallBack(AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> callback, CreateVolumeFromBaseImageContext<VolumeApiResult> context) {
-        VolumeObject vo = context.getVolumeObject();
-        CreateCmdResult result = callback.getResult();
+    public Void copyBaseImageCallBack(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CreateVolumeFromBaseImageContext<VolumeApiResult> context) {
+        VolumeObject vo = context.vo;
+        CopyCommandResult result = callback.getResult();
         VolumeApiResult volResult = new VolumeApiResult(vo);
        
         if (result.isSuccess()) {
             if (result.getPath() != null) {
                 vo.setPath(result.getPath());
             }
-            vo.stateTransit(Volume.Event.OperationSucceeded); 
+            vo.processEvent(Event.OperationSuccessed); 
         } else {
-            vo.stateTransit(Volume.Event.OperationFailed);
+            vo.processEvent(Event.OperationFailed);
             volResult.setResult(result.getResult());
         }
         
@@ -397,13 +399,65 @@ public class VolumeServiceImpl implements VolumeService {
             return future;
         }
             
-        createVolumeFromBaseImageAsync(volume, template, pd, future);
+        createVolumeFromBaseImageAsync(volume, templateOnPrimaryStore, pd, future);
         return future;
     }
 
     @Override
-    public TemplateOnPrimaryDataStoreInfo grantAccess(TemplateOnPrimaryDataStoreInfo template, EndPoint endPoint) {
+    @DB
+    public boolean destroyVolume(long volumeId)
+            throws ConcurrentOperationException {
+        
+        VolumeInfo vol = this.volFactory.getVolume(volumeId);
+        vol.processEvent(Event.DestroyRequested);
+        this.snapshotMgr.deletePoliciesForVolume(volumeId);
+
+        vol.processEvent(Event.OperationSuccessed);
+             
+        return true;
+    }
+
+    @Override
+    public AsyncCallFuture<VolumeApiResult> createVolumeFromSnapshot(
+            VolumeInfo volume, DataStore store, SnapshotInfo snapshot) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public AsyncCallFuture<VolumeApiResult> copyVolume(VolumeInfo srcVolume,
+            DataStore destStore) {
         // TODO Auto-generated method stub
         return null;
     }
+    
+    @Override
+    public AsyncCallFuture<VolumeApiResult> registerVolume(VolumeInfo volume, DataStore store) {
+        
+        AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
+        VolumeObject vo = (VolumeObject) volume;
+        vo.stateTransit(Volume.Event.UploadRequested);
+
+        CreateVolumeContext<VolumeApiResult> context = new CreateVolumeContext<VolumeApiResult>(null, vo, future);
+        AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
+        caller.setCallback(caller.getTarget().registerVolumeCallback(null, null))
+        .setContext(context);
+        
+        dataObjectMgr.createAsync(volume, store, caller, true);
+        return future;
+    }
+    
+    protected Void registerVolumeCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> callback, CreateVolumeContext<VolumeApiResult> context) {
+        CreateCmdResult result = callback.getResult();
+        VolumeObject vo = (VolumeObject)context.volume;
+        /*if (result.isFailed()) {
+            vo.stateTransit(Volume.Event.OperationFailed);
+        } else {
+            vo.stateTransit(Volume.Event.OperationSucceeded);
+        }*/
+        VolumeApiResult res = new VolumeApiResult(vo);
+        context.future.complete(res);
+        return null;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/00df9727/framework/api/pom.xml
----------------------------------------------------------------------
diff --git a/framework/api/pom.xml b/framework/api/pom.xml
new file mode 100644
index 0000000..3212d7c
--- /dev/null
+++ b/framework/api/pom.xml
@@ -0,0 +1,42 @@
+<!-- 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-framework-api</artifactId>
+  <parent>
+    <groupId>org.apache.cloudstack</groupId>
+    <artifactId>cloudstack-framework</artifactId>
+    <version>4.1.0-SNAPSHOT</version>
+    <relativePath>../pom.xml</relativePath>
+  </parent>
+  <dependencies>
+    <!-- <dependency> <groupId>org.hornetq</groupId> <artifactId>hornetq-core-client</artifactId> 
+      <version>snap-r9548</version> </dependency> -->
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-utils</artifactId>
+      <version>4.1.0-SNAPSHOT</version>
+    </dependency>
+
+  </dependencies>
+
+  <build>
+    <defaultGoal>install</defaultGoal>
+    <sourceDirectory>src</sourceDirectory>
+    <testSourceDirectory>${project.basedir}/test</testSourceDirectory>
+    <testResources>
+      <testResource>
+        <directory>${project.basedir}/test/resources</directory>
+      </testResource>
+    </testResources>
+  </build>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/00df9727/framework/api/src/org/apache/cloudstack/framework/async/AsyncCallFuture.java
----------------------------------------------------------------------
diff --git a/framework/api/src/org/apache/cloudstack/framework/async/AsyncCallFuture.java b/framework/api/src/org/apache/cloudstack/framework/async/AsyncCallFuture.java
new file mode 100644
index 0000000..57489ff
--- /dev/null
+++ b/framework/api/src/org/apache/cloudstack/framework/async/AsyncCallFuture.java
@@ -0,0 +1,84 @@
+/* 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.framework.async;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+public class AsyncCallFuture<T> implements Future<T>, AsyncCompletionCallback<T> {
+
+	Object _completed = new Object();
+	boolean _done = false;
+	T _resultObject;		// we will store a copy of the result object
+	
+	public AsyncCallFuture() {
+	}
+	
+	@Override
+	public boolean cancel(boolean mayInterruptIfRunning) {
+		// TODO we don't support cancel yet
+		return false;
+	}
+
+	@Override
+	public T get() throws InterruptedException, ExecutionException {
+		synchronized(_completed) {
+			if(!_done)
+				_completed.wait();
+		}
+		
+		return _resultObject;
+	}
+
+	@Override
+	public T get(long timeout, TimeUnit timeUnit) throws InterruptedException,
+			ExecutionException, TimeoutException {
+
+		TimeUnit milliSecondsUnit = TimeUnit.MILLISECONDS;
+		
+		synchronized(_completed) {
+			if(!_done)
+				_completed.wait(milliSecondsUnit.convert(timeout, timeUnit));
+		}
+		
+		return _resultObject;
+	}
+
+	@Override
+	public boolean isCancelled() {
+		// TODO we don't support cancel yet
+		return false;
+	}
+
+	@Override
+	public boolean isDone() {
+		return _done;
+	}
+
+	@Override
+	public void complete(T resultObject) {
+		_resultObject = resultObject;
+		synchronized(_completed) {
+			_done = true;
+			_completed.notifyAll();
+		}
+	}
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/00df9727/framework/api/src/org/apache/cloudstack/framework/async/AsyncCompletionCallback.java
----------------------------------------------------------------------
diff --git a/framework/api/src/org/apache/cloudstack/framework/async/AsyncCompletionCallback.java b/framework/api/src/org/apache/cloudstack/framework/async/AsyncCompletionCallback.java
new file mode 100644
index 0000000..7cdf5fe
--- /dev/null
+++ b/framework/api/src/org/apache/cloudstack/framework/async/AsyncCompletionCallback.java
@@ -0,0 +1,23 @@
+/*
+ * 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.framework.async;
+
+public interface AsyncCompletionCallback <T> {	
+	void complete(T resultObject);
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/00df9727/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallFuture.java
----------------------------------------------------------------------
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallFuture.java b/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallFuture.java
deleted file mode 100644
index 57489ff..0000000
--- a/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallFuture.java
+++ /dev/null
@@ -1,84 +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.framework.async;
-
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-public class AsyncCallFuture<T> implements Future<T>, AsyncCompletionCallback<T> {
-
-	Object _completed = new Object();
-	boolean _done = false;
-	T _resultObject;		// we will store a copy of the result object
-	
-	public AsyncCallFuture() {
-	}
-	
-	@Override
-	public boolean cancel(boolean mayInterruptIfRunning) {
-		// TODO we don't support cancel yet
-		return false;
-	}
-
-	@Override
-	public T get() throws InterruptedException, ExecutionException {
-		synchronized(_completed) {
-			if(!_done)
-				_completed.wait();
-		}
-		
-		return _resultObject;
-	}
-
-	@Override
-	public T get(long timeout, TimeUnit timeUnit) throws InterruptedException,
-			ExecutionException, TimeoutException {
-
-		TimeUnit milliSecondsUnit = TimeUnit.MILLISECONDS;
-		
-		synchronized(_completed) {
-			if(!_done)
-				_completed.wait(milliSecondsUnit.convert(timeout, timeUnit));
-		}
-		
-		return _resultObject;
-	}
-
-	@Override
-	public boolean isCancelled() {
-		// TODO we don't support cancel yet
-		return false;
-	}
-
-	@Override
-	public boolean isDone() {
-		return _done;
-	}
-
-	@Override
-	public void complete(T resultObject) {
-		_resultObject = resultObject;
-		synchronized(_completed) {
-			_done = true;
-			_completed.notifyAll();
-		}
-	}
-}
-

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/00df9727/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCompletionCallback.java
----------------------------------------------------------------------
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCompletionCallback.java b/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCompletionCallback.java
deleted file mode 100644
index 7cdf5fe..0000000
--- a/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCompletionCallback.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.framework.async;
-
-public interface AsyncCompletionCallback <T> {	
-	void complete(T resultObject);
-}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/00df9727/framework/pom.xml
----------------------------------------------------------------------
diff --git a/framework/pom.xml b/framework/pom.xml
index 4dfb409..4633dab 100644
--- a/framework/pom.xml
+++ b/framework/pom.xml
@@ -33,5 +33,6 @@
     <module>ipc</module>
     <module>rest</module>
     <module>events</module>
+    <module>api</module>
   </modules>
 </project>

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/00df9727/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java
index 84c3747..5d7edce 100755
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java
@@ -60,9 +60,9 @@ import com.cloud.resource.ResourceManager;
 import com.cloud.resource.ResourceStateAdapter;
 import com.cloud.resource.ServerResource;
 import com.cloud.resource.UnableDeleteHostException;
+import com.cloud.storage.VMTemplateVO;
 import com.cloud.storage.Storage.ImageFormat;
 import com.cloud.storage.Storage.TemplateType;
-import com.cloud.storage.VMTemplateVO;
 import com.cloud.storage.dao.VMTemplateDao;
 import com.cloud.user.Account;
 import com.cloud.utils.UriUtils;

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/00df9727/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java
index a054063..c2f4923 100755
--- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java
@@ -79,9 +79,9 @@ import com.cloud.resource.ResourceManager;
 import com.cloud.resource.ResourceStateAdapter;
 import com.cloud.resource.ServerResource;
 import com.cloud.resource.UnableDeleteHostException;
+import com.cloud.storage.VMTemplateVO;
 import com.cloud.storage.Storage.ImageFormat;
 import com.cloud.storage.Storage.TemplateType;
-import com.cloud.storage.VMTemplateVO;
 import com.cloud.storage.dao.VMTemplateDao;
 import com.cloud.storage.dao.VMTemplateHostDao;
 import com.cloud.user.Account;

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/00df9727/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java
index 70660d2..9c29149 100644
--- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java
@@ -144,6 +144,7 @@ public class XenServerStorageResource {
         
         try {
             obj = Decoder.decode(uriString);
+
             DecodedDataStore store = obj.getStore(); 
             if (obj.getObjType().equalsIgnoreCase("template") && store.getRole().equalsIgnoreCase("image")) {
                 return getTemplateSize(cmd, obj.getPath());
@@ -224,6 +225,7 @@ public class XenServerStorageResource {
     }
     
     protected SR getNfsSR(Connection conn, DecodedDataStore store) {
+
         Map<String, String> deviceConfig = new HashMap<String, String>();
 
         String uuid = store.getUuid();
@@ -410,6 +412,7 @@ public class XenServerStorageResource {
         try {
             DecodedDataObject obj = Decoder.decode(storeUrl);
             DecodedDataStore store = obj.getStore();
+
             if (store.getScheme().equalsIgnoreCase("nfs")) {
                 SR sr = getNfsSR(conn, store);
             } else if (store.getScheme().equalsIgnoreCase("iscsi")) {
@@ -570,7 +573,9 @@ public class XenServerStorageResource {
         Connection conn = hypervisorResource.getConnection();
         try {
             DecodedDataObject obj = Decoder.decode(dataStoreUri);
+
             DecodedDataStore store = obj.getStore();
+
             SR sr = hypervisorResource.getStorageRepository(conn, store.getUuid());
             hypervisorResource.setupHeartbeatSr(conn, sr, false);
             long capacity = sr.getPhysicalSize(conn);

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/00df9727/plugins/storage-allocators/random/src/com/cloud/storage/allocator/RandomStoragePoolAllocator.java
----------------------------------------------------------------------
diff --git a/plugins/storage-allocators/random/src/com/cloud/storage/allocator/RandomStoragePoolAllocator.java b/plugins/storage-allocators/random/src/com/cloud/storage/allocator/RandomStoragePoolAllocator.java
index 812867e..af21f50 100644
--- a/plugins/storage-allocators/random/src/com/cloud/storage/allocator/RandomStoragePoolAllocator.java
+++ b/plugins/storage-allocators/random/src/com/cloud/storage/allocator/RandomStoragePoolAllocator.java
@@ -21,6 +21,7 @@ import java.util.List;
 
 import javax.ejb.Local;
 
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
@@ -28,7 +29,6 @@ import com.cloud.deploy.DeploymentPlan;
 import com.cloud.deploy.DeploymentPlanner.ExcludeList;
 import com.cloud.server.StatsCollector;
 import com.cloud.storage.StoragePool;
-import com.cloud.storage.StoragePoolVO;
 import com.cloud.storage.VMTemplateVO;
 import com.cloud.vm.DiskProfile;
 import com.cloud.vm.VirtualMachine;
@@ -77,7 +77,8 @@ public class RandomStoragePoolAllocator extends AbstractStoragePoolAllocator {
         		break;
         	}        	
         	if (checkPool(avoid, pool, dskCh, template, null, sc, plan)) {
-        		suitablePools.add(pool);
+        	    StoragePool pol = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(pool.getId());
+        		suitablePools.add(pol);
         	}
         }
 

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/00df9727/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java
----------------------------------------------------------------------
diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java
index 3244c7a..88c5374 100644
--- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java
+++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java
@@ -24,8 +24,8 @@ 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.engine.subsystem.api.storage.SnapshotInfo;
 import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
-import org.apache.cloudstack.storage.snapshot.SnapshotInfo;
 import org.apache.cloudstack.storage.volume.PrimaryDataStoreDriver;
 
 public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/00df9727/server/src/com/cloud/alert/AlertManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/alert/AlertManagerImpl.java b/server/src/com/cloud/alert/AlertManagerImpl.java
index 4545f0a..f8a8fd8 100755
--- a/server/src/com/cloud/alert/AlertManagerImpl.java
+++ b/server/src/com/cloud/alert/AlertManagerImpl.java
@@ -38,6 +38,8 @@ import javax.mail.URLName;
 import javax.mail.internet.InternetAddress;
 import javax.naming.ConfigurationException;
 
+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;
 
@@ -69,8 +71,6 @@ import com.cloud.network.dao.IPAddressDao;
 import com.cloud.org.Grouping.AllocationState;
 import com.cloud.resource.ResourceManager;
 import com.cloud.storage.StorageManager;
-import com.cloud.storage.StoragePoolVO;
-import com.cloud.storage.dao.StoragePoolDao;
 import com.cloud.storage.dao.VolumeDao;
 import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.component.ManagerBase;
@@ -102,7 +102,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager {
     @Inject private VolumeDao _volumeDao;
     @Inject private IPAddressDao _publicIPAddressDao;
     @Inject private DataCenterIpAddressDao _privateIPAddressDao;
-    @Inject private StoragePoolDao _storagePoolDao;
+    @Inject private PrimaryDataStoreDao _storagePoolDao;
     @Inject private ConfigurationDao _configDao;
     @Inject private ResourceManager _resourceMgr;
     @Inject private ConfigurationManager _configMgr;   

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/00df9727/server/src/com/cloud/api/ApiDBUtils.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java
index e6b1bf1..0a20352 100755
--- a/server/src/com/cloud/api/ApiDBUtils.java
+++ b/server/src/com/cloud/api/ApiDBUtils.java
@@ -45,7 +45,7 @@ import org.apache.cloudstack.api.response.UserResponse;
 import org.apache.cloudstack.api.response.UserVmResponse;
 import org.apache.cloudstack.api.response.VolumeResponse;
 import org.apache.cloudstack.api.response.ZoneResponse;
-
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 import org.springframework.stereotype.Component;
 
 import com.cloud.api.query.dao.AccountJoinDao;
@@ -182,10 +182,13 @@ import com.cloud.service.ServiceOfferingVO;
 import com.cloud.service.dao.ServiceOfferingDao;
 import com.cloud.storage.*;
 import com.cloud.storage.Storage.ImageFormat;
+
 import com.cloud.storage.Volume.Type;
 import com.cloud.storage.dao.*;
 import com.cloud.storage.snapshot.SnapshotPolicy;
+import com.cloud.template.TemplateManager;
 import com.cloud.user.*;
+
 import com.cloud.user.dao.AccountDao;
 import com.cloud.user.dao.SSHKeyPairDao;
 import com.cloud.user.dao.UserDao;
@@ -218,9 +221,12 @@ public class ApiDBUtils {
     static AsyncJobManager _asyncMgr;
     static SecurityGroupManager _securityGroupMgr;
     static StorageManager _storageMgr;
+    static VolumeManager _volumeMgr;
     static UserVmManager _userVmMgr;
     static NetworkModel _networkModel;
     static NetworkManager _networkMgr;
+    static TemplateManager _templateMgr;
+    
     static StatsCollector _statsCollector;
 
     static AccountDao _accountDao;
@@ -321,6 +327,8 @@ public class ApiDBUtils {
     @Inject private NetworkModel networkModel;
     @Inject private NetworkManager networkMgr;
     @Inject private StatsCollector statsCollector;
+    @Inject private TemplateManager templateMgr;
+    @Inject private VolumeManager volumeMgr;
 
     @Inject private AccountDao accountDao;
     @Inject private AccountVlanMapDao accountVlanMapDao;
@@ -421,6 +429,7 @@ public class ApiDBUtils {
         _networkModel = networkModel;
         _networkMgr = networkMgr;
         _configMgr = configMgr;
+        _templateMgr = templateMgr;
 
         _accountDao = accountDao;
         _accountVlanMapDao = accountVlanMapDao;
@@ -784,7 +793,7 @@ public class ApiDBUtils {
             List<VMTemplateHostVO> res = _templateHostDao.listByTemplateId(templateId);
             return res.size() == 0 ? null : res.get(0);
         } else {
-            return _storageMgr.getTemplateHostRef(zoneId, templateId, readyOnly);
+            return _templateMgr.getTemplateHostRef(zoneId, templateId, readyOnly);
         }
     }
 
@@ -886,7 +895,7 @@ public class ApiDBUtils {
             throw new InvalidParameterValueException("Please specify a valid volume ID.");
         }
 
-        return _storageMgr.volumeOnSharedStoragePool(volume);
+        return _volumeMgr.volumeOnSharedStoragePool(volume);
     }
 
     public static List<NicProfile> getNics(VirtualMachine vm) {

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/00df9727/server/src/com/cloud/api/ApiResponseHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java
index a94e935..3da3168 100755
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -94,6 +94,7 @@ import org.apache.cloudstack.api.response.VpcResponse;
 import org.apache.cloudstack.api.response.VpnUsersResponse;
 import org.apache.cloudstack.api.response.ZoneResponse;
 import org.apache.cloudstack.api.response.S3Response;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 import org.springframework.stereotype.Component;
 
 import com.cloud.async.AsyncJob;
@@ -165,6 +166,7 @@ import com.cloud.storage.Storage.ImageFormat;
 import com.cloud.storage.Storage.StoragePoolType;
 import com.cloud.storage.Storage.TemplateType;
 import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
+
 import com.cloud.storage.snapshot.SnapshotPolicy;
 import com.cloud.storage.snapshot.SnapshotSchedule;
 import com.cloud.template.VirtualMachineTemplate;

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/00df9727/server/src/com/cloud/api/commands/GetUsageRecordsCmd.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/commands/GetUsageRecordsCmd.java b/server/src/com/cloud/api/commands/GetUsageRecordsCmd.java
new file mode 100644
index 0000000..36d66d9
--- /dev/null
+++ b/server/src/com/cloud/api/commands/GetUsageRecordsCmd.java
@@ -0,0 +1,372 @@
+// 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 com.cloud.api.commands;
+
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.TimeZone;
+
+import org.apache.cloudstack.api.response.AccountResponse;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.ProjectResponse;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.ApiConstants;
+import com.cloud.api.ApiDBUtils;
+import com.cloud.dc.DataCenter;
+import com.cloud.domain.Domain;
+
+import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.response.ListResponse;
+import com.cloud.projects.Project;
+import com.cloud.server.ManagementServerExt;
+import com.cloud.storage.VMTemplateVO;
+
+import org.apache.cloudstack.api.response.UsageRecordResponse;
+
+import com.cloud.usage.UsageTypes;
+import com.cloud.usage.UsageVO;
+import com.cloud.user.Account;
+import com.cloud.uuididentity.dao.IdentityDao;
+import com.cloud.uuididentity.dao.IdentityDaoImpl;
+import com.cloud.vm.VMInstanceVO;
+
+@APICommand(name = "listUsageRecords", description="Lists usage records for accounts", responseObject=UsageRecordResponse.class)
+public class GetUsageRecordsCmd extends BaseListCmd {
+    public static final Logger s_logger = Logger.getLogger(GetUsageRecordsCmd.class.getName());
+
+    private static final String s_name = "listusagerecordsresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="List usage records for the specified user.")
+    private String accountName;
+
+    @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType = DomainResponse.class,
+            description="List usage records for the specified domain.")
+    private Long domainId;
+
+    @Parameter(name=ApiConstants.END_DATE, type=CommandType.DATE, required=true, description="End date range for usage record query. Use yyyy-MM-dd as the date format, e.g. startDate=2009-06-03.")
+    private Date endDate;
+
+    @Parameter(name=ApiConstants.START_DATE, type=CommandType.DATE, required=true, description="Start date range for usage record query. Use yyyy-MM-dd as the date format, e.g. startDate=2009-06-01.")
+    private Date startDate;
+
+    @Parameter(name=ApiConstants.ACCOUNT_ID, type=CommandType.UUID, entityType = AccountResponse.class,
+            description="List usage records for the specified account")
+    private Long accountId;
+
+    @Parameter(name=ApiConstants.PROJECT_ID, type=CommandType.UUID, entityType = ProjectResponse.class,
+            description="List usage records for specified project")
+    private Long projectId;
+
+    @Parameter(name=ApiConstants.TYPE, type=CommandType.LONG, description="List usage records for the specified usage type")
+    private Long usageType;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getAccountName() {
+        return accountName;
+    }
+
+    public Long getDomainId() {
+        return domainId;
+    }
+
+    public Date getEndDate() {
+        return endDate;
+    }
+
+    public Date getStartDate() {
+        return startDate;
+    }
+
+    public Long getAccountId() {
+        return accountId;
+    }
+
+    public Long getUsageType() {
+        return usageType;
+    }
+
+    public Long getProjectId() {
+        return projectId;
+    }
+
+    /////////////////////////////////////////////////////
+    ///////////////  Misc parameters  ///////////////////
+    /////////////////////////////////////////////////////
+
+    private TimeZone usageTimezone;
+
+    public TimeZone getUsageTimezone() {
+        return usageTimezone;
+    }
+
+    public void setUsageTimezone(TimeZone tz) {
+        this.usageTimezone = tz;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public String getDateStringInternal(Date inputDate) {
+        if (inputDate == null) return null;
+
+        TimeZone tz = getUsageTimezone();
+        Calendar cal = Calendar.getInstance(tz);
+        cal.setTime(inputDate);
+
+        StringBuffer sb = new StringBuffer();
+        sb.append(cal.get(Calendar.YEAR)+"-");
+
+        int month = cal.get(Calendar.MONTH) + 1;
+        if (month < 10) {
+            sb.append("0" + month + "-");
+        } else {
+            sb.append(month+"-");
+        }
+
+        int day = cal.get(Calendar.DAY_OF_MONTH);
+        if (day < 10) {
+            sb.append("0" + day);
+        } else {
+            sb.append(""+day);
+        }
+
+        sb.append("'T'");
+
+        int hour = cal.get(Calendar.HOUR_OF_DAY);
+        if (hour < 10) {
+            sb.append("0" + hour + ":");
+        } else {
+            sb.append(hour+":");
+        }
+
+        int minute = cal.get(Calendar.MINUTE);
+        if (minute < 10) {
+            sb.append("0" + minute + ":");
+        } else {
+            sb.append(minute+":");
+        }
+
+        int seconds = cal.get(Calendar.SECOND);
+        if (seconds < 10) {
+            sb.append("0" + seconds);
+        } else {
+            sb.append(""+seconds);
+        }
+
+        double offset = cal.get(Calendar.ZONE_OFFSET);
+        if (tz.inDaylightTime(inputDate)) {
+            offset += (1.0*tz.getDSTSavings()); // add the timezone's DST value (typically 1 hour expressed in milliseconds)
+        }
+
+        offset = offset / (1000d*60d*60d);
+        int hourOffset = (int)offset;
+        double decimalVal = Math.abs(offset) - Math.abs(hourOffset);
+        int minuteOffset = (int)(decimalVal * 60);
+
+        if (hourOffset < 0) {
+            if (hourOffset > -10) {
+                sb.append("-0"+Math.abs(hourOffset));
+            } else {
+                sb.append("-"+Math.abs(hourOffset));
+            }
+        } else {
+            if (hourOffset < 10) {
+                sb.append("+0" + hourOffset);
+            } else {
+                sb.append("+" + hourOffset);
+            }
+        }
+
+        sb.append(":");
+
+        if (minuteOffset == 0) {
+            sb.append("00");
+        } else if (minuteOffset < 10) {
+            sb.append("0" + minuteOffset);
+        } else {
+            sb.append("" + minuteOffset);
+        }
+
+        return sb.toString();
+    }
+
+    @Override
+    public void execute(){
+        ManagementServerExt _mgrExt = (ManagementServerExt)_mgr;
+        List<UsageVO> usageRecords = _mgrExt.getUsageRecords(this);
+        IdentityDao identityDao = new IdentityDaoImpl();
+        ListResponse<UsageRecordResponse> response = new ListResponse<UsageRecordResponse>();
+        List<UsageRecordResponse> usageResponses = new ArrayList<UsageRecordResponse>();
+        for (Object usageRecordGeneric : usageRecords) {
+            UsageRecordResponse usageRecResponse = new UsageRecordResponse();
+            if (usageRecordGeneric instanceof UsageVO) {
+                UsageVO usageRecord = (UsageVO)usageRecordGeneric;
+
+                Account account = ApiDBUtils.findAccountByIdIncludingRemoved(usageRecord.getAccountId());
+                if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+                    //find the project
+                    Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId());
+                    usageRecResponse.setProjectId(project.getUuid());
+                    usageRecResponse.setProjectName(project.getName());
+                } else {
+                    usageRecResponse.setAccountId(account.getUuid());
+                    usageRecResponse.setAccountName(account.getAccountName());
+                }
+
+                Domain domain = ApiDBUtils.findDomainById(usageRecord.getDomainId());
+                if (domain != null) {
+                    usageRecResponse.setDomainId(domain.getUuid());
+                }
+
+                if (usageRecord.getZoneId() != null) {
+                    DataCenter zone = ApiDBUtils.findZoneById(usageRecord.getZoneId());
+                    if (zone != null) {
+                        usageRecResponse.setZoneId(zone.getUuid());
+                    }
+                }
+                usageRecResponse.setDescription(usageRecord.getDescription());
+                usageRecResponse.setUsage(usageRecord.getUsageDisplay());
+                usageRecResponse.setUsageType(usageRecord.getUsageType());
+                if (usageRecord.getVmInstanceId() != null) {
+                    VMInstanceVO vm = ApiDBUtils.findVMInstanceById(usageRecord.getVmInstanceId());
+                    if (vm != null) {
+                        usageRecResponse.setVirtualMachineId(vm.getUuid());
+                    }
+                }
+                usageRecResponse.setVmName(usageRecord.getVmName());
+                if (usageRecord.getTemplateId() != null) {
+                    VMTemplateVO template = ApiDBUtils.findTemplateById(usageRecord.getTemplateId());
+                    if (template != null) {
+                        usageRecResponse.setTemplateId(template.getUuid());
+                    }
+                }
+
+                if(usageRecord.getUsageType() == UsageTypes.RUNNING_VM || usageRecord.getUsageType() == UsageTypes.ALLOCATED_VM){
+                	//Service Offering Id
+                	usageRecResponse.setOfferingId(identityDao.getIdentityUuid("disk_offering", usageRecord.getOfferingId().toString()));
+                	//VM Instance ID
+                	usageRecResponse.setUsageId(identityDao.getIdentityUuid("vm_instance", usageRecord.getUsageId().toString()));
+                	//Hypervisor Type
+                	usageRecResponse.setType(usageRecord.getType());
+
+                } else if(usageRecord.getUsageType() == UsageTypes.IP_ADDRESS){
+                	//isSourceNAT
+                    usageRecResponse.setSourceNat((usageRecord.getType().equals("SourceNat"))?true:false);
+                    //isSystem
+                    usageRecResponse.setSystem((usageRecord.getSize() == 1)?true:false);
+                    //IP Address ID
+                    usageRecResponse.setUsageId(identityDao.getIdentityUuid("user_ip_address", usageRecord.getUsageId().toString()));
+
+                } else if(usageRecord.getUsageType() == UsageTypes.NETWORK_BYTES_SENT || usageRecord.getUsageType() == UsageTypes.NETWORK_BYTES_RECEIVED){
+                	//Device Type
+                	usageRecResponse.setType(usageRecord.getType());
+                	if(usageRecord.getType().equals("DomainRouter")){
+                        //Domain Router Id
+                        usageRecResponse.setUsageId(identityDao.getIdentityUuid("vm_instance", usageRecord.getUsageId().toString()));
+                	} else {
+                		//External Device Host Id
+                		usageRecResponse.setUsageId(identityDao.getIdentityUuid("host", usageRecord.getUsageId().toString()));
+                	}
+                    //Network ID
+                    usageRecResponse.setNetworkId(identityDao.getIdentityUuid("networks", usageRecord.getNetworkId().toString()));
+
+                } else if(usageRecord.getUsageType() == UsageTypes.VOLUME){
+                    //Volume ID
+                    usageRecResponse.setUsageId(identityDao.getIdentityUuid("volumes", usageRecord.getUsageId().toString()));
+                    //Volume Size
+                    usageRecResponse.setSize(usageRecord.getSize());
+                	//Disk Offering Id
+                    if(usageRecord.getOfferingId() != null){
+                    	usageRecResponse.setOfferingId(identityDao.getIdentityUuid("disk_offering", usageRecord.getOfferingId().toString()));
+                    }
+
+                } else if(usageRecord.getUsageType() == UsageTypes.TEMPLATE || usageRecord.getUsageType() == UsageTypes.ISO){
+                    //Template/ISO ID
+                    usageRecResponse.setUsageId(identityDao.getIdentityUuid("vm_template", usageRecord.getUsageId().toString()));
+                    //Template/ISO Size
+                    usageRecResponse.setSize(usageRecord.getSize());
+
+                } else if(usageRecord.getUsageType() == UsageTypes.SNAPSHOT){
+                    //Snapshot ID
+                    usageRecResponse.setUsageId(identityDao.getIdentityUuid("snapshots", usageRecord.getUsageId().toString()));
+                    //Snapshot Size
+                    usageRecResponse.setSize(usageRecord.getSize());
+
+                } else if(usageRecord.getUsageType() == UsageTypes.LOAD_BALANCER_POLICY){
+                    //Load Balancer Policy ID
+                    usageRecResponse.setUsageId(usageRecord.getUsageId().toString());
+
+                } else if(usageRecord.getUsageType() == UsageTypes.PORT_FORWARDING_RULE){
+                    //Port Forwarding Rule ID
+                    usageRecResponse.setUsageId(usageRecord.getUsageId().toString());
+
+                } else if(usageRecord.getUsageType() == UsageTypes.NETWORK_OFFERING){
+                	//Network Offering Id
+                	usageRecResponse.setOfferingId(identityDao.getIdentityUuid("network_offerings", usageRecord.getOfferingId().toString()));
+                	//is Default
+                	usageRecResponse.setDefault((usageRecord.getUsageId() == 1)? true:false);
+
+                } else if(usageRecord.getUsageType() == UsageTypes.VPN_USERS){
+                    //VPN User ID
+                    usageRecResponse.setUsageId(usageRecord.getUsageId().toString());
+
+                } else if(usageRecord.getUsageType() == UsageTypes.SECURITY_GROUP){
+                	//Security Group Id
+                	usageRecResponse.setUsageId(identityDao.getIdentityUuid("security_group", usageRecord.getUsageId().toString()));
+                }
+
+                if (usageRecord.getRawUsage() != null) {
+                    DecimalFormat decimalFormat = new DecimalFormat("###########.######");
+                    usageRecResponse.setRawUsage(decimalFormat.format(usageRecord.getRawUsage()));
+                }
+
+                if (usageRecord.getStartDate() != null) {
+                    usageRecResponse.setStartDate(getDateStringInternal(usageRecord.getStartDate()));
+                }
+                if (usageRecord.getEndDate() != null) {
+                    usageRecResponse.setEndDate(getDateStringInternal(usageRecord.getEndDate()));
+                }
+            }
+
+            usageRecResponse.setObjectName("usagerecord");
+            usageResponses.add(usageRecResponse);
+        }
+
+        response.setResponses(usageResponses);
+        response.setResponseName(getCommandName());
+        this.setResponseObject(response);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/00df9727/server/src/com/cloud/baremetal/BareMetalTemplateAdapter.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/baremetal/BareMetalTemplateAdapter.java b/server/src/com/cloud/baremetal/BareMetalTemplateAdapter.java
index 4440b7a..0cf19fb 100755
--- a/server/src/com/cloud/baremetal/BareMetalTemplateAdapter.java
+++ b/server/src/com/cloud/baremetal/BareMetalTemplateAdapter.java
@@ -37,10 +37,10 @@ import com.cloud.host.Host;
 import com.cloud.host.HostVO;
 import com.cloud.host.dao.HostDao;
 import com.cloud.resource.ResourceManager;
-import com.cloud.storage.VMTemplateHostVO;
-import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
 import com.cloud.storage.TemplateProfile;
+import com.cloud.storage.VMTemplateHostVO;
 import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
 import com.cloud.storage.VMTemplateZoneVO;
 import com.cloud.template.TemplateAdapter;
 import com.cloud.template.TemplateAdapterBase;

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/00df9727/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java b/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java
index 5de5ccd..2817fcc 100755
--- a/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java
+++ b/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java
@@ -27,19 +27,12 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
-import org.apache.cloudstack.api.command.user.template.CreateTemplateCmd;
 import org.apache.cloudstack.api.command.user.vm.DeployVMCmd;
-import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd;
-import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd;
+import org.apache.cloudstack.api.command.user.vm.StartVMCmd;
 import org.apache.log4j.Logger;
 
-import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.StopAnswer;
-import com.cloud.agent.api.baremetal.IpmISetBootDevCommand;
-import com.cloud.agent.api.baremetal.IpmiBootorResetCommand;
 import com.cloud.agent.manager.Commands;
-import org.apache.cloudstack.api.command.user.vm.StartVMCmd;
 
 import com.cloud.baremetal.PxeServerManager.PxeServerType;
 import com.cloud.configuration.Resource.ResourceType;
@@ -62,25 +55,18 @@ import com.cloud.org.Grouping;
 import com.cloud.resource.ResourceManager;
 import com.cloud.service.ServiceOfferingVO;
 import com.cloud.storage.Storage;
-import com.cloud.storage.Storage.TemplateType;
-import com.cloud.storage.TemplateProfile;
 import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.Volume;
+import com.cloud.storage.Storage.TemplateType;
 import com.cloud.template.TemplateAdapter;
-import com.cloud.template.TemplateAdapter.TemplateAdapterType;
 import com.cloud.user.Account;
-import com.cloud.user.AccountVO;
 import com.cloud.user.SSHKeyPair;
-import com.cloud.user.User;
 import com.cloud.user.UserContext;
 import com.cloud.user.*;
 import com.cloud.uservm.UserVm;
 import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.Pair;
-import com.cloud.utils.component.AdapterBase;
 import com.cloud.utils.component.Manager;
 import com.cloud.utils.concurrency.NamedThreadFactory;
-import com.cloud.utils.db.DB;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.utils.fsm.StateListener;
 import com.cloud.utils.net.NetUtils;
@@ -103,7 +89,7 @@ public class BareMetalVmManagerImpl extends UserVmManagerImpl implements BareMet
     @PostConstruct
     public void init() {
     }
-    
+    /*
 	@Override
 	public boolean attachISOToVM(long vmId, long isoId, boolean attach) {
 		s_logger.warn("attachISOToVM is not supported by Bare Metal, just fake a true");
@@ -131,6 +117,7 @@ public class BareMetalVmManagerImpl extends UserVmManagerImpl implements BareMet
 	@Override
     public VMTemplateVO createPrivateTemplateRecord(CreateTemplateCmd cmd, Account templateOwner) throws ResourceAllocationException {
 		/*Baremetal creates record after host rebooting for imaging, in createPrivateTemplate*/
+    /*
 		return null;
 	}
 	
@@ -164,10 +151,12 @@ public class BareMetalVmManagerImpl extends UserVmManagerImpl implements BareMet
         }
 
         HostVO pxe = pxes.get(0);
+        */
         /*
          * prepare() will check if current account has right for creating
          * template
          */
+    /*
         TemplateAdapter adapter = AdapterBase.getAdapterByName(_adapters, TemplateAdapterType.BareMetal.getName());
         Long userId = UserContext.current().getCallerUserId();
         userId = (userId == null ? User.UID_SYSTEM : userId);
@@ -202,6 +191,7 @@ public class BareMetalVmManagerImpl extends UserVmManagerImpl implements BareMet
             throw new CloudRuntimeException(e.getMessage());
         }
 	}
+	*/
 
 	@Override
 	public UserVm createVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException,

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/00df9727/server/src/com/cloud/capacity/CapacityManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/capacity/CapacityManager.java b/server/src/com/cloud/capacity/CapacityManager.java
index fffb41f..656e744 100755
--- a/server/src/com/cloud/capacity/CapacityManager.java
+++ b/server/src/com/cloud/capacity/CapacityManager.java
@@ -16,8 +16,9 @@
 // under the License.
 package com.cloud.capacity;
 
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+
 import com.cloud.host.HostVO;
-import com.cloud.storage.StoragePoolVO;
 import com.cloud.storage.VMTemplateVO;
 import com.cloud.utils.component.Manager;
 import com.cloud.vm.VirtualMachine;

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/00df9727/server/src/com/cloud/capacity/CapacityManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/capacity/CapacityManagerImpl.java b/server/src/com/cloud/capacity/CapacityManagerImpl.java
index 4787c7b..74152ff 100755
--- a/server/src/com/cloud/capacity/CapacityManagerImpl.java
+++ b/server/src/com/cloud/capacity/CapacityManagerImpl.java
@@ -27,6 +27,7 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
@@ -57,10 +58,7 @@ import com.cloud.resource.ServerResource;
 import com.cloud.service.ServiceOfferingVO;
 import com.cloud.service.dao.ServiceOfferingDao;
 import com.cloud.storage.StorageManager;
-import com.cloud.storage.StoragePoolVO;
-import com.cloud.storage.VMTemplateHostVO;
 import com.cloud.storage.VMTemplateStoragePoolVO;
-import com.cloud.storage.VMTemplateSwiftVO;
 import com.cloud.storage.VMTemplateVO;
 import com.cloud.storage.VolumeVO;
 import com.cloud.storage.dao.VMTemplatePoolDao;
@@ -499,28 +497,9 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager,
         }
         
         // Add the size for the templateForVmCreation if its not already present
-        if ((templateForVmCreation != null) && !tmpinstalled) {
-            // If the template that was passed into this allocator is not installed in the storage pool,
-            // add 3 * (template size on secondary storage) to the running total
-            VMTemplateHostVO templateHostVO = _storageMgr.findVmTemplateHost(templateForVmCreation.getId(), pool);
-
-            if (templateHostVO == null) {
-                VMTemplateSwiftVO templateSwiftVO = _swiftMgr.findByTmpltId(templateForVmCreation.getId());
-                if (templateSwiftVO != null) {                                    
-                    long templateSize = templateSwiftVO.getPhysicalSize();
-                    if (templateSize == 0) {
-                        templateSize = templateSwiftVO.getSize();
-                    }
-                    totalAllocatedSize += (templateSize + _extraBytesPerVolume);
-                }
-            } else {
-                long templateSize = templateHostVO.getPhysicalSize();
-                if ( templateSize == 0 ){
-                    templateSize = templateHostVO.getSize();
-                }
-                totalAllocatedSize +=  (templateSize + _extraBytesPerVolume);
-            }
-        }
+        /*if ((templateForVmCreation != null) && !tmpinstalled) {
+            
+        }*/
         
         return totalAllocatedSize;
     }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/00df9727/server/src/com/cloud/capacity/dao/CapacityDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/capacity/dao/CapacityDaoImpl.java b/server/src/com/cloud/capacity/dao/CapacityDaoImpl.java
index c33bfaf..3582614 100755
--- a/server/src/com/cloud/capacity/dao/CapacityDaoImpl.java
+++ b/server/src/com/cloud/capacity/dao/CapacityDaoImpl.java
@@ -27,13 +27,13 @@ import java.util.Map;
 import javax.ejb.Local;
 import javax.inject.Inject;
 
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
 import com.cloud.capacity.Capacity;
 import com.cloud.capacity.CapacityVO;
 import com.cloud.storage.Storage;
-import com.cloud.storage.StoragePoolVO;
 import com.cloud.storage.dao.StoragePoolDao;
 import com.cloud.utils.Pair;
 import com.cloud.utils.db.Filter;

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/00df9727/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
index 168ac0e..69f70e5 100755
--- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
+++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
@@ -29,14 +29,10 @@ import java.util.UUID;
 import javax.ejb.Local;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
-import javax.persistence.Table;
 
 import org.apache.cloudstack.api.ServerApiException;
-import com.cloud.offering.DiskOffering;
-import com.cloud.storage.dao.DiskOfferingDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 import org.apache.log4j.Logger;
-import org.springframework.context.annotation.Primary;
-import org.springframework.stereotype.Component;
 
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.api.AgentControlAnswer;
@@ -102,6 +98,7 @@ import com.cloud.network.dao.IPAddressVO;
 import com.cloud.network.dao.NetworkDao;
 import com.cloud.network.dao.NetworkVO;
 import com.cloud.network.rules.RulesManager;
+import com.cloud.offering.DiskOffering;
 import com.cloud.offering.NetworkOffering;
 import com.cloud.offering.ServiceOffering;
 import com.cloud.offerings.dao.NetworkOfferingDao;
@@ -114,13 +111,14 @@ import com.cloud.service.dao.ServiceOfferingDao;
 import com.cloud.servlet.ConsoleProxyServlet;
 import com.cloud.storage.StorageManager;
 import com.cloud.storage.StoragePoolStatus;
-import com.cloud.storage.StoragePoolVO;
 import com.cloud.storage.VMTemplateHostVO;
-import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
 import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
+import com.cloud.storage.dao.DiskOfferingDao;
 import com.cloud.storage.dao.StoragePoolDao;
 import com.cloud.storage.dao.VMTemplateDao;
 import com.cloud.storage.dao.VMTemplateHostDao;
+import com.cloud.template.TemplateManager;
 import com.cloud.user.Account;
 import com.cloud.user.AccountManager;
 import com.cloud.user.User;
@@ -233,6 +231,8 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
     @Inject
     RulesManager _rulesMgr;
     @Inject
+    TemplateManager templateMgr;
+    @Inject
     IPAddressDao _ipAddressDao;
 
     private ConsoleProxyListener _listener;
@@ -1175,7 +1175,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
         ZoneHostInfo zoneHostInfo = zoneHostInfoMap.get(dataCenterId);
         if (zoneHostInfo != null && isZoneHostReady(zoneHostInfo)) {
             VMTemplateVO template = _templateDao.findSystemVMTemplate(dataCenterId);
-            HostVO secondaryStorageHost = _storageMgr.getSecondaryStorageHost(dataCenterId);
+            HostVO secondaryStorageHost = this.templateMgr.getSecondaryStorageHost(dataCenterId);
             boolean templateReady = false;
 
             if (template != null && secondaryStorageHost != null) {

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/00df9727/server/src/com/cloud/deploy/FirstFitPlanner.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/deploy/FirstFitPlanner.java b/server/src/com/cloud/deploy/FirstFitPlanner.java
index 66a24ac..b452da0 100755
--- a/server/src/com/cloud/deploy/FirstFitPlanner.java
+++ b/server/src/com/cloud/deploy/FirstFitPlanner.java
@@ -27,6 +27,7 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
 import org.apache.log4j.Logger;
 
 import com.cloud.agent.manager.allocator.HostAllocator;
@@ -59,7 +60,6 @@ import com.cloud.storage.DiskOfferingVO;
 import com.cloud.storage.StorageManager;
 import com.cloud.storage.StoragePool;
 import com.cloud.storage.StoragePoolHostVO;
-import com.cloud.storage.StoragePoolVO;
 import com.cloud.storage.Volume;
 import com.cloud.storage.VolumeVO;
 import com.cloud.storage.allocator.StoragePoolAllocator;
@@ -99,6 +99,7 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
     @Inject protected CapacityDao _capacityDao;
     @Inject protected AccountManager _accountMgr;
     @Inject protected StorageManager _storageMgr;
+    @Inject DataStoreManager dataStoreMgr;
 
     //@com.cloud.utils.component.Inject(adapter=StoragePoolAllocator.class)
     @Inject protected List<StoragePoolAllocator> _storagePoolAllocators;
@@ -736,11 +737,11 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
             if(plan.getPoolId() != null){
                 s_logger.debug("Volume has pool already allocated, checking if pool can be reused, poolId: "+toBeCreated.getPoolId());
                 List<StoragePool> suitablePools = new ArrayList<StoragePool>();
-                StoragePoolVO pool;
+                StoragePool pool = null;
                 if(toBeCreated.getPoolId() != null){
-                    pool = _storagePoolDao.findById(toBeCreated.getPoolId());
+                    pool = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(toBeCreated.getPoolId());
                 }else{
-                    pool = _storagePoolDao.findById(plan.getPoolId());
+                    pool = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(plan.getPoolId());
                 }
                 
                 if(!pool.isInMaintenance()){

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/00df9727/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java b/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java
index eb27fda..bba8be5 100755
--- a/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java
+++ b/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java
@@ -31,7 +31,6 @@ import javax.naming.ConfigurationException;
 
 import org.apache.log4j.Logger;
 import org.apache.log4j.NDC;
-import org.springframework.stereotype.Component;
 
 import com.cloud.agent.AgentManager;
 import com.cloud.alert.AlertManager;
@@ -60,6 +59,7 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.resource.ResourceManager;
 import com.cloud.server.ManagementServer;
 import com.cloud.storage.StorageManager;
+import com.cloud.storage.VolumeManager;
 import com.cloud.storage.dao.GuestOSCategoryDao;
 import com.cloud.storage.dao.GuestOSDao;
 import com.cloud.user.AccountManager;
@@ -140,6 +140,8 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai
     ManagementServer _msServer;
     @Inject
     ConfigurationDao _configDao;
+    @Inject
+    VolumeManager volumeMgr;
 
     String _instance;
     ScheduledExecutorService _executor;
@@ -499,7 +501,7 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvai
             return null; // VM doesn't require HA
         }
 
-        if (!_storageMgr.canVmRestartOnAnotherServer(vm.getId())) {
+        if (!this.volumeMgr.canVmRestartOnAnotherServer(vm.getId())) {
             if (s_logger.isDebugEnabled()) {
                 s_logger.debug("VM can not restart on another server.");
             }