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 02:03:17 UTC

[5/9] refactor api

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a2f86003/engine/storage/src/org/apache/cloudstack/storage/datastore/DefaultDatastoreLifeCyle.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/DefaultDatastoreLifeCyle.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/DefaultDatastoreLifeCyle.java
new file mode 100644
index 0000000..910c071
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/DefaultDatastoreLifeCyle.java
@@ -0,0 +1,109 @@
+/*
+ * 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;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole;
+import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
+import org.apache.cloudstack.storage.image.datastore.ImageDataStoreHelper;
+import org.apache.cloudstack.storage.volume.datastore.PrimaryDataStoreHelper;
+import org.springframework.stereotype.Component;
+
+import edu.emory.mathcs.backport.java.util.Arrays;
+
+public class DefaultDatastoreLifeCyle implements DataStoreLifeCycle {
+    @Inject
+    PrimaryDataStoreHelper primaryStoreHelper;
+    @Inject
+    ImageDataStoreHelper imageStoreHelper;
+    @Override
+    public boolean initialize(DataStore store, Map<String, String> dsInfos) {
+        String roles = dsInfos.get("roles");
+        List<String> roleArry = Arrays.asList(roles.split(";"));
+        List<DataStoreRole> storeRoles = new ArrayList<DataStoreRole>();
+        for (String role : roleArry) {
+            storeRoles.add(DataStoreRole.getRole(role));
+        }
+
+        if (storeRoles.contains(DataStoreRole.Primary)) {
+            primaryStoreHelper.createPrimaryDataStore(dsInfos); 
+        }
+        
+        if (storeRoles.contains(DataStoreRole.Image)) {
+            imageStoreHelper.createImageDataStore(dsInfos);
+        }
+        
+        //TODO: add more roles
+       
+        return true;
+    }
+
+    @Override
+    public boolean attachCluster(DataStore dataStore, ClusterScope scope) {
+        if (dataStore.getRole() == DataStoreRole.Primary) {
+            primaryStoreHelper.attachCluster(dataStore);
+        }
+        // TODO Auto-generated method stub
+        return true;
+    }
+    
+    @Override
+    public boolean attachZone(DataStore dataStore, ZoneScope scope) {
+        return false;
+    }
+
+    @Override
+    public boolean dettach() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean unmanaged() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean maintain() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean cancelMaintain() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean deleteDataStore() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a2f86003/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java
index 7bca13b..d7ffc17 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java
@@ -1,17 +1,23 @@
 package org.apache.cloudstack.storage.datastore;
 
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
 import org.apache.cloudstack.storage.db.ObjectInDataStoreVO;
 import org.apache.cloudstack.storage.image.TemplateInfo;
 import org.apache.cloudstack.storage.snapshot.SnapshotInfo;
 import org.apache.cloudstack.storage.volume.ObjectInDataStoreStateMachine;
+import org.apache.cloudstack.storage.volume.ObjectInDataStoreStateMachine.Event;
+
+import com.cloud.utils.fsm.NoTransitionException;
 
 public interface ObjectInDataStoreManager {
     public TemplateInfo create(TemplateInfo template, DataStore dataStore);
-    public ObjectInDataStoreVO create(VolumeInfo volume, DataStore dataStore);
-    public ObjectInDataStoreVO create(SnapshotInfo snapshot, DataStore dataStore);
-    public TemplateInfo findTemplate(TemplateInfo template, DataStore dataStore);
-    public VolumeInfo findVolume(VolumeInfo volume, DataStore dataStore);
-    public SnapshotInfo findSnapshot(SnapshotInfo snapshot, DataStore dataStore);
-    public boolean update(TemplateInfo vo, ObjectInDataStoreStateMachine.Event event);
+    public VolumeInfo create(VolumeInfo volume, DataStore dataStore);
+    public SnapshotInfo create(SnapshotInfo snapshot, DataStore dataStore);
+    public ObjectInDataStoreVO findObject(long objectId, DataObjectType type,
+            long dataStoreId, DataStoreRole role);
+    public boolean update(DataObject vo, Event event) throws NoTransitionException;
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a2f86003/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
index 2cc72dd..9e27183 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
@@ -1,65 +1,107 @@
 package org.apache.cloudstack.storage.datastore;
 
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
 import org.apache.cloudstack.storage.db.ObjectInDataStoreDao;
 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.snapshot.SnapshotInfo;
+import org.apache.cloudstack.storage.volume.ObjectInDataStoreStateMachine;
 import org.apache.cloudstack.storage.volume.ObjectInDataStoreStateMachine.Event;
+import org.apache.cloudstack.storage.volume.ObjectInDataStoreStateMachine.State;
 import org.springframework.stereotype.Component;
 
 import com.cloud.utils.component.Inject;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.SearchCriteria2;
+import com.cloud.utils.db.SearchCriteriaService;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.NoTransitionException;
+import com.cloud.utils.fsm.StateMachine2;
 
 @Component
 public  class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager {
     @Inject
     ObjectInDataStoreDao objectDataStoreDao;
+    @Inject
+    ImageDataFactory imageFactory;
+    @Inject
+    VolumeDataFactory volumeFactory;
+    protected StateMachine2<State, Event, ObjectInDataStoreVO> stateMachines;
+    public ObjectInDataStoreManagerImpl() {
+        stateMachines = new StateMachine2<State, Event, ObjectInDataStoreVO>();
+        stateMachines.addTransition(State.Allocated, Event.CreateRequested, State.Creating);
+        stateMachines.addTransition(State.Creating, Event.OperationSuccessed, State.Created);
+        stateMachines.addTransition(State.Creating, Event.OperationFailed, State.Failed);
+        stateMachines.addTransition(State.Failed, Event.CreateRequested, State.Creating);
+        stateMachines.addTransition(State.Ready, Event.DestroyRequested, State.Destroying);
+        stateMachines.addTransition(State.Destroying, Event.OperationSuccessed, State.Destroyed);
+        stateMachines.addTransition(State.Destroying, Event.OperationFailed, State.Destroying);
+        stateMachines.addTransition(State.Destroying, Event.DestroyRequested, State.Destroying);
+        stateMachines.addTransition(State.Created, Event.CopyingRequested, State.Copying);
+        stateMachines.addTransition(State.Copying, Event.OperationFailed, State.Created);
+        stateMachines.addTransition(State.Copying, Event.OperationSuccessed, State.Ready);
+        stateMachines.addTransition(State.Allocated, Event.CreateOnlyRequested, State.Creating2);
+        stateMachines.addTransition(State.Creating2, Event.OperationFailed, State.Failed);
+        stateMachines.addTransition(State.Creating2, Event.OperationSuccessed, State.Ready);
+    }
+    
     @Override
     public TemplateInfo create(TemplateInfo template, DataStore dataStore) {
         ObjectInDataStoreVO vo = new ObjectInDataStoreVO();
         vo.setDataStoreId(dataStore.getId());
-        vo.setDataStoreType(dataStore.getRole());
+        vo.setDataStoreRole(dataStore.getRole());
         vo.setObjectId(template.getId());
-        vo.setObjectType("template");
+        vo.setObjectType(template.getType());
         vo = objectDataStoreDao.persist(vo);
-        TemplateInDataStore tmpl = new TemplateInDataStore(template, dataStore, vo);
-        return tmpl;
+        
+        return imageFactory.getTemplate(template.getId(), dataStore);
     }
 
     @Override
-    public ObjectInDataStoreVO create(VolumeInfo volume, DataStore dataStore) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public ObjectInDataStoreVO create(SnapshotInfo snapshot, DataStore dataStore) {
-        // TODO Auto-generated method stub
-        return null;
+    public VolumeInfo create(VolumeInfo volume, DataStore dataStore) {
+        ObjectInDataStoreVO vo = new ObjectInDataStoreVO();
+        vo.setDataStoreId(dataStore.getId());
+        vo.setDataStoreRole(dataStore.getRole());
+        vo.setObjectId(volume.getId());
+        vo.setObjectType(volume.getType());
+        vo = objectDataStoreDao.persist(vo);
+        
+        return volumeFactory.getVolume(volume.getId(), dataStore);
     }
 
     @Override
-    public TemplateInfo findTemplate(TemplateInfo template, DataStore dataStore) {
+    public SnapshotInfo create(SnapshotInfo snapshot, DataStore dataStore) {
         // TODO Auto-generated method stub
         return null;
     }
-
+    
     @Override
-    public VolumeInfo findVolume(VolumeInfo volume, DataStore dataStore) {
-        // TODO Auto-generated method stub
-        return null;
+    public ObjectInDataStoreVO findObject(long objectId, DataObjectType type, long dataStoreId, DataStoreRole role) {
+        SearchCriteriaService<ObjectInDataStoreVO, ObjectInDataStoreVO> sc = SearchCriteria2.create(ObjectInDataStoreVO.class);
+        sc.addAnd(sc.getEntity().getObjectId(), Op.EQ, objectId);
+        sc.addAnd(sc.getEntity().getDataStoreId(), Op.EQ, dataStoreId);
+        sc.addAnd(sc.getEntity().getObjectType(), Op.EQ, type);
+        sc.addAnd(sc.getEntity().getDataStoreRole(), Op.EQ, role);
+        sc.addAnd(sc.getEntity().getState(), Op.NIN, ObjectInDataStoreStateMachine.State.Destroyed, 
+                ObjectInDataStoreStateMachine.State.Failed);
+        ObjectInDataStoreVO objectStoreVO = sc.find();
+        return objectStoreVO;
     }
 
     @Override
-    public SnapshotInfo findSnapshot(SnapshotInfo snapshot, DataStore dataStore) {
-        // TODO Auto-generated method stub
-        return null;
-    }
+    public boolean update(DataObject data, Event event) throws NoTransitionException {
+        ObjectInDataStoreVO obj = this.findObject(data.getId(), data.getType(), 
+                data.getDataStore().getId(), data.getDataStore().getRole());
+        if (obj == null) {
+            throw new CloudRuntimeException("can't find mapping in ObjectInDataStore table for: " + data);
+        }
 
-    @Override
-    public boolean update(TemplateInfo vo, Event event) {
-        // TODO Auto-generated method stub
-        return false;
+        return this.stateMachines.transitTo(obj, event, null, objectDataStoreDao);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a2f86003/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStore.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStore.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStore.java
index cf4f879..a6ba9bc 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStore.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStore.java
@@ -20,15 +20,17 @@ package org.apache.cloudstack.storage.datastore;
 
 import java.util.List;
 
+import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult;
+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.PrimaryDataStoreInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskType;
+import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat;
 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.image.TemplateInfo;
-import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
-import org.apache.cloudstack.storage.to.VolumeTO;
+import org.apache.cloudstack.storage.snapshot.SnapshotInfo;
+import org.apache.cloudstack.storage.volume.PrimaryDataStoreDriver;
 import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo;
 
 public interface PrimaryDataStore extends DataStore, PrimaryDataStoreInfo {
@@ -36,27 +38,28 @@ public interface PrimaryDataStore extends DataStore, PrimaryDataStoreInfo {
 
     List<VolumeInfo> getVolumes();
 
-    void deleteVolumeAsync(VolumeInfo volume, AsyncCompletionCallback<CommandResult> callback);
+/*    void deleteVolumeAsync(VolumeInfo volume, AsyncCompletionCallback<CommandResult> callback);
 
     void createVolumeAsync(VolumeInfo vo, VolumeDiskType diskType, AsyncCompletionCallback<CommandResult> callback);
 
-    VolumeInfo createVoluemFromBaseImage(VolumeInfo volume, TemplateOnPrimaryDataStoreInfo templateStore);
-    
     void createVoluemFromBaseImageAsync(VolumeInfo volume, TemplateInfo templateStore, AsyncCompletionCallback<CommandResult> callback);
-    
-    List<EndPoint> getEndPoints();
+ */   
 
-    boolean exists(VolumeInfo vi);
+    boolean exists(DataObject data);
 
-    boolean templateExists(TemplateInfo template);
+    TemplateInfo getTemplate(long templateId);
+    
+    SnapshotInfo getSnapshot(long snapshotId);
 
-    TemplateOnPrimaryDataStoreInfo getTemplate(TemplateInfo template);
 
-    boolean installTemplate(TemplateOnPrimaryDataStoreInfo template);
+    DiskFormat getDefaultDiskType();
 
-    VolumeDiskType getDefaultDiskType();
+/*    void takeSnapshot(SnapshotInfo snapshot,
+            AsyncCompletionCallback<CommandResult> callback);
 
-    PrimaryDataStoreTO getDataStoreTO();
+    void revertSnapshot(SnapshotInfo snapshot,
+            AsyncCompletionCallback<CommandResult> callback);
 
-    VolumeTO getVolumeTO(VolumeInfo volume);
+    void deleteSnapshot(SnapshotInfo snapshot,
+            AsyncCompletionCallback<CommandResult> callback);*/
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a2f86003/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreProviderManager.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreProviderManager.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreProviderManager.java
new file mode 100644
index 0000000..a60ec7a
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreProviderManager.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.datastore;
+
+import org.apache.cloudstack.storage.volume.PrimaryDataStoreDriver;
+
+
+public interface PrimaryDataStoreProviderManager {
+    public PrimaryDataStore getPrimaryDataStore(long dataStoreId);
+
+    boolean registerDriver(String uuid, PrimaryDataStoreDriver driver);
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a2f86003/engine/storage/src/org/apache/cloudstack/storage/datastore/TemplateInDataStore.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/TemplateInDataStore.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/TemplateInDataStore.java
deleted file mode 100644
index f3697cf..0000000
--- a/engine/storage/src/org/apache/cloudstack/storage/datastore/TemplateInDataStore.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package org.apache.cloudstack.storage.datastore;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskType;
-import org.apache.cloudstack.storage.db.ObjectInDataStoreVO;
-import org.apache.cloudstack.storage.image.TemplateInfo;
-import org.apache.cloudstack.storage.image.store.ImageDataStoreInfo;
-
-public class TemplateInDataStore implements TemplateInfo {
-    public TemplateInDataStore(TemplateInfo template, DataStore dataStore, ObjectInDataStoreVO obj) {
-        
-    }
-    @Override
-    public ImageDataStoreInfo getDataStore() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public long getId() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public VolumeDiskType getDiskType() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public String getPath() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public String getUuid() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a2f86003/engine/storage/src/org/apache/cloudstack/storage/datastore/VolumeDataFactory.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/VolumeDataFactory.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/VolumeDataFactory.java
new file mode 100644
index 0000000..0cffc05
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/VolumeDataFactory.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.datastore;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+
+public interface VolumeDataFactory {
+    VolumeInfo getVolume(long volumeId, DataStore store);
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a2f86003/engine/storage/src/org/apache/cloudstack/storage/datastore/db/DataStoreProviderDao.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/db/DataStoreProviderDao.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/db/DataStoreProviderDao.java
new file mode 100644
index 0000000..dca83ce
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/db/DataStoreProviderDao.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.datastore.db;
+
+import com.cloud.utils.db.GenericDao;
+
+public interface DataStoreProviderDao extends GenericDao<DataStoreProviderVO, Long> {
+    public DataStoreProviderVO findByName(String name);
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a2f86003/engine/storage/src/org/apache/cloudstack/storage/datastore/db/DataStoreProviderDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/db/DataStoreProviderDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/db/DataStoreProviderDaoImpl.java
new file mode 100644
index 0000000..ccb6b48
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/db/DataStoreProviderDaoImpl.java
@@ -0,0 +1,38 @@
+/*
+ * 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.db;
+
+import org.springframework.stereotype.Component;
+
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchCriteria2;
+import com.cloud.utils.db.SearchCriteriaService;
+import com.cloud.utils.db.SearchCriteria.Op;
+
+@Component
+class DataStoreProviderDaoImpl extends GenericDaoBase<DataStoreProviderVO, Long> implements DataStoreProviderDao {
+
+    @Override
+    public DataStoreProviderVO findByName(String name) {
+        SearchCriteriaService<DataStoreProviderVO, DataStoreProviderVO> sc = SearchCriteria2.create(DataStoreProviderVO.class);
+        sc.addAnd(sc.getEntity().getName(), Op.EQ, name);
+        return sc.find();
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a2f86003/engine/storage/src/org/apache/cloudstack/storage/datastore/db/DataStoreProviderVO.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/db/DataStoreProviderVO.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/db/DataStoreProviderVO.java
new file mode 100644
index 0000000..dcdafdd
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/db/DataStoreProviderVO.java
@@ -0,0 +1,60 @@
+/*
+ * 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.db;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.TableGenerator;
+
+@Entity
+@Table(name = "data_store_provider")
+public class DataStoreProviderVO {
+    @Id
+    @TableGenerator(name = "data_store_provider_sq", table = "sequence", pkColumnName = "name", valueColumnName = "value", pkColumnValue = "data_store_provider_seq", allocationSize = 1)
+    @Column(name = "id", updatable = false, nullable = false)
+    private long id;
+
+    @Column(name = "name", nullable = false)
+    private String name;
+    
+    @Column(name = "uuid", nullable = false)
+    private String uuid;
+    
+    public long getId() {
+        return id;
+    }
+    
+    public String getName() {
+        return this.name;
+    }
+    
+    public void setName(String name) {
+        this.name = name;
+    }
+    
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+    
+    public String getUuid() {
+        return this.uuid;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a2f86003/engine/storage/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java
new file mode 100644
index 0000000..24a5c79
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java
@@ -0,0 +1,116 @@
+/*
+ * 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.db;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cloudstack.storage.datastore.DataStoreStatus;
+
+import com.cloud.utils.db.GenericDao;
+
+public interface PrimaryDataStoreDao extends GenericDao<PrimaryDataStoreVO, Long> {
+
+    /**
+     * @param datacenterId
+     *            -- the id of the datacenter (availability zone)
+     */
+    List<PrimaryDataStoreVO> listByDataCenterId(long datacenterId);
+
+    /**
+     * @param datacenterId
+     *            -- the id of the datacenter (availability zone)
+     */
+    List<PrimaryDataStoreVO> listBy(long datacenterId, long podId, Long clusterId);
+
+    /**
+     * Set capacity of storage pool in bytes
+     * 
+     * @param id
+     *            pool id.
+     * @param capacity
+     *            capacity in bytes
+     */
+    void updateCapacity(long id, long capacity);
+
+    /**
+     * Set available bytes of storage pool in bytes
+     * 
+     * @param id
+     *            pool id.
+     * @param available
+     *            available capacity in bytes
+     */
+    void updateAvailable(long id, long available);
+
+    PrimaryDataStoreVO persist(PrimaryDataStoreVO pool, Map<String, String> details);
+
+    /**
+     * Find pool by name.
+     * 
+     * @param name
+     *            name of pool.
+     * @return the single StoragePoolVO
+     */
+    List<PrimaryDataStoreVO> findPoolByName(String name);
+
+    /**
+     * Find pools by the pod that matches the details.
+     * 
+     * @param podId
+     *            pod id to find the pools in.
+     * @param details
+     *            details to match. All must match for the pool to be returned.
+     * @return List of StoragePoolVO
+     */
+    List<PrimaryDataStoreVO> findPoolsByDetails(long dcId, long podId, Long clusterId, Map<String, String> details);
+
+    List<PrimaryDataStoreVO> findPoolsByTags(long dcId, long podId, Long clusterId, String[] tags, Boolean shared);
+
+    /**
+     * Find pool by UUID.
+     * 
+     * @param uuid
+     *            uuid of pool.
+     * @return the single StoragePoolVO
+     */
+    PrimaryDataStoreVO findPoolByUUID(String uuid);
+
+    List<PrimaryDataStoreVO> listByStorageHost(String hostFqdnOrIp);
+
+    PrimaryDataStoreVO findPoolByHostPath(long dcId, Long podId, String host, String path, String uuid);
+
+    List<PrimaryDataStoreVO> listPoolByHostPath(String host, String path);
+
+    void updateDetails(long poolId, Map<String, String> details);
+
+    Map<String, String> getDetails(long poolId);
+
+    List<String> searchForStoragePoolDetails(long poolId, String value);
+
+    List<PrimaryDataStoreVO> findIfDuplicatePoolsExistByUUID(String uuid);
+
+    List<PrimaryDataStoreVO> listByStatus(DataStoreStatus status);
+
+    long countPoolsByStatus(DataStoreStatus... statuses);
+
+    List<PrimaryDataStoreVO> listByStatusInZone(long dcId, DataStoreStatus status);
+
+    List<PrimaryDataStoreVO> listPoolsByCluster(long clusterId);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a2f86003/engine/storage/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java
new file mode 100644
index 0000000..247cdee
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java
@@ -0,0 +1,366 @@
+/*
+ * 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.db;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.storage.datastore.DataStoreStatus;
+import org.springframework.stereotype.Component;
+
+import com.cloud.storage.StoragePoolDetailVO;
+import com.cloud.storage.dao.StoragePoolDetailsDao;
+import com.cloud.storage.dao.StoragePoolDetailsDaoImpl;
+import com.cloud.utils.component.ComponentInject;
+import com.cloud.utils.component.ComponentLocator;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.GenericSearchBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.SearchCriteria.Func;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+@Component
+public class PrimaryDataStoreDaoImpl extends GenericDaoBase<PrimaryDataStoreVO, Long> implements PrimaryDataStoreDao {
+    protected final SearchBuilder<PrimaryDataStoreVO> AllFieldSearch;
+    protected final SearchBuilder<PrimaryDataStoreVO> DcPodSearch;
+    protected final SearchBuilder<PrimaryDataStoreVO> DcPodAnyClusterSearch;
+    protected final SearchBuilder<PrimaryDataStoreVO> DeleteLvmSearch;
+    protected final GenericSearchBuilder<PrimaryDataStoreVO, Long> StatusCountSearch;
+
+    protected final PrimaryDataStoreDetailsDao _detailsDao = null;
+
+    private final String DetailsSqlPrefix = "SELECT storage_pool.* from storage_pool LEFT JOIN storage_pool_details ON storage_pool.id = storage_pool_details.pool_id WHERE storage_pool.removed is null and storage_pool.data_center_id = ? and (storage_pool.pod_id = ? or storage_pool.pod_id is null) and (";
+    private final String DetailsSqlSuffix = ") GROUP BY storage_pool_details.pool_id HAVING COUNT(storage_pool_details.name) >= ?";
+    private final String FindPoolTagDetails = "SELECT storage_pool_details.name FROM storage_pool_details WHERE pool_id = ? and value = ?";
+
+    public PrimaryDataStoreDaoImpl() {
+        AllFieldSearch = createSearchBuilder();
+        AllFieldSearch.and("name", AllFieldSearch.entity().getName(), SearchCriteria.Op.EQ);
+        AllFieldSearch.and("uuid", AllFieldSearch.entity().getUuid(), SearchCriteria.Op.EQ);
+        AllFieldSearch.and("datacenterId", AllFieldSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        AllFieldSearch.and("hostAddress", AllFieldSearch.entity().getHostAddress(), SearchCriteria.Op.EQ);
+        AllFieldSearch.and("status", AllFieldSearch.entity().getStatus(), SearchCriteria.Op.EQ);
+        AllFieldSearch.and("path", AllFieldSearch.entity().getPath(), SearchCriteria.Op.EQ);
+        AllFieldSearch.and("podId", AllFieldSearch.entity().getPodId(), Op.EQ);
+        AllFieldSearch.and("clusterId", AllFieldSearch.entity().getClusterId(), Op.EQ);
+        AllFieldSearch.done();
+
+        DcPodSearch = createSearchBuilder();
+        DcPodSearch.and("datacenterId", DcPodSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        DcPodSearch.and().op("nullpod", DcPodSearch.entity().getPodId(), SearchCriteria.Op.NULL);
+        DcPodSearch.or("podId", DcPodSearch.entity().getPodId(), SearchCriteria.Op.EQ);
+        DcPodSearch.cp();
+        DcPodSearch.and().op("nullcluster", DcPodSearch.entity().getClusterId(), SearchCriteria.Op.NULL);
+        DcPodSearch.or("cluster", DcPodSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
+        DcPodSearch.cp();
+        DcPodSearch.done();
+
+        DcPodAnyClusterSearch = createSearchBuilder();
+        DcPodAnyClusterSearch.and("datacenterId", DcPodAnyClusterSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        DcPodAnyClusterSearch.and().op("nullpod", DcPodAnyClusterSearch.entity().getPodId(), SearchCriteria.Op.NULL);
+        DcPodAnyClusterSearch.or("podId", DcPodAnyClusterSearch.entity().getPodId(), SearchCriteria.Op.EQ);
+        DcPodAnyClusterSearch.cp();
+        DcPodAnyClusterSearch.done();
+
+        DeleteLvmSearch = createSearchBuilder();
+        DeleteLvmSearch.and("ids", DeleteLvmSearch.entity().getId(), SearchCriteria.Op.IN);
+        DeleteLvmSearch.and().op("LVM", DeleteLvmSearch.entity().getPoolType(), SearchCriteria.Op.EQ);
+        DeleteLvmSearch.or("Filesystem", DeleteLvmSearch.entity().getPoolType(), SearchCriteria.Op.EQ);
+        DeleteLvmSearch.cp();
+        DeleteLvmSearch.done();
+
+        StatusCountSearch = createSearchBuilder(Long.class);
+        StatusCountSearch.and("status", StatusCountSearch.entity().getStatus(), SearchCriteria.Op.IN);
+        StatusCountSearch.select(null, Func.COUNT, null);
+        StatusCountSearch.done();
+
+       // _detailsDao = ComponentInject.inject(PrimaryDataStoreDetailsDaoImpl.class);
+    }
+
+    @Override
+    public List<PrimaryDataStoreVO> findPoolByName(String name) {
+        SearchCriteria<PrimaryDataStoreVO> sc = AllFieldSearch.create();
+        sc.setParameters("name", name);
+        return listIncludingRemovedBy(sc);
+    }
+
+    @Override
+    public PrimaryDataStoreVO findPoolByUUID(String uuid) {
+        SearchCriteria<PrimaryDataStoreVO> sc = AllFieldSearch.create();
+        sc.setParameters("uuid", uuid);
+        return findOneIncludingRemovedBy(sc);
+    }
+
+    @Override
+    public List<PrimaryDataStoreVO> findIfDuplicatePoolsExistByUUID(String uuid) {
+        SearchCriteria<PrimaryDataStoreVO> sc = AllFieldSearch.create();
+        sc.setParameters("uuid", uuid);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<PrimaryDataStoreVO> listByDataCenterId(long datacenterId) {
+        SearchCriteria<PrimaryDataStoreVO> sc = AllFieldSearch.create();
+        sc.setParameters("datacenterId", datacenterId);
+        return listBy(sc);
+    }
+
+    @Override
+    public void updateAvailable(long id, long available) {
+        PrimaryDataStoreVO pool = createForUpdate(id);
+        pool.setAvailableBytes(available);
+        update(id, pool);
+    }
+
+    @Override
+    public void updateCapacity(long id, long capacity) {
+        PrimaryDataStoreVO pool = createForUpdate(id);
+        pool.setCapacityBytes(capacity);
+        update(id, pool);
+
+    }
+
+    @Override
+    public List<PrimaryDataStoreVO> listByStorageHost(String hostFqdnOrIp) {
+        SearchCriteria<PrimaryDataStoreVO> sc = AllFieldSearch.create();
+        sc.setParameters("hostAddress", hostFqdnOrIp);
+        return listIncludingRemovedBy(sc);
+    }
+
+    @Override
+    public List<PrimaryDataStoreVO> listByStatus(DataStoreStatus status) {
+        SearchCriteria<PrimaryDataStoreVO> sc = AllFieldSearch.create();
+        sc.setParameters("status", status);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<PrimaryDataStoreVO> listByStatusInZone(long dcId, DataStoreStatus status) {
+        SearchCriteria<PrimaryDataStoreVO> sc = AllFieldSearch.create();
+        sc.setParameters("status", status);
+        sc.setParameters("datacenterId", dcId);
+        return listBy(sc);
+    }
+
+    @Override
+    public PrimaryDataStoreVO findPoolByHostPath(long datacenterId, Long podId, String host, String path, String uuid) {
+        SearchCriteria<PrimaryDataStoreVO> sc = AllFieldSearch.create();
+        sc.setParameters("hostAddress", host);
+        sc.setParameters("path", path);
+        sc.setParameters("datacenterId", datacenterId);
+        sc.setParameters("podId", podId);
+        sc.setParameters("uuid", uuid);
+
+        return findOneBy(sc);
+    }
+
+    @Override
+    public List<PrimaryDataStoreVO> listBy(long datacenterId, long podId, Long clusterId) {
+        if (clusterId != null) {
+            SearchCriteria<PrimaryDataStoreVO> sc = DcPodSearch.create();
+            sc.setParameters("datacenterId", datacenterId);
+            sc.setParameters("podId", podId);
+
+            sc.setParameters("cluster", clusterId);
+            return listBy(sc);
+        } else {
+            SearchCriteria<PrimaryDataStoreVO> sc = DcPodAnyClusterSearch.create();
+            sc.setParameters("datacenterId", datacenterId);
+            sc.setParameters("podId", podId);
+            return listBy(sc);
+        }
+    }
+
+    @Override
+    public List<PrimaryDataStoreVO> listPoolByHostPath(String host, String path) {
+        SearchCriteria<PrimaryDataStoreVO> sc = AllFieldSearch.create();
+        sc.setParameters("hostAddress", host);
+        sc.setParameters("path", path);
+
+        return listBy(sc);
+    }
+
+    public PrimaryDataStoreVO listById(Integer id) {
+        SearchCriteria<PrimaryDataStoreVO> sc = AllFieldSearch.create();
+        sc.setParameters("id", id);
+
+        return findOneIncludingRemovedBy(sc);
+    }
+
+    @Override
+    @DB
+    public PrimaryDataStoreVO persist(PrimaryDataStoreVO pool, Map<String, String> details) {
+        Transaction txn = Transaction.currentTxn();
+        txn.start();
+        pool = super.persist(pool);
+        if (details != null) {
+            for (Map.Entry<String, String> detail : details.entrySet()) {
+                PrimaryDataStoreDetailVO vo = new PrimaryDataStoreDetailVO(pool.getId(), detail.getKey(), detail.getValue());
+                _detailsDao.persist(vo);
+            }
+        }
+        txn.commit();
+        return pool;
+    }
+
+    @DB
+    @Override
+    public List<PrimaryDataStoreVO> findPoolsByDetails(long dcId, long podId, Long clusterId, Map<String, String> details) {
+        StringBuilder sql = new StringBuilder(DetailsSqlPrefix);
+        if (clusterId != null) {
+            sql.append("storage_pool.cluster_id = ? OR storage_pool.cluster_id IS NULL) AND (");
+        }
+        for (Map.Entry<String, String> detail : details.entrySet()) {
+            sql.append("((storage_pool_details.name='").append(detail.getKey()).append("') AND (storage_pool_details.value='").append(detail.getValue()).append("')) OR ");
+        }
+        sql.delete(sql.length() - 4, sql.length());
+        sql.append(DetailsSqlSuffix);
+        Transaction txn = Transaction.currentTxn();
+        PreparedStatement pstmt = null;
+        try {
+            pstmt = txn.prepareAutoCloseStatement(sql.toString());
+            int i = 1;
+            pstmt.setLong(i++, dcId);
+            pstmt.setLong(i++, podId);
+            if (clusterId != null) {
+                pstmt.setLong(i++, clusterId);
+            }
+            pstmt.setInt(i++, details.size());
+            ResultSet rs = pstmt.executeQuery();
+            List<PrimaryDataStoreVO> pools = new ArrayList<PrimaryDataStoreVO>();
+            while (rs.next()) {
+                pools.add(toEntityBean(rs, false));
+            }
+            return pools;
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Unable to execute " + pstmt, e);
+        }
+    }
+
+    protected Map<String, String> tagsToDetails(String[] tags) {
+        Map<String, String> details = new HashMap<String, String>(tags.length);
+        for (String tag : tags) {
+            details.put(tag, "true");
+        }
+        return details;
+    }
+
+    @Override
+    public List<PrimaryDataStoreVO> findPoolsByTags(long dcId, long podId, Long clusterId, String[] tags, Boolean shared) {
+        List<PrimaryDataStoreVO> storagePools = null;
+        if (tags == null || tags.length == 0) {
+            storagePools = listBy(dcId, podId, clusterId);
+        } else {
+            Map<String, String> details = tagsToDetails(tags);
+            storagePools = findPoolsByDetails(dcId, podId, clusterId, details);
+        }
+
+        if (shared == null) {
+            return storagePools;
+        } else {
+            List<PrimaryDataStoreVO> filteredStoragePools = new ArrayList<PrimaryDataStoreVO>(storagePools);
+            for (PrimaryDataStoreVO pool : storagePools) {
+                /*
+                 * if (shared != pool.isShared()) {
+                 * filteredStoragePools.remove(pool); }
+                 */
+            }
+
+            return filteredStoragePools;
+        }
+    }
+
+    @Override
+    @DB
+    public List<String> searchForStoragePoolDetails(long poolId, String value) {
+
+        StringBuilder sql = new StringBuilder(FindPoolTagDetails);
+
+        Transaction txn = Transaction.currentTxn();
+        PreparedStatement pstmt = null;
+        try {
+            pstmt = txn.prepareAutoCloseStatement(sql.toString());
+            pstmt.setLong(1, poolId);
+            pstmt.setString(2, value);
+
+            ResultSet rs = pstmt.executeQuery();
+            List<String> tags = new ArrayList<String>();
+
+            while (rs.next()) {
+                tags.add(rs.getString("name"));
+            }
+            return tags;
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Unable to execute " + pstmt.toString(), e);
+        }
+
+    }
+
+    @Override
+    public void updateDetails(long poolId, Map<String, String> details) {
+        if (details != null) {
+            _detailsDao.update(poolId, details);
+        }
+    }
+
+    @Override
+    public Map<String, String> getDetails(long poolId) {
+        return _detailsDao.getDetails(poolId);
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        super.configure(name, params);
+        _detailsDao.configure("DetailsDao", params);
+        return true;
+    }
+
+    @Override
+    public long countPoolsByStatus(DataStoreStatus... statuses) {
+        SearchCriteria<Long> sc = StatusCountSearch.create();
+
+        sc.setParameters("status", (Object[]) statuses);
+
+        List<Long> rs = customSearchIncludingRemoved(sc, null);
+        if (rs.size() == 0) {
+            return 0;
+        }
+
+        return rs.get(0);
+    }
+
+    @Override
+    public List<PrimaryDataStoreVO> listPoolsByCluster(long clusterId) {
+        SearchCriteria<PrimaryDataStoreVO> sc = AllFieldSearch.create();
+        sc.setParameters("clusterId", clusterId);
+
+        return listBy(sc);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a2f86003/engine/storage/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailVO.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailVO.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailVO.java
new file mode 100644
index 0000000..d1f802d
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailVO.java
@@ -0,0 +1,79 @@
+// 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.db;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name="storage_pool_details")
+public class PrimaryDataStoreDetailVO {
+    @Id
+    @GeneratedValue(strategy=GenerationType.IDENTITY)
+    @Column(name="id")
+    long id;
+    
+    @Column(name="pool_id")
+    long poolId;
+    
+    @Column(name="name")
+    String name;
+    
+    @Column(name="value")
+    String value;
+    
+    public PrimaryDataStoreDetailVO(long poolId, String name, String value) {
+        this.poolId = poolId;
+        this.name = name;
+        this.value = value;
+    }
+   
+    public long getId() {
+        return id;
+    }
+
+    public long getPoolId() {
+        return poolId;
+    }
+
+    public void setPoolId(long poolId) {
+        this.poolId = poolId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    protected PrimaryDataStoreDetailVO() {
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a2f86003/engine/storage/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailsDao.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailsDao.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailsDao.java
new file mode 100644
index 0000000..906742b
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailsDao.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.datastore.db;
+
+import java.util.Map;
+
+import com.cloud.storage.StoragePoolDetailVO;
+import com.cloud.utils.db.GenericDao;
+
+public interface PrimaryDataStoreDetailsDao extends GenericDao<PrimaryDataStoreDetailVO, Long> {
+    
+    void update(long poolId, Map<String, String> details);
+    Map<String, String> getDetails(long poolId);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a2f86003/engine/storage/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailsDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailsDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailsDaoImpl.java
new file mode 100644
index 0000000..59c488c
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailsDaoImpl.java
@@ -0,0 +1,71 @@
+// 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.db;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.springframework.stereotype.Component;
+
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.Transaction;
+
+@Component
+public class PrimaryDataStoreDetailsDaoImpl extends GenericDaoBase<PrimaryDataStoreDetailVO, Long> implements PrimaryDataStoreDetailsDao {
+    
+    protected final SearchBuilder<PrimaryDataStoreDetailVO> PoolSearch = null;
+    
+    protected PrimaryDataStoreDetailsDaoImpl() {
+        /*
+        super();
+        PoolSearch = createSearchBuilder();
+        PoolSearch.and("pool", PoolSearch.entity().getPoolId(), SearchCriteria.Op.EQ);
+        PoolSearch.done();
+        */
+    }
+    
+    @Override
+    public void update(long poolId, Map<String, String> details) {
+        Transaction txn = Transaction.currentTxn();
+        SearchCriteria<PrimaryDataStoreDetailVO> sc = PoolSearch.create();
+        sc.setParameters("pool", poolId);
+        
+        txn.start();
+        expunge(sc);
+        for (Map.Entry<String, String> entry : details.entrySet()) {
+            PrimaryDataStoreDetailVO detail = new PrimaryDataStoreDetailVO(poolId, entry.getKey(), entry.getValue());
+            persist(detail);
+        }
+        txn.commit();
+    }
+    
+    @Override
+    public Map<String, String> getDetails(long poolId) {
+    	SearchCriteria<PrimaryDataStoreDetailVO> sc = PoolSearch.create();
+    	sc.setParameters("pool", poolId);
+    	
+    	List<PrimaryDataStoreDetailVO> details = listBy(sc);
+    	Map<String, String> detailsMap = new HashMap<String, String>();
+    	for (PrimaryDataStoreDetailVO detail : details) {
+    		detailsMap.put(detail.getName(), detail.getValue());
+    	}
+    	
+    	return detailsMap;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a2f86003/engine/storage/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreVO.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreVO.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreVO.java
new file mode 100644
index 0000000..19e1990
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreVO.java
@@ -0,0 +1,266 @@
+/*
+ * 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.db;
+
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.TableGenerator;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType;
+import org.apache.cloudstack.storage.datastore.DataStoreStatus;
+
+import com.cloud.utils.db.GenericDao;
+
+@Entity
+@Table(name = "storage_pool")
+public class PrimaryDataStoreVO implements Identity {
+    @Id
+    @TableGenerator(name = "storage_pool_sq", table = "sequence", pkColumnName = "name", valueColumnName = "value", pkColumnValue = "storage_pool_seq", allocationSize = 1)
+    @Column(name = "id", updatable = false, nullable = false)
+    private long id;
+
+    @Column(name = "name", updatable = false, nullable = false, length = 255)
+    private String name = null;
+
+    @Column(name = "uuid", length = 255)
+    private String uuid = null;
+
+    @Column(name = "pool_type", updatable = false, nullable = false, length = 32)
+    private String poolType;
+
+    @Column(name = GenericDao.CREATED_COLUMN)
+    Date created;
+
+    @Column(name = GenericDao.REMOVED_COLUMN)
+    private Date removed;
+
+    @Column(name = "update_time", updatable = true)
+    @Temporal(value = TemporalType.TIMESTAMP)
+    private Date updateTime;
+
+    @Column(name = "data_center_id", updatable = true, nullable = false)
+    private long dataCenterId;
+
+    @Column(name = "pod_id", updatable = true)
+    private Long podId;
+
+    @Column(name = "available_bytes", updatable = true, nullable = true)
+    private long availableBytes;
+
+    @Column(name = "capacity_bytes", updatable = true, nullable = true)
+    private long capacityBytes;
+
+    @Column(name = "status", updatable = true, nullable = false)
+    @Enumerated(value = EnumType.STRING)
+    private DataStoreStatus status;
+
+    @Column(name = "storage_provider_id", updatable = true, nullable = false)
+    private Long storageProviderId;
+
+    @Column(name = "host_address")
+    private String hostAddress;
+
+    @Column(name = "path")
+    private String path;
+
+    @Column(name = "port")
+    private int port;
+
+    @Column(name = "user_info")
+    private String userInfo;
+
+    @Column(name = "cluster_id")
+    private Long clusterId;
+
+    @Column(name = "scope")
+    private ScopeType scope;
+
+    public long getId() {
+        return id;
+    }
+
+    public DataStoreStatus getStatus() {
+        return status;
+    }
+
+    public PrimaryDataStoreVO() {
+        this.status = DataStoreStatus.Initial;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String getUuid() {
+        return uuid;
+    }
+
+    public String getPoolType() {
+        return poolType;
+    }
+
+    public void setPoolType(String protocol) {
+        this.poolType = protocol;
+    }
+
+    public Date getCreated() {
+        return created;
+    }
+
+    public Date getRemoved() {
+        return removed;
+    }
+
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    public long getDataCenterId() {
+        return dataCenterId;
+    }
+
+    public long getAvailableBytes() {
+        return availableBytes;
+    }
+
+    public Long getStorageProviderId() {
+        return storageProviderId;
+    }
+
+    public void setStorageProviderId(Long provider) {
+        storageProviderId = provider;
+    }
+
+    public long getCapacityBytes() {
+        return capacityBytes;
+    }
+
+    public void setAvailableBytes(long available) {
+        availableBytes = available;
+    }
+
+    public void setCapacityBytes(long capacity) {
+        capacityBytes = capacity;
+    }
+
+    public Long getClusterId() {
+        return clusterId;
+    }
+
+    public void setClusterId(Long clusterId) {
+        this.clusterId = clusterId;
+    }
+
+    public String getHostAddress() {
+        return hostAddress;
+    }
+
+    public void setHostAddress(String host) {
+        this.hostAddress = host;
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    public String getUserInfo() {
+        return userInfo;
+    }
+
+    public void setStatus(DataStoreStatus status) {
+        this.status = status;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    public void setDataCenterId(long dcId) {
+        this.dataCenterId = dcId;
+    }
+
+    public void setPodId(Long podId) {
+        this.podId = podId;
+    }
+
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+
+    public void setPath(String path) {
+        this.path = path;
+    }
+
+    public void setUserInfo(String userInfo) {
+        this.userInfo = userInfo;
+    }
+
+    public int getPort() {
+        return port;
+    }
+
+    public void setPort(int port) {
+        this.port = port;
+    }
+
+    public Long getPodId() {
+        return podId;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public void setScope(ScopeType scope) {
+        this.scope = scope;
+    }
+
+    public ScopeType getScope() {
+        return this.scope;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof PrimaryDataStoreVO) || obj == null) {
+            return false;
+        }
+        PrimaryDataStoreVO that = (PrimaryDataStoreVO) obj;
+        return this.id == that.id;
+    }
+
+    @Override
+    public int hashCode() {
+        return new Long(id).hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return new StringBuilder("Pool[").append(id).append("|").append(poolType).append("]").toString();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a2f86003/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProvider.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProvider.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProvider.java
new file mode 100644
index 0000000..0d38f34
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProvider.java
@@ -0,0 +1,32 @@
+/*
+ * 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.Map;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle;
+
+public interface DataStoreProvider {
+    public DataStoreLifeCycle getLifeCycle();
+    public String getName();
+    public String getUuid();
+    public long getId();
+    public boolean configure(Map<String, Object> params);
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a2f86003/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManager.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManager.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManager.java
new file mode 100644
index 0000000..cbe045c
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManager.java
@@ -0,0 +1,30 @@
+/*
+ * 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 com.cloud.utils.component.Manager;
+
+public interface DataStoreProviderManager extends Manager {
+    public DataStoreProvider getDataStoreProviderByUuid(String uuid);
+    public DataStoreProvider getDataStoreProviderById(long id);
+    public DataStoreProvider getDataStoreProvider(String name);
+    public List<DataStoreProvider> getDataStoreProviders();
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a2f86003/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java
new file mode 100644
index 0000000..1276825
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java
@@ -0,0 +1,108 @@
+/*
+ * 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.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.storage.datastore.db.DataStoreProviderDao;
+import org.apache.cloudstack.storage.datastore.db.DataStoreProviderVO;
+import org.springframework.stereotype.Component;
+
+@Component
+public class DataStoreProviderManagerImpl implements DataStoreProviderManager {
+    @Inject
+    List<DataStoreProvider> providers;
+    @Inject
+    DataStoreProviderDao providerDao;
+    protected Map<String, DataStoreProvider> providerMap = new HashMap<String, DataStoreProvider>();
+    @Override
+    public DataStoreProvider getDataStoreProviderByUuid(String uuid) {
+        return providerMap.get(uuid);
+    }
+
+    @Override
+    public DataStoreProvider getDataStoreProvider(String name) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public List<DataStoreProvider> getDataStoreProviders() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params)
+            throws ConfigurationException {
+        //TODO: hold global lock
+        List<DataStoreProviderVO> providerVos = providerDao.listAll();
+        for (DataStoreProvider provider : providers) {
+            boolean existingProvider = false;
+            DataStoreProviderVO providerVO = null;
+            for (DataStoreProviderVO prov : providerVos) {
+                if (prov.getName().equalsIgnoreCase(provider.getName())) {
+                    existingProvider = true;
+                    providerVO = prov;
+                    break;
+                }
+            }
+            String uuid = provider.getUuid();
+            if (!existingProvider) {
+                uuid = UUID.nameUUIDFromBytes(provider.getName().getBytes()).toString();
+                providerVO = new DataStoreProviderVO();
+                providerVO.setName(provider.getName());
+                providerVO.setUuid(uuid);
+                providerVO = providerDao.persist(providerVO);
+            }
+            params.put("uuid", uuid);
+            params.put("id", providerVO.getId());
+            provider.configure(params);
+            providerMap.put(uuid, provider);
+        }
+        return true;
+    }
+
+    @Override
+    public boolean start() {
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    @Override
+    public String getName() {
+        return "Data store provider manager";
+    }
+
+    @Override
+    public DataStoreProvider getDataStoreProviderById(long id) {
+        DataStoreProviderVO provider = providerDao.findById(id);
+        return providerMap.get(provider.getUuid());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a2f86003/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/ImageDataStoreProvider.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/ImageDataStoreProvider.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/ImageDataStoreProvider.java
new file mode 100644
index 0000000..502158c
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/ImageDataStoreProvider.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.storage.datastore.provider;
+
+public interface ImageDataStoreProvider extends DataStoreProvider {
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a2f86003/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/PrimaryDataStoreProvider.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/PrimaryDataStoreProvider.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/PrimaryDataStoreProvider.java
new file mode 100644
index 0000000..ffaf897
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/PrimaryDataStoreProvider.java
@@ -0,0 +1,5 @@
+package org.apache.cloudstack.storage.datastore.provider;
+
+
+public interface PrimaryDataStoreProvider extends DataStoreProvider {
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a2f86003/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreDaoImpl.java
index 9932b48..dd0b2c6 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreDaoImpl.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreDaoImpl.java
@@ -4,10 +4,11 @@ package org.apache.cloudstack.storage.db;
 
 import org.apache.cloudstack.storage.volume.ObjectInDataStoreStateMachine.Event;
 import org.apache.cloudstack.storage.volume.ObjectInDataStoreStateMachine.State;
+import org.springframework.stereotype.Component;
 
 import com.cloud.utils.db.GenericDaoBase;
 
-
+@Component
 public class ObjectInDataStoreDaoImpl extends GenericDaoBase<ObjectInDataStoreVO, Long> implements ObjectInDataStoreDao {
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a2f86003/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java b/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java
index 2b92f6d..cdc8f87 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java
@@ -13,12 +13,17 @@ import javax.persistence.Table;
 import javax.persistence.Temporal;
 import javax.persistence.TemporalType;
 
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole;
+import org.apache.cloudstack.storage.volume.ObjectInDataStoreStateMachine;
+
 import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
 import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.fsm.StateObject;
 
 @Entity
 @Table(name = "object_datastore_ref")
-public class ObjectInDataStoreVO {
+public class ObjectInDataStoreVO implements StateObject<ObjectInDataStoreStateMachine.State> {
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     long id;
@@ -26,14 +31,16 @@ public class ObjectInDataStoreVO {
     @Column(name = "datastore_id")
     private long dataStoreId;
     
-    @Column(name = "datastore_type")
-    private String dataStoreType;
+    @Column(name = "datastore_role")
+    @Enumerated(EnumType.STRING)
+    private DataStoreRole dataStoreRole;
 
     @Column(name = "ojbect_id")
     long objectId;
     
     @Column(name = "object_type")
-    String objectType;
+    @Enumerated(EnumType.STRING)
+    DataObjectType objectType;
 
     @Column(name = GenericDaoBase.CREATED_COLUMN)
     Date created = null;
@@ -65,11 +72,16 @@ public class ObjectInDataStoreVO {
     long size;
     
     @Column(name = "state")
-    String state;
+    @Enumerated(EnumType.STRING)
+    ObjectInDataStoreStateMachine.State state;
 
     @Column(name="update_count", updatable = true, nullable=false)
     protected long updatedCount;
     
+    public ObjectInDataStoreVO() {
+        this.state = ObjectInDataStoreStateMachine.State.Allocated;
+    }
+    
     public long getId() {
         return this.id;
     }
@@ -82,12 +94,12 @@ public class ObjectInDataStoreVO {
         this.dataStoreId = id;
     }
     
-    public String getDataStoreType() {
-        return this.dataStoreType;
+    public DataStoreRole getDataStoreRole() {
+        return this.dataStoreRole;
     }
     
-    public void setDataStoreType(String type) {
-        this.dataStoreType = type;
+    public void setDataStoreRole(DataStoreRole role) {
+        this.dataStoreRole = role;
     }
     
     public long getObjectId() {
@@ -98,11 +110,24 @@ public class ObjectInDataStoreVO {
         this.objectId = id;
     }
     
-    public String getObjectType() {
+    public DataObjectType getObjectType() {
         return this.objectType;
     }
     
-    public void setObjectType(String type) {
+    public void setObjectType(DataObjectType type) {
         this.objectType = type;
     }
+
+    @Override
+    public ObjectInDataStoreStateMachine.State getState() {
+        return this.state;
+    }
+    
+    public void setInstallPath(String path) {
+        this.installPath = path;
+    }
+    
+    public String getInstallPath() {
+        return this.installPath;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a2f86003/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java
new file mode 100644
index 0000000..5d1e1ff
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java
@@ -0,0 +1,149 @@
+/*
+ * 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.endpoint;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import javax.inject.Inject;
+
+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.DataStoreRole;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
+import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
+import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType;
+import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat;
+import org.apache.cloudstack.storage.HypervisorHostEndPoint;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Transaction;
+
+@Component
+public class DefaultEndPointSelector implements EndPointSelector {
+    private static final Logger s_logger = Logger
+            .getLogger(DefaultEndPointSelector.class);
+    @Inject
+    HostDao hostDao;
+    private String findOneHostInaScope = "select id from host where "
+            + " status == 'Up' and hypervisor_type != 'VMware' and type in ('Routing', 'SecondaryStorageVM') ";
+
+    protected boolean moveBetweenPrimaryImage(DataStore srcStore,
+            DataStore destStore) {
+        DataStoreRole srcRole = srcStore.getRole();
+        DataStoreRole destRole = destStore.getRole();
+        if ((srcRole == DataStoreRole.Primary && destRole.isImageStore())
+                || (srcRole.isImageStore() && destRole == DataStoreRole.Primary)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    @DB
+    protected EndPoint findEndPointInScope(Scope scope) {
+        StringBuilder sbuilder = new StringBuilder();
+        sbuilder.append(findOneHostInaScope);
+
+        if (scope.getScopeType() == ScopeType.HOST) {
+            sbuilder.append(" and id = ");
+            sbuilder.append(scope.getScopeId());
+        } else if (scope.getScopeType() == ScopeType.CLUSTER) {
+            sbuilder.append(" and cluster_id = ");
+            sbuilder.append(scope.getScopeId());
+        } else if (scope.getScopeType() == ScopeType.ZONE) {
+            sbuilder.append(" and data_center_id = ");
+            sbuilder.append(scope.getScopeId());
+        }
+
+        sbuilder.append(" ORDER by rand() limit 1");
+        String sql = sbuilder.toString();
+        PreparedStatement pstmt = null;
+        ResultSet rs = null;
+        HostVO host = null;
+        Transaction txn = Transaction.currentTxn();
+
+        try {
+            pstmt = txn.prepareStatement(sql);
+            rs = pstmt.executeQuery();
+            while (rs.next()) {
+                long id = rs.getLong(1);
+                host = hostDao.findById(id);
+            }
+        } catch (SQLException e) {
+            s_logger.warn("can't find endpoint", e);
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (pstmt != null) {
+                    pstmt.close();
+                }
+            } catch (SQLException e) {
+            }
+        }
+
+        if (host == null) {
+            return null;
+        }
+
+        return new HypervisorHostEndPoint(host.getId(),
+                host.getPrivateIpAddress());
+    }
+
+    protected EndPoint findEndPointForImageMove(DataStore srcStore,
+            DataStore destStore) {
+        // find any xen/kvm host in the scope
+        Scope srcScope = srcStore.getScope();
+        Scope destScope = destStore.getScope();
+        Scope selectedScope = null;
+        // assumption, at least one of scope should be zone, find the least
+        // scope
+        if (srcScope.getScopeType() != ScopeType.ZONE) {
+            selectedScope = srcScope;
+        } else if (destScope.getScopeType() != ScopeType.ZONE) {
+            selectedScope = destScope;
+        } else {
+            // if both are zone scope
+            selectedScope = srcScope;
+        }
+        return findEndPointInScope(selectedScope);
+    }
+
+    @Override
+    public EndPoint select(DataObject srcData, DataObject destData) {
+        DataStore srcStore = srcData.getDataStore();
+        DataStore destStore = destData.getDataStore();
+        if (srcData.getFormat() == DiskFormat.VMDK
+                || destData.getFormat() == DiskFormat.VMDK) {
+            // If any of data is for vmware, data moving should go to ssvm
+
+        } else if (moveBetweenPrimaryImage(srcStore, destStore)) {
+            return findEndPointForImageMove(srcStore, destStore);
+        }
+        // TODO Auto-generated method stub
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a2f86003/engine/storage/src/org/apache/cloudstack/storage/endpoint/EndPointSelector.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/endpoint/EndPointSelector.java b/engine/storage/src/org/apache/cloudstack/storage/endpoint/EndPointSelector.java
new file mode 100644
index 0000000..274c5dc
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/endpoint/EndPointSelector.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.endpoint;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
+
+public interface EndPointSelector {
+    public EndPoint select(DataObject srcData, DataObject destData);
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a2f86003/engine/storage/src/org/apache/cloudstack/storage/image/ImageDataFactory.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/ImageDataFactory.java b/engine/storage/src/org/apache/cloudstack/storage/image/ImageDataFactory.java
new file mode 100644
index 0000000..7c7c2a8
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/image/ImageDataFactory.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.image;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+
+public interface ImageDataFactory {
+    TemplateInfo getTemplate(long templateId, DataStore store);
+}