cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bfede...@apache.org
Subject [33/90] [abbrv] [partial] Moved most of the VOs and DAOs from server package into engine-schema as well
Date Wed, 08 May 2013 17:48:57 GMT
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/572e71e5/engine/schema/src/com/cloud/storage/dao/VMTemplatePoolDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplatePoolDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VMTemplatePoolDaoImpl.java
new file mode 100644
index 0000000..5f212eb
--- /dev/null
+++ b/engine/schema/src/com/cloud/storage/dao/VMTemplatePoolDaoImpl.java
@@ -0,0 +1,304 @@
+// 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.storage.dao;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import javax.ejb.Local;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.storage.VMTemplateStoragePoolVO;
+import com.cloud.storage.VMTemplateStorageResourceAssoc;
+import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.UpdateBuilder;
+
+@Component
+@Local(value={VMTemplatePoolDao.class})
+public class VMTemplatePoolDaoImpl extends GenericDaoBase<VMTemplateStoragePoolVO, Long> implements VMTemplatePoolDao {
+	public static final Logger s_logger = Logger.getLogger(VMTemplatePoolDaoImpl.class.getName());
+	
+	protected final SearchBuilder<VMTemplateStoragePoolVO> PoolSearch;
+	protected final SearchBuilder<VMTemplateStoragePoolVO> TemplateSearch;
+	protected final SearchBuilder<VMTemplateStoragePoolVO> PoolTemplateSearch;
+	protected final SearchBuilder<VMTemplateStoragePoolVO> TemplateStatusSearch;
+    protected final SearchBuilder<VMTemplateStoragePoolVO> TemplatePoolStatusSearch;
+	protected final SearchBuilder<VMTemplateStoragePoolVO> TemplateStatesSearch;
+	protected final SearchBuilder<VMTemplateStoragePoolVO> updateStateSearch;
+	
+	protected static final String UPDATE_TEMPLATE_HOST_REF =
+		"UPDATE template_spool_ref SET download_state = ?, download_pct= ?, last_updated = ? "
+	+   ", error_str = ?, local_path = ?, job_id = ? "
+	+   "WHERE pool_id = ? and template_id = ?";
+	
+	protected static final String DOWNLOADS_STATE_DC=
+		"SELECT * FROM template_spool_ref t, storage_pool p where t.pool_id = p.id and p.data_center_id=? "
+	+	" and t.template_id=? and t.download_state = ?" ;
+	
+	protected static final String DOWNLOADS_STATE_DC_POD=
+		"SELECT * FROM template_spool_ref tp, storage_pool_host_ref ph, host h where tp.pool_id = ph.pool_id and ph.host_id = h.id and h.data_center_id=? and h.pod_id=? "
+	+	" and tp.template_id=? and tp.download_state=?" ;
+	
+	protected static final String HOST_TEMPLATE_SEARCH=
+		"SELECT * FROM template_spool_ref tp, storage_pool_host_ref ph, host h where tp.pool_id = ph.pool_id and ph.host_id = h.id and h.id=? "
+	+	" and tp.template_id=? " ;
+	
+	
+	public VMTemplatePoolDaoImpl () {
+		PoolSearch = createSearchBuilder();
+		PoolSearch.and("pool_id", PoolSearch.entity().getPoolId(), SearchCriteria.Op.EQ);
+		PoolSearch.done();
+		
+		TemplateSearch = createSearchBuilder();
+		TemplateSearch.and("template_id", TemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
+		TemplateSearch.done();
+		
+		PoolTemplateSearch = createSearchBuilder();
+		PoolTemplateSearch.and("pool_id", PoolTemplateSearch.entity().getPoolId(), SearchCriteria.Op.EQ);
+		PoolTemplateSearch.and("template_id", PoolTemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
+		PoolTemplateSearch.done();
+		
+		TemplateStatusSearch = createSearchBuilder();
+		TemplateStatusSearch.and("template_id", TemplateStatusSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
+		TemplateStatusSearch.and("download_state", TemplateStatusSearch.entity().getDownloadState(), SearchCriteria.Op.EQ);
+		TemplateStatusSearch.done();
+
+		TemplatePoolStatusSearch = createSearchBuilder();
+		TemplatePoolStatusSearch.and("pool_id", TemplatePoolStatusSearch.entity().getPoolId(), SearchCriteria.Op.EQ);
+		TemplatePoolStatusSearch.and("template_id", TemplatePoolStatusSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
+		TemplatePoolStatusSearch.and("download_state", TemplatePoolStatusSearch.entity().getDownloadState(), SearchCriteria.Op.EQ);
+		TemplatePoolStatusSearch.done();
+
+        TemplateStatesSearch = createSearchBuilder();
+		TemplateStatesSearch.and("template_id", TemplateStatesSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
+		TemplateStatesSearch.and("states", TemplateStatesSearch.entity().getDownloadState(), SearchCriteria.Op.IN);
+		TemplateStatesSearch.done();
+
+		updateStateSearch = this.createSearchBuilder();
+		updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ);
+		updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ);
+		updateStateSearch.and("updatedCount", updateStateSearch.entity().getUpdatedCount(), Op.EQ);
+		updateStateSearch.done();
+	}
+
+	@Override
+	public List<VMTemplateStoragePoolVO> listByPoolId(long id) {
+	    SearchCriteria<VMTemplateStoragePoolVO> sc = PoolSearch.create();
+	    sc.setParameters("pool_id", id);
+	    return listIncludingRemovedBy(sc);
+	}
+
+	@Override
+	public List<VMTemplateStoragePoolVO> listByTemplateId(long templateId) {
+	    SearchCriteria<VMTemplateStoragePoolVO> sc = TemplateSearch.create();
+	    sc.setParameters("template_id", templateId);
+	    return listIncludingRemovedBy(sc);
+	}
+
+	@Override
+	public VMTemplateStoragePoolVO findByPoolTemplate(long hostId, long templateId) {
+		SearchCriteria<VMTemplateStoragePoolVO> sc = PoolTemplateSearch.create();
+	    sc.setParameters("pool_id", hostId);
+	    sc.setParameters("template_id", templateId);
+	    return findOneIncludingRemovedBy(sc);
+	}
+
+	@Override
+	public List<VMTemplateStoragePoolVO> listByTemplateStatus(long templateId, VMTemplateStoragePoolVO.Status downloadState) {
+		SearchCriteria<VMTemplateStoragePoolVO> sc = TemplateStatusSearch.create();
+		sc.setParameters("template_id", templateId);
+		sc.setParameters("download_state", downloadState.toString());
+		return listIncludingRemovedBy(sc);
+	}
+
+	@Override
+    public List<VMTemplateStoragePoolVO> listByTemplateStatus(long templateId, VMTemplateStoragePoolVO.Status downloadState, long poolId) {
+        SearchCriteria<VMTemplateStoragePoolVO> sc = TemplatePoolStatusSearch.create();
+        sc.setParameters("pool_id", poolId);
+        sc.setParameters("template_id", templateId);
+        sc.setParameters("download_state", downloadState.toString());
+        return listIncludingRemovedBy(sc);
+    }
+
+	@Override
+	public List<VMTemplateStoragePoolVO> listByTemplateStatus(long templateId, long datacenterId, VMTemplateStoragePoolVO.Status downloadState) {
+        Transaction txn = Transaction.currentTxn();
+		PreparedStatement pstmt = null;
+		List<VMTemplateStoragePoolVO> result = new ArrayList<VMTemplateStoragePoolVO>();
+		try {
+			String sql = DOWNLOADS_STATE_DC;
+			pstmt = txn.prepareAutoCloseStatement(sql);
+			pstmt.setLong(1, datacenterId);
+			pstmt.setLong(2, templateId);
+			pstmt.setString(3, downloadState.toString());
+			ResultSet rs = pstmt.executeQuery();
+			while (rs.next()) {
+                result.add(toEntityBean(rs, false));
+            }
+		} catch (Exception e) {
+			s_logger.warn("Exception: ", e);
+		}
+		return result;
+
+	}
+	
+	@Override
+	public List<VMTemplateStoragePoolVO> listByTemplateStatus(long templateId, long datacenterId, long podId, VMTemplateStoragePoolVO.Status downloadState) {
+        Transaction txn = Transaction.currentTxn();
+		PreparedStatement pstmt = null;
+		List<VMTemplateStoragePoolVO> result = new ArrayList<VMTemplateStoragePoolVO>();
+		ResultSet rs = null;
+		try {
+			String sql = DOWNLOADS_STATE_DC_POD;
+			pstmt = txn.prepareStatement(sql);
+			
+			pstmt.setLong(1, datacenterId);
+			pstmt.setLong(2, podId);
+			pstmt.setLong(3, templateId);
+			pstmt.setString(4, downloadState.toString());
+			rs = pstmt.executeQuery();
+			while (rs.next()) {
+                // result.add(toEntityBean(rs, false)); TODO: this is buggy in GenericDaoBase for hand constructed queries
+				long id = rs.getLong(1); //ID column
+				result.add(findById(id));
+            }
+		} catch (Exception e) {
+			s_logger.warn("Exception: ", e);
+		} finally {
+			try {
+				if (rs != null) {
+					rs.close();
+				}
+				if (pstmt != null) {
+					pstmt.close();
+				}
+			} catch (SQLException e) {
+			}
+		}
+		return result;
+
+	}
+	
+	public List<VMTemplateStoragePoolVO> listByHostTemplate(long hostId, long templateId) {
+        Transaction txn = Transaction.currentTxn();
+		PreparedStatement pstmt = null;
+		List<VMTemplateStoragePoolVO> result = new ArrayList<VMTemplateStoragePoolVO>();
+		ResultSet rs = null;
+		try {
+			String sql = HOST_TEMPLATE_SEARCH;
+			pstmt = txn.prepareStatement(sql);
+			
+			pstmt.setLong(1, hostId);
+			pstmt.setLong(2, templateId);
+			rs = pstmt.executeQuery();
+			while (rs.next()) {
+                // result.add(toEntityBean(rs, false)); TODO: this is buggy in GenericDaoBase for hand constructed queries
+				long id = rs.getLong(1); //ID column
+				result.add(findById(id));
+            }
+		} catch (Exception e) {
+			s_logger.warn("Exception: ", e);
+		} finally {
+			try {
+				if (rs != null) {
+					rs.close();
+				}
+				if (pstmt != null) {
+					pstmt.close();
+				}
+			} catch (SQLException e) {
+			}
+		}
+		return result;
+
+	}
+
+	@Override
+	public boolean templateAvailable(long templateId, long hostId) {
+		VMTemplateStorageResourceAssoc tmpltPool = findByPoolTemplate(hostId, templateId);
+		if (tmpltPool == null)
+		  return false;
+		
+		return tmpltPool.getDownloadState()==Status.DOWNLOADED;
+	}
+
+	@Override
+	public List<VMTemplateStoragePoolVO> listByTemplateStates(long templateId, VMTemplateStoragePoolVO.Status... states) {
+    	SearchCriteria<VMTemplateStoragePoolVO> sc = TemplateStatesSearch.create();
+    	sc.setParameters("states", (Object[])states);
+		sc.setParameters("template_id", templateId);
+
+	  	return search(sc, null);
+	}
+
+	@Override
+	public VMTemplateStoragePoolVO findByHostTemplate(Long hostId, Long templateId) {
+		List<VMTemplateStoragePoolVO> result = listByHostTemplate(hostId, templateId);
+		return (result.size() == 0)?null:result.get(1);
+	}
+
+    @Override
+    public boolean updateState(State currentState, Event event,
+            State nextState, DataObjectInStore vo, Object data) {
+        VMTemplateStoragePoolVO templatePool = (VMTemplateStoragePoolVO)vo;
+        Long oldUpdated = templatePool.getUpdatedCount();
+        Date oldUpdatedTime = templatePool.getUpdated();
+    
+        SearchCriteria<VMTemplateStoragePoolVO> sc = updateStateSearch.create();
+        sc.setParameters("id", templatePool.getId());
+        sc.setParameters("state", currentState);
+        sc.setParameters("updatedCount", templatePool.getUpdatedCount());
+
+        templatePool.incrUpdatedCount();
+
+        UpdateBuilder builder = getUpdateBuilder(vo);
+        builder.set(vo, "state", nextState);
+        builder.set(vo, "updated", new Date());
+
+        int rows = update((VMTemplateStoragePoolVO) vo, sc);
+        if (rows == 0 && s_logger.isDebugEnabled()) {
+            VMTemplateStoragePoolVO dbVol = findByIdIncludingRemoved(templatePool.getId());
+            if (dbVol != null) {
+                StringBuilder str = new StringBuilder("Unable to update ").append(vo.toString());
+                str.append(": DB Data={id=").append(dbVol.getId()).append("; state=").append(dbVol.getState()).append("; updatecount=").append(dbVol.getUpdatedCount()).append(";updatedTime=")
+                        .append(dbVol.getUpdated());
+                str.append(": New Data={id=").append(templatePool.getId()).append("; state=").append(nextState).append("; event=").append(event).append("; updatecount=").append(templatePool.getUpdatedCount())
+                        .append("; updatedTime=").append(templatePool.getUpdated());
+                str.append(": stale Data={id=").append(templatePool.getId()).append("; state=").append(currentState).append("; event=").append(event).append("; updatecount=").append(oldUpdated)
+                        .append("; updatedTime=").append(oldUpdatedTime);
+            } else {
+                s_logger.debug("Unable to update objectIndatastore: id=" + templatePool.getId() + ", as there is no such object exists in the database anymore");
+            }
+        }
+        return rows > 0;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/572e71e5/engine/schema/src/com/cloud/storage/dao/VMTemplateS3Dao.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateS3Dao.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateS3Dao.java
new file mode 100644
index 0000000..d36fb3a
--- /dev/null
+++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateS3Dao.java
@@ -0,0 +1,36 @@
+/*
+ * 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.storage.dao;
+
+import com.cloud.storage.VMTemplateS3VO;
+import com.cloud.utils.db.GenericDao;
+
+import java.util.List;
+
+public interface VMTemplateS3Dao extends GenericDao<VMTemplateS3VO, Long> {
+
+    List<VMTemplateS3VO> listByS3Id(long id);
+
+    VMTemplateS3VO findOneByTemplateId(long id);
+
+    VMTemplateS3VO findOneByS3Template(long s3Id, long templateId);
+
+    void expungeAllByTemplateId(long templateId);
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/572e71e5/engine/schema/src/com/cloud/storage/dao/VMTemplateS3DaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateS3DaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateS3DaoImpl.java
new file mode 100644
index 0000000..7cfd3b5
--- /dev/null
+++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateS3DaoImpl.java
@@ -0,0 +1,105 @@
+/*
+ * 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.storage.dao;
+
+import static com.cloud.utils.db.SearchCriteria.Op.*;
+import static com.cloud.storage.VMTemplateS3VO.*;
+
+import com.cloud.storage.VMTemplateS3VO;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+
+import javax.ejb.Local;
+
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+@Component
+@Local(VMTemplateS3Dao.class)
+public class VMTemplateS3DaoImpl extends GenericDaoBase<VMTemplateS3VO, Long>
+        implements VMTemplateS3Dao {
+
+    private final SearchBuilder<VMTemplateS3VO> searchBuilder;
+
+    public VMTemplateS3DaoImpl() {
+
+        super();
+
+        this.searchBuilder = createSearchBuilder();
+        this.searchBuilder
+                .and(S3_ID_COLUMN_NAME, this.searchBuilder.entity().getS3Id(),
+                        EQ)
+                .and(TEMPLATE_ID_COLUMN_NAME,
+                        this.searchBuilder.entity().getTemplateId(), EQ).done();
+
+    }
+
+    @Override
+    public List<VMTemplateS3VO> listByS3Id(final long s3id) {
+
+        final SearchCriteria<VMTemplateS3VO> criteria = this.searchBuilder
+                .create();
+
+        criteria.setParameters(S3_ID_COLUMN_NAME, s3id);
+
+        return this.listBy(criteria);
+
+    }
+
+    @Override
+    public VMTemplateS3VO findOneByTemplateId(final long templateId) {
+
+        final SearchCriteria<VMTemplateS3VO> criteria = this.searchBuilder
+                .create();
+
+        criteria.setParameters(TEMPLATE_ID_COLUMN_NAME, templateId);
+
+        return this.findOneBy(criteria);
+
+    }
+
+    @Override
+    public VMTemplateS3VO findOneByS3Template(final long s3Id,
+            final long templateId) {
+
+        final SearchCriteria<VMTemplateS3VO> criteria = this.searchBuilder
+                .create();
+
+        criteria.setParameters(S3_ID_COLUMN_NAME, s3Id);
+        criteria.setParameters(TEMPLATE_ID_COLUMN_NAME, templateId);
+
+        return this.findOneBy(criteria);
+
+    }
+
+    @Override
+    public void expungeAllByTemplateId(long templateId) {
+
+        final SearchCriteria<VMTemplateS3VO> criteria = this.searchBuilder
+                .create();
+
+        criteria.setParameters(TEMPLATE_ID_COLUMN_NAME, templateId);
+
+        this.expunge(criteria);
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/572e71e5/engine/schema/src/com/cloud/storage/dao/VMTemplateSwiftDao.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateSwiftDao.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateSwiftDao.java
new file mode 100755
index 0000000..ec18189
--- /dev/null
+++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateSwiftDao.java
@@ -0,0 +1,37 @@
+// 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.storage.dao;
+
+import java.util.List;
+
+import com.cloud.storage.VMTemplateSwiftVO;
+import com.cloud.utils.db.GenericDao;
+
+/**
+ * 
+ * 
+ */
+
+public interface VMTemplateSwiftDao extends GenericDao<VMTemplateSwiftVO, Long> {
+    List<VMTemplateSwiftVO> listBySwiftId(long id);
+
+    List<VMTemplateSwiftVO> listByTemplateId(long templateId);
+
+    VMTemplateSwiftVO findBySwiftTemplate(long swiftId, long templateId);
+
+    VMTemplateSwiftVO findOneByTemplateId(long templateId);
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/572e71e5/engine/schema/src/com/cloud/storage/dao/VMTemplateSwiftDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateSwiftDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateSwiftDaoImpl.java
new file mode 100755
index 0000000..c65527a
--- /dev/null
+++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateSwiftDaoImpl.java
@@ -0,0 +1,87 @@
+// 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.storage.dao;
+
+import java.util.Collections;
+import java.util.List;
+
+import javax.ejb.Local;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.storage.VMTemplateSwiftVO;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+
+/**
+ * 
+ * 
+ */
+
+@Component
+@Local(value = { VMTemplateSwiftDao.class })
+public class VMTemplateSwiftDaoImpl extends GenericDaoBase<VMTemplateSwiftVO, Long> implements VMTemplateSwiftDao {
+    public static final Logger s_logger = Logger.getLogger(VMTemplateSwiftDaoImpl.class.getName());
+
+    protected final SearchBuilder<VMTemplateSwiftVO> AllFieldSearch;
+
+    public VMTemplateSwiftDaoImpl() {
+        AllFieldSearch = createSearchBuilder();
+        AllFieldSearch.and("swift_id", AllFieldSearch.entity().getSwiftId(), SearchCriteria.Op.EQ);
+        AllFieldSearch.and("template_id", AllFieldSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
+        AllFieldSearch.done();
+
+    }
+
+    @Override
+    public List<VMTemplateSwiftVO> listBySwiftId(long id) {
+        SearchCriteria<VMTemplateSwiftVO> sc = AllFieldSearch.create();
+        sc.setParameters("swift_id", id);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<VMTemplateSwiftVO> listByTemplateId(long templateId) {
+        SearchCriteria<VMTemplateSwiftVO> sc = AllFieldSearch.create();
+        sc.setParameters("template_id", templateId);
+        return listBy(sc);
+    }
+
+    @Override
+    public VMTemplateSwiftVO findOneByTemplateId(long templateId) {
+        SearchCriteria<VMTemplateSwiftVO> sc = AllFieldSearch.create();
+        sc.setParameters("template_id", templateId);
+        List<VMTemplateSwiftVO> list = listBy(sc);
+        if (list == null || list.size() < 1) {
+            return null;
+        } else {
+            Collections.shuffle(list);
+            return list.get(0);
+        }
+    }
+
+    @Override
+    public VMTemplateSwiftVO findBySwiftTemplate(long swiftId, long templateId) {
+        SearchCriteria<VMTemplateSwiftVO> sc = AllFieldSearch.create();
+        sc.setParameters("swift_id", swiftId);
+        sc.setParameters("template_id", templateId);
+        return findOneBy(sc);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/572e71e5/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDao.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDao.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDao.java
new file mode 100755
index 0000000..bb3aa01
--- /dev/null
+++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDao.java
@@ -0,0 +1,33 @@
+// 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.storage.dao;
+
+import java.util.List;
+
+import com.cloud.storage.VMTemplateZoneVO;
+import com.cloud.utils.db.GenericDao;
+
+public interface VMTemplateZoneDao extends GenericDao<VMTemplateZoneVO, Long> {
+	public List<VMTemplateZoneVO> listByZoneId(long id);
+	
+	public List<VMTemplateZoneVO> listByTemplateId(long templateId);
+	
+	public VMTemplateZoneVO findByZoneTemplate(long zoneId, long templateId);
+	
+    public List<VMTemplateZoneVO> listByZoneTemplate(Long zoneId, long templateId);
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/572e71e5/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDaoImpl.java
new file mode 100644
index 0000000..916e0ac
--- /dev/null
+++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDaoImpl.java
@@ -0,0 +1,89 @@
+// 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.storage.dao;
+
+import java.util.List;
+
+import javax.ejb.Local;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.storage.VMTemplateZoneVO;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+
+@Component
+@Local(value={VMTemplateZoneDao.class})
+public class VMTemplateZoneDaoImpl extends GenericDaoBase<VMTemplateZoneVO, Long> implements VMTemplateZoneDao {
+	public static final Logger s_logger = Logger.getLogger(VMTemplateZoneDaoImpl.class.getName());
+	
+	protected final SearchBuilder<VMTemplateZoneVO> ZoneSearch;
+	protected final SearchBuilder<VMTemplateZoneVO> TemplateSearch;
+	protected final SearchBuilder<VMTemplateZoneVO> ZoneTemplateSearch;
+	
+	
+	public VMTemplateZoneDaoImpl () {
+		ZoneSearch = createSearchBuilder();
+		ZoneSearch.and("zone_id", ZoneSearch.entity().getZoneId(), SearchCriteria.Op.EQ);
+		ZoneSearch.done();
+		
+		TemplateSearch = createSearchBuilder();
+		TemplateSearch.and("template_id", TemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
+		TemplateSearch.done();
+		
+		ZoneTemplateSearch = createSearchBuilder();
+		ZoneTemplateSearch.and("zone_id", ZoneTemplateSearch.entity().getZoneId(), SearchCriteria.Op.EQ);
+		ZoneTemplateSearch.and("template_id", ZoneTemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
+		ZoneTemplateSearch.done();
+	}
+	
+
+	@Override
+	public List<VMTemplateZoneVO> listByZoneId(long id) {
+	    SearchCriteria<VMTemplateZoneVO> sc = ZoneSearch.create();
+	    sc.setParameters("zone_id", id);
+	    return listIncludingRemovedBy(sc);
+	}
+
+	@Override
+	public List<VMTemplateZoneVO> listByTemplateId(long templateId) {
+	    SearchCriteria<VMTemplateZoneVO> sc = TemplateSearch.create();
+	    sc.setParameters("template_id", templateId);
+	    return listIncludingRemovedBy(sc);
+	}
+
+	@Override
+	public VMTemplateZoneVO findByZoneTemplate(long zoneId, long templateId) {
+		SearchCriteria<VMTemplateZoneVO> sc = ZoneTemplateSearch.create();
+	    sc.setParameters("zone_id", zoneId);
+	    sc.setParameters("template_id", templateId);
+	    return findOneIncludingRemovedBy(sc);
+	}
+
+	@Override
+    public List<VMTemplateZoneVO> listByZoneTemplate(Long zoneId, long templateId) {
+		SearchCriteria<VMTemplateZoneVO> sc = ZoneTemplateSearch.create();
+        if (zoneId != null) {
+            sc.setParameters("zone_id", zoneId);
+        }
+	    sc.setParameters("template_id", templateId);
+	    return listBy(sc);
+	}	
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/572e71e5/engine/schema/src/com/cloud/storage/dao/VolumeDao.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/storage/dao/VolumeDao.java b/engine/schema/src/com/cloud/storage/dao/VolumeDao.java
new file mode 100755
index 0000000..2513181
--- /dev/null
+++ b/engine/schema/src/com/cloud/storage/dao/VolumeDao.java
@@ -0,0 +1,92 @@
+// 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.storage.dao;
+
+import java.util.List;
+
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.utils.Pair;
+import com.cloud.utils.db.GenericDao;
+import com.cloud.utils.fsm.StateDao;
+
+public interface VolumeDao extends GenericDao<VolumeVO, Long>, StateDao<Volume.State, Volume.Event, Volume> {
+
+    List<VolumeVO> findDetachedByAccount(long accountId);
+
+    List<VolumeVO> findByAccount(long accountId);
+
+    Pair<Long, Long> getCountAndTotalByPool(long poolId);
+
+    Pair<Long, Long> getNonDestroyedCountAndTotalByPool(long poolId);
+
+    List<VolumeVO> findByInstance(long id);
+
+    List<VolumeVO> findByInstanceAndType(long id, Volume.Type vType);
+
+    List<VolumeVO> findByInstanceIdDestroyed(long vmId);
+
+    List<VolumeVO> findByAccountAndPod(long accountId, long podId);
+
+    List<VolumeVO> findByTemplateAndZone(long templateId, long zoneId);
+
+    void deleteVolumesByInstance(long instanceId);
+
+    void attachVolume(long volumeId, long vmId, long deviceId);
+
+    void detachVolume(long volumeId);
+
+    boolean isAnyVolumeActivelyUsingTemplateOnPool(long templateId, long poolId);
+
+    List<VolumeVO> findCreatedByInstance(long id);
+
+    List<VolumeVO> findByPoolId(long poolId);
+
+    List<VolumeVO> findByInstanceAndDeviceId(long instanceId, long deviceId);
+
+    List<VolumeVO> findUsableVolumesForInstance(long instanceId);
+
+    Long countAllocatedVolumesForAccount(long accountId); 
+
+    HypervisorType getHypervisorType(long volumeId);
+
+    List<VolumeVO> listVolumesToBeDestroyed();
+
+    ImageFormat getImageFormat(Long volumeId);
+
+    List<VolumeVO> findReadyRootVolumesByInstance(long instanceId);
+
+    List<Long> listPoolIdsByVolumeCount(long dcId, Long podId, Long clusterId, long accountId);
+
+    /**
+     * Gets the Total Primary Storage space allocated for an account
+     *
+     * @param account
+     * @return total Primary Storage space (in bytes) used
+     */
+    long primaryStorageUsedForAccount(long accountId);
+
+    /**
+     * Gets the Total Secondary Storage space used by volumes allocated for an account
+     *
+     * @param account
+     * @return total Secondary Storage space (in bytes) used
+     */
+    long secondaryStorageUsedForAccount(long accountId);
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/572e71e5/engine/schema/src/com/cloud/storage/dao/VolumeDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/storage/dao/VolumeDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VolumeDaoImpl.java
new file mode 100755
index 0000000..12ca3c7
--- /dev/null
+++ b/engine/schema/src/com/cloud/storage/dao/VolumeDaoImpl.java
@@ -0,0 +1,459 @@
+// 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.storage.dao;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.server.ResourceTag.TaggedResourceType;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Volume;
+import com.cloud.storage.Volume.Event;
+import com.cloud.storage.Volume.State;
+import com.cloud.storage.Volume.Type;
+import com.cloud.storage.VolumeVO;
+import com.cloud.tags.dao.ResourceTagDao;
+import com.cloud.utils.Pair;
+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.SearchCriteria.Func;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.UpdateBuilder;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+@Component
+@Local(value=VolumeDao.class)
+public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements VolumeDao {
+    private static final Logger s_logger = Logger.getLogger(VolumeDaoImpl.class);
+    protected final SearchBuilder<VolumeVO> DetachedAccountIdSearch;
+    protected final SearchBuilder<VolumeVO> TemplateZoneSearch;
+    protected final GenericSearchBuilder<VolumeVO, SumCount> TotalSizeByPoolSearch;
+    protected final GenericSearchBuilder<VolumeVO, Long> ActiveTemplateSearch;
+    protected final SearchBuilder<VolumeVO> InstanceStatesSearch;
+    protected final SearchBuilder<VolumeVO> AllFieldsSearch;
+    protected GenericSearchBuilder<VolumeVO, Long> CountByAccount;
+    protected GenericSearchBuilder<VolumeVO, SumCount> primaryStorageSearch;
+    protected GenericSearchBuilder<VolumeVO, SumCount> secondaryStorageSearch;
+    @Inject ResourceTagDao _tagsDao;
+
+    protected static final String SELECT_VM_SQL = "SELECT DISTINCT instance_id from volumes v where v.host_id = ? and v.mirror_state = ?";
+    protected static final String SELECT_HYPERTYPE_FROM_VOLUME = "SELECT c.hypervisor_type from volumes v, storage_pool s, cluster c where v.pool_id = s.id and s.cluster_id = c.id and v.id = ?";
+
+    private static final String ORDER_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT = "SELECT pool.id, SUM(IF(vol.state='Ready' AND vol.account_id = ?, 1, 0)) FROM `cloud`.`storage_pool` pool LEFT JOIN `cloud`.`volumes` vol ON pool.id = vol.pool_id WHERE pool.data_center_id = ? " +
+                                                                        " AND pool.pod_id = ? AND pool.cluster_id = ? " +
+                                                                        " GROUP BY pool.id ORDER BY 2 ASC ";
+    
+    @Override
+    public List<VolumeVO> findDetachedByAccount(long accountId) {
+    	SearchCriteria<VolumeVO> sc = DetachedAccountIdSearch.create();
+    	sc.setParameters("accountId", accountId);
+    	sc.setParameters("destroyed", Volume.State.Destroy);
+    	return listBy(sc);
+    }
+    
+    @Override
+    public List<VolumeVO> findByAccount(long accountId) {
+        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+        sc.setParameters("accountId", accountId);
+        sc.setParameters("state", Volume.State.Ready);
+        return listBy(sc);
+    }
+    
+    @Override
+    public List<VolumeVO> findByInstance(long id) {
+        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+        sc.setParameters("instanceId", id);
+	    return listBy(sc);
+	}
+   
+    @Override
+    public List<VolumeVO> findByInstanceAndDeviceId(long instanceId, long deviceId){
+    	SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+    	sc.setParameters("instanceId", instanceId);
+    	sc.setParameters("deviceId", deviceId);
+    	return listBy(sc);
+    }
+    
+    @Override
+    public List<VolumeVO> findByPoolId(long poolId) {
+        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+        sc.setParameters("poolId", poolId);
+        sc.setParameters("notDestroyed", Volume.State.Destroy);
+        sc.setParameters("vType", Volume.Type.ROOT.toString());
+	    return listBy(sc);
+	}
+    
+    @Override 
+    public List<VolumeVO> findCreatedByInstance(long id) {
+        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+        sc.setParameters("instanceId", id);
+        sc.setParameters("state", Volume.State.Ready);
+        return listBy(sc);
+    }
+    
+    @Override
+    public List<VolumeVO> findUsableVolumesForInstance(long instanceId) {
+        SearchCriteria<VolumeVO> sc = InstanceStatesSearch.create();
+        sc.setParameters("instance", instanceId);
+        sc.setParameters("states", Volume.State.Creating, Volume.State.Ready, Volume.State.Allocated);
+        
+        return listBy(sc);
+    }
+    
+	@Override
+	public List<VolumeVO> findByInstanceAndType(long id, Type vType) {
+        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+        sc.setParameters("instanceId", id);
+        sc.setParameters("vType", vType.toString());
+	    return listBy(sc);
+	}
+	
+	@Override
+	public List<VolumeVO> findByInstanceIdDestroyed(long vmId) {
+		SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+		sc.setParameters("instanceId", vmId);
+		sc.setParameters("destroyed", Volume.State.Destroy);
+		return listBy(sc);
+	}
+	
+	@Override
+	public List<VolumeVO> findReadyRootVolumesByInstance(long instanceId) {
+		SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+		sc.setParameters("instanceId", instanceId);
+		sc.setParameters("state", Volume.State.Ready);
+		sc.setParameters("vType", Volume.Type.ROOT);		
+		return listBy(sc);
+	}
+	
+	@Override
+	public List<VolumeVO> findByAccountAndPod(long accountId, long podId) {
+		SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+        sc.setParameters("accountId", accountId);
+        sc.setParameters("pod", podId);
+        sc.setParameters("state", Volume.State.Ready);
+        
+        return listIncludingRemovedBy(sc);
+	}
+	
+	@Override
+	public List<VolumeVO> findByTemplateAndZone(long templateId, long zoneId) {
+		SearchCriteria<VolumeVO> sc = TemplateZoneSearch.create();
+		sc.setParameters("template", templateId);
+		sc.setParameters("zone", zoneId);
+		
+		return listIncludingRemovedBy(sc);
+	}
+
+	@Override
+	public boolean isAnyVolumeActivelyUsingTemplateOnPool(long templateId, long poolId) {
+	    SearchCriteria<Long> sc = ActiveTemplateSearch.create();
+	    sc.setParameters("template", templateId);
+	    sc.setParameters("pool", poolId);
+	    
+	    List<Long> results = customSearchIncludingRemoved(sc, null);
+	    assert results.size() > 0 : "How can this return a size of " + results.size();
+	    
+	    return results.get(0) > 0;
+	}
+	
+    @Override
+    public void deleteVolumesByInstance(long instanceId) {
+        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+        sc.setParameters("instanceId", instanceId);
+        expunge(sc);
+    }
+    
+    @Override
+    public void attachVolume(long volumeId, long vmId, long deviceId) {
+    	VolumeVO volume = createForUpdate(volumeId);
+    	volume.setInstanceId(vmId);
+    	volume.setDeviceId(deviceId);
+    	volume.setUpdated(new Date());
+    	volume.setAttached(new Date());
+    	update(volumeId, volume);
+    }
+    
+    @Override
+    public void detachVolume(long volumeId) {
+    	VolumeVO volume = createForUpdate(volumeId);
+    	volume.setInstanceId(null);
+        volume.setDeviceId(null);
+    	volume.setUpdated(new Date());
+    	volume.setAttached(null);
+    	update(volumeId, volume);
+    }
+    
+    @Override
+    @DB
+	public HypervisorType getHypervisorType(long volumeId) {
+		/*lookup from cluster of pool*/
+    	 Transaction txn = Transaction.currentTxn();
+         PreparedStatement pstmt = null;
+
+         try {
+             String sql = SELECT_HYPERTYPE_FROM_VOLUME;
+             pstmt = txn.prepareAutoCloseStatement(sql);
+             pstmt.setLong(1, volumeId);
+             ResultSet rs = pstmt.executeQuery();
+             if (rs.next()) {
+                return HypervisorType.getType(rs.getString(1));
+            }
+             return HypervisorType.None;
+         } catch (SQLException e) {
+             throw new CloudRuntimeException("DB Exception on: " + SELECT_HYPERTYPE_FROM_VOLUME, e);
+         } catch (Throwable e) {
+             throw new CloudRuntimeException("Caught: " + SELECT_HYPERTYPE_FROM_VOLUME, e);
+         }
+	}
+    
+    @Override
+    public ImageFormat getImageFormat(Long volumeId) {
+        HypervisorType type = getHypervisorType(volumeId);
+        if ( type.equals(HypervisorType.KVM)) {
+            return ImageFormat.QCOW2;
+        } else if ( type.equals(HypervisorType.XenServer)) {
+            return ImageFormat.VHD;
+        } else if ( type.equals(HypervisorType.VMware)) {
+            return ImageFormat.OVA;
+        } else {
+            s_logger.warn("Do not support hypervisor " + type.toString());
+            return null;
+        }
+    }
+    
+	public VolumeDaoImpl() {
+	    AllFieldsSearch = createSearchBuilder();
+	    AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ);
+        AllFieldsSearch.and("accountId", AllFieldsSearch.entity().getAccountId(), Op.EQ);
+        AllFieldsSearch.and("pod", AllFieldsSearch.entity().getPodId(), Op.EQ);
+        AllFieldsSearch.and("instanceId", AllFieldsSearch.entity().getInstanceId(), Op.EQ);
+        AllFieldsSearch.and("deviceId", AllFieldsSearch.entity().getDeviceId(), Op.EQ);
+        AllFieldsSearch.and("poolId", AllFieldsSearch.entity().getPoolId(), Op.EQ);
+        AllFieldsSearch.and("vType", AllFieldsSearch.entity().getVolumeType(), Op.EQ);
+        AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), Op.EQ);
+        AllFieldsSearch.and("destroyed", AllFieldsSearch.entity().getState(), Op.EQ);
+        AllFieldsSearch.and("notDestroyed", AllFieldsSearch.entity().getState(), Op.NEQ);
+        AllFieldsSearch.and("updatedCount", AllFieldsSearch.entity().getUpdatedCount(), Op.EQ);
+        AllFieldsSearch.done();
+        
+        DetachedAccountIdSearch = createSearchBuilder();
+        DetachedAccountIdSearch.and("accountId", DetachedAccountIdSearch.entity().getAccountId(), Op.EQ);
+        DetachedAccountIdSearch.and("destroyed", DetachedAccountIdSearch.entity().getState(), Op.NEQ);
+        DetachedAccountIdSearch.and("instanceId", DetachedAccountIdSearch.entity().getInstanceId(), Op.NULL);
+        DetachedAccountIdSearch.done();
+        
+        TemplateZoneSearch = createSearchBuilder();
+        TemplateZoneSearch.and("template", TemplateZoneSearch.entity().getTemplateId(), Op.EQ);
+        TemplateZoneSearch.and("zone", TemplateZoneSearch.entity().getDataCenterId(), Op.EQ);
+        TemplateZoneSearch.done();
+        
+        TotalSizeByPoolSearch = createSearchBuilder(SumCount.class);
+        TotalSizeByPoolSearch.select("sum", Func.SUM, TotalSizeByPoolSearch.entity().getSize());
+        TotalSizeByPoolSearch.select("count", Func.COUNT, (Object[])null);
+        TotalSizeByPoolSearch.and("poolId", TotalSizeByPoolSearch.entity().getPoolId(), Op.EQ);
+        TotalSizeByPoolSearch.and("removed", TotalSizeByPoolSearch.entity().getRemoved(), Op.NULL);
+        TotalSizeByPoolSearch.and("state", TotalSizeByPoolSearch.entity().getState(), Op.NEQ);
+        TotalSizeByPoolSearch.done();
+      
+        ActiveTemplateSearch = createSearchBuilder(Long.class);
+        ActiveTemplateSearch.and("pool", ActiveTemplateSearch.entity().getPoolId(), Op.EQ);
+        ActiveTemplateSearch.and("template", ActiveTemplateSearch.entity().getTemplateId(), Op.EQ);
+        ActiveTemplateSearch.and("removed", ActiveTemplateSearch.entity().getRemoved(), Op.NULL);
+        ActiveTemplateSearch.select(null, Func.COUNT, null);
+        ActiveTemplateSearch.done();
+        
+        InstanceStatesSearch = createSearchBuilder();
+        InstanceStatesSearch.and("instance", InstanceStatesSearch.entity().getInstanceId(), Op.EQ);
+        InstanceStatesSearch.and("states", InstanceStatesSearch.entity().getState(), Op.IN);
+        InstanceStatesSearch.done();
+
+        CountByAccount = createSearchBuilder(Long.class);
+        CountByAccount.select(null, Func.COUNT, null);
+        CountByAccount.and("account", CountByAccount.entity().getAccountId(), SearchCriteria.Op.EQ);
+        CountByAccount.and("state", CountByAccount.entity().getState(), SearchCriteria.Op.NIN);
+        CountByAccount.done();
+
+        primaryStorageSearch = createSearchBuilder(SumCount.class);
+        primaryStorageSearch.select("sum", Func.SUM, primaryStorageSearch.entity().getSize());
+        primaryStorageSearch.and("accountId", primaryStorageSearch.entity().getAccountId(), Op.EQ);
+        primaryStorageSearch.and("path", primaryStorageSearch.entity().getPath(), Op.NNULL);
+        primaryStorageSearch.and("isRemoved", primaryStorageSearch.entity().getRemoved(), Op.NULL);
+        primaryStorageSearch.done();
+
+        secondaryStorageSearch = createSearchBuilder(SumCount.class);
+        secondaryStorageSearch.select("sum", Func.SUM, secondaryStorageSearch.entity().getSize());
+        secondaryStorageSearch.and("accountId", secondaryStorageSearch.entity().getAccountId(), Op.EQ);
+        secondaryStorageSearch.and("path", secondaryStorageSearch.entity().getPath(), Op.NULL);
+        secondaryStorageSearch.and("isRemoved", secondaryStorageSearch.entity().getRemoved(), Op.NULL);
+        secondaryStorageSearch.done();
+	}
+
+	@Override @DB(txn=false)
+	public Pair<Long, Long> getCountAndTotalByPool(long poolId) {
+        SearchCriteria<SumCount> sc = TotalSizeByPoolSearch.create();
+        sc.setParameters("poolId", poolId);
+        List<SumCount> results = customSearch(sc, null);
+        SumCount sumCount = results.get(0);
+        return new Pair<Long, Long>(sumCount.count, sumCount.sum);
+	}
+
+    @Override
+	public Long countAllocatedVolumesForAccount(long accountId) {
+	  	SearchCriteria<Long> sc = CountByAccount.create();
+        sc.setParameters("account", accountId);
+		sc.setParameters("state", Volume.State.Destroy);
+        return customSearch(sc, null).get(0);
+	}
+
+    @Override
+    public long primaryStorageUsedForAccount(long accountId) {
+        SearchCriteria<SumCount> sc = primaryStorageSearch.create();
+        sc.setParameters("accountId", accountId);
+        List<SumCount> storageSpace = customSearch(sc, null);
+        if (storageSpace != null) {
+            return storageSpace.get(0).sum;
+        } else {
+            return 0;
+        }
+    }
+
+    @Override
+    public long secondaryStorageUsedForAccount(long accountId) {
+        SearchCriteria<SumCount> sc = secondaryStorageSearch.create();
+        sc.setParameters("accountId", accountId);
+        List<SumCount> storageSpace = customSearch(sc, null);
+        if (storageSpace != null) {
+            return storageSpace.get(0).sum;
+        } else {
+            return 0;
+        }
+    }
+
+
+	public static class SumCount {
+	    public long sum;
+	    public long count;
+	    public SumCount() {
+	    }
+	}
+
+    @Override
+    public List<VolumeVO> listVolumesToBeDestroyed() {
+        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+        sc.setParameters("state", Volume.State.Destroy);
+        
+        return listBy(sc);
+    }
+
+	@Override
+	public boolean updateState(com.cloud.storage.Volume.State currentState,
+			Event event, com.cloud.storage.Volume.State nextState, Volume vo,
+			Object data) {
+		
+	        Long oldUpdated = vo.getUpdatedCount();
+	        Date oldUpdatedTime = vo.getUpdated();
+	        
+	        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+	        sc.setParameters("id", vo.getId());
+	        sc.setParameters("state", currentState);
+	        sc.setParameters("updatedCount", vo.getUpdatedCount());
+	        
+	        vo.incrUpdatedCount();
+	        
+	        UpdateBuilder builder = getUpdateBuilder(vo);
+	        builder.set(vo, "state", nextState);
+	        builder.set(vo, "updated", new Date());
+	        
+	        int rows = update((VolumeVO)vo, sc);
+	        if (rows == 0 && s_logger.isDebugEnabled()) {
+	            VolumeVO dbVol = findByIdIncludingRemoved(vo.getId()); 
+	            if (dbVol != null) {
+	            	StringBuilder str = new StringBuilder("Unable to update ").append(vo.toString());
+	            	str.append(": DB Data={id=").append(dbVol.getId()).append("; state=").append(dbVol.getState()).append("; updatecount=").append(dbVol.getUpdatedCount()).append(";updatedTime=").append(dbVol.getUpdated());
+	            	str.append(": New Data={id=").append(vo.getId()).append("; state=").append(nextState).append("; event=").append(event).append("; updatecount=").append(vo.getUpdatedCount()).append("; updatedTime=").append(vo.getUpdated());
+	            	str.append(": stale Data={id=").append(vo.getId()).append("; state=").append(currentState).append("; event=").append(event).append("; updatecount=").append(oldUpdated).append("; updatedTime=").append(oldUpdatedTime);
+	            } else {
+	            	s_logger.debug("Unable to update volume: id=" + vo.getId() + ", as there is no such volume exists in the database anymore");
+	            }
+	        }
+	        return rows > 0;
+	}
+
+    @Override
+    public List<Long> listPoolIdsByVolumeCount(long dcId, Long podId, Long clusterId, long accountId) {
+        Transaction txn = Transaction.currentTxn();
+        PreparedStatement pstmt = null;
+        List<Long> result = new ArrayList<Long>();
+        try {
+            String sql = ORDER_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT;
+            pstmt = txn.prepareAutoCloseStatement(sql);
+            pstmt.setLong(1, accountId);
+            pstmt.setLong(2, dcId);
+            pstmt.setLong(3, podId);
+            pstmt.setLong(4, clusterId);
+            
+            ResultSet rs = pstmt.executeQuery();
+            while (rs.next()) {
+                result.add(rs.getLong(1));
+            }
+            return result;
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("DB Exception on: " + ORDER_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT, e);
+        } catch (Throwable e) {
+            throw new CloudRuntimeException("Caught: " + ORDER_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT, e);
+        }
+    }
+    
+    @Override @DB(txn=false)
+    public Pair<Long, Long> getNonDestroyedCountAndTotalByPool(long poolId) {
+        SearchCriteria<SumCount> sc = TotalSizeByPoolSearch.create();
+        sc.setParameters("poolId", poolId);
+        sc.setParameters("state", State.Destroy);
+        List<SumCount> results = customSearch(sc, null);
+        SumCount sumCount = results.get(0);
+        return new Pair<Long, Long>(sumCount.count, sumCount.sum);
+    }
+    
+    @Override
+    @DB
+    public boolean remove(Long id) {
+        Transaction txn = Transaction.currentTxn();
+        txn.start();
+        VolumeVO entry = findById(id);
+        if (entry != null) {
+            _tagsDao.removeByIdAndType(id, TaggedResourceType.Volume);
+        }
+        boolean result = super.remove(id);
+        txn.commit();
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/572e71e5/engine/schema/src/com/cloud/storage/dao/VolumeHostDao.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/storage/dao/VolumeHostDao.java b/engine/schema/src/com/cloud/storage/dao/VolumeHostDao.java
new file mode 100755
index 0000000..39dda12
--- /dev/null
+++ b/engine/schema/src/com/cloud/storage/dao/VolumeHostDao.java
@@ -0,0 +1,40 @@
+// 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.storage.dao;
+
+import java.util.List;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
+
+import com.cloud.storage.VolumeHostVO;
+import com.cloud.utils.db.GenericDao;
+import com.cloud.utils.fsm.StateDao;
+
+public interface VolumeHostDao extends GenericDao<VolumeHostVO, Long>, StateDao<ObjectInDataStoreStateMachine.State, ObjectInDataStoreStateMachine.Event, DataObjectInStore>{
+
+	VolumeHostVO findByHostVolume(long hostId, long volumeId);
+
+	VolumeHostVO findByVolumeId(long volumeId);
+
+	List<VolumeHostVO> listBySecStorage(long sserverId);
+
+	List<VolumeHostVO> listDestroyed(long hostId);
+
+	VolumeHostVO findVolumeByZone(long zoneId, long volumeId);
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/572e71e5/engine/schema/src/com/cloud/storage/dao/VolumeHostDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/storage/dao/VolumeHostDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VolumeHostDaoImpl.java
new file mode 100755
index 0000000..2fd39e6
--- /dev/null
+++ b/engine/schema/src/com/cloud/storage/dao/VolumeHostDaoImpl.java
@@ -0,0 +1,165 @@
+// 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.storage.dao;
+
+import java.util.Date;
+import java.util.List;
+
+import javax.ejb.Local;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.storage.VolumeHostVO;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.UpdateBuilder;
+
+@Component
+@Local(value={VolumeHostDao.class})
+public class VolumeHostDaoImpl extends GenericDaoBase<VolumeHostVO, Long> implements VolumeHostDao {
+    private static final Logger s_logger = Logger.getLogger(VolumeHostDaoImpl.class);
+    protected final SearchBuilder<VolumeHostVO> HostVolumeSearch;
+    protected final SearchBuilder<VolumeHostVO> ZoneVolumeSearch;
+    protected final SearchBuilder<VolumeHostVO> VolumeSearch;
+    protected final SearchBuilder<VolumeHostVO> HostSearch;
+    protected final SearchBuilder<VolumeHostVO> HostDestroyedSearch;
+    protected final SearchBuilder<VolumeHostVO> updateStateSearch;
+    public VolumeHostDaoImpl(){
+        HostVolumeSearch = createSearchBuilder();
+        HostVolumeSearch.and("host_id", HostVolumeSearch.entity().getHostId(), SearchCriteria.Op.EQ);
+        HostVolumeSearch.and("volume_id", HostVolumeSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
+        HostVolumeSearch.and("destroyed", HostVolumeSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
+        HostVolumeSearch.done();
+
+        ZoneVolumeSearch = createSearchBuilder();
+        ZoneVolumeSearch.and("zone_id", ZoneVolumeSearch.entity().getZoneId(), SearchCriteria.Op.EQ);
+        ZoneVolumeSearch.and("volume_id", ZoneVolumeSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
+        ZoneVolumeSearch.and("destroyed", ZoneVolumeSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
+        ZoneVolumeSearch.done();
+
+        HostSearch = createSearchBuilder();
+        HostSearch.and("host_id", HostSearch.entity().getHostId(), SearchCriteria.Op.EQ);		
+        HostSearch.and("destroyed", HostSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
+        HostSearch.done();
+
+        VolumeSearch = createSearchBuilder();
+        VolumeSearch.and("volume_id", VolumeSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
+        VolumeSearch.and("destroyed", VolumeSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
+        VolumeSearch.done();
+
+        HostDestroyedSearch = createSearchBuilder();
+        HostDestroyedSearch.and("host_id", HostDestroyedSearch.entity().getHostId(), SearchCriteria.Op.EQ);
+        HostDestroyedSearch.and("destroyed", HostDestroyedSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
+        HostDestroyedSearch.done();	
+        
+        updateStateSearch = this.createSearchBuilder();
+        updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ);
+        updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ);
+        updateStateSearch.and("updatedCount", updateStateSearch.entity().getUpdatedCount(), Op.EQ);
+        updateStateSearch.done();
+    }
+
+
+
+    @Override
+    public VolumeHostVO findByHostVolume(long hostId, long volumeId) {
+        SearchCriteria<VolumeHostVO> sc = HostVolumeSearch.create();
+        sc.setParameters("host_id", hostId);
+        sc.setParameters("volume_id", volumeId);
+        sc.setParameters("destroyed", false);
+        return findOneIncludingRemovedBy(sc);
+    }	
+
+    @Override
+    public VolumeHostVO findVolumeByZone(long volumeId, long zoneId) {
+        SearchCriteria<VolumeHostVO> sc = ZoneVolumeSearch.create();
+        sc.setParameters("zone_id", zoneId);
+        sc.setParameters("volume_id", volumeId);
+        sc.setParameters("destroyed", false);
+        return findOneIncludingRemovedBy(sc);
+    }
+
+    @Override
+    public VolumeHostVO findByVolumeId(long volumeId) {
+        SearchCriteria<VolumeHostVO> sc = VolumeSearch.create();
+        sc.setParameters("volume_id", volumeId);
+        sc.setParameters("destroyed", false);
+        return findOneBy(sc);
+    }
+
+
+
+    @Override
+    public List<VolumeHostVO> listBySecStorage(long ssHostId) {
+        SearchCriteria<VolumeHostVO> sc = HostSearch.create();
+        sc.setParameters("host_id", ssHostId);
+        sc.setParameters("destroyed", false);
+        return listAll();
+    }
+
+    @Override
+    public List<VolumeHostVO> listDestroyed(long hostId){
+        SearchCriteria<VolumeHostVO> sc = HostDestroyedSearch.create();
+        sc.setParameters("host_id", hostId);
+        sc.setParameters("destroyed", true);
+        return listIncludingRemovedBy(sc);
+    }
+
+    @Override
+    public boolean updateState(State currentState, Event event,
+            State nextState, DataObjectInStore vo, Object data) {
+        VolumeHostVO volHost = (VolumeHostVO) vo;
+        Long oldUpdated = volHost.getUpdatedCount();
+        Date oldUpdatedTime = volHost.getUpdated();
+    
+        
+        SearchCriteria<VolumeHostVO> sc = updateStateSearch.create();
+        sc.setParameters("id", volHost.getId());
+        sc.setParameters("state", currentState);
+        sc.setParameters("updatedCount", volHost.getUpdatedCount());
+
+        volHost.incrUpdatedCount();
+
+        UpdateBuilder builder = getUpdateBuilder(vo);
+        builder.set(vo, "state", nextState);
+        builder.set(vo, "updated", new Date());
+
+        int rows = update((VolumeHostVO) vo, sc);
+        if (rows == 0 && s_logger.isDebugEnabled()) {
+            VolumeHostVO dbVol = findByIdIncludingRemoved(volHost.getId());
+            if (dbVol != null) {
+                StringBuilder str = new StringBuilder("Unable to update ").append(vo.toString());
+                str.append(": DB Data={id=").append(dbVol.getId()).append("; state=").append(dbVol.getState()).append("; updatecount=").append(dbVol.getUpdatedCount()).append(";updatedTime=")
+                        .append(dbVol.getUpdated());
+                str.append(": New Data={id=").append(volHost.getId()).append("; state=").append(nextState).append("; event=").append(event).append("; updatecount=").append(volHost.getUpdatedCount())
+                        .append("; updatedTime=").append(volHost.getUpdated());
+                str.append(": stale Data={id=").append(volHost.getId()).append("; state=").append(currentState).append("; event=").append(event).append("; updatecount=").append(oldUpdated)
+                        .append("; updatedTime=").append(oldUpdatedTime);
+            } else {
+                s_logger.debug("Unable to update objectIndatastore: id=" + volHost.getId() + ", as there is no such object exists in the database anymore");
+            }
+        }
+        return rows > 0;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/572e71e5/engine/schema/src/com/cloud/tags/ResourceTagVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/tags/ResourceTagVO.java b/engine/schema/src/com/cloud/tags/ResourceTagVO.java
new file mode 100644
index 0000000..04ae757
--- /dev/null
+++ b/engine/schema/src/com/cloud/tags/ResourceTagVO.java
@@ -0,0 +1,160 @@
+// 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.tags;
+
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import org.apache.cloudstack.api.Identity;
+import com.cloud.server.ResourceTag;
+import org.apache.cloudstack.api.InternalIdentity;
+
+
+@Entity
+@Table(name="resource_tags")
+public class ResourceTagVO implements ResourceTag {
+    
+    @Id
+    @GeneratedValue(strategy=GenerationType.IDENTITY)
+    @Column(name="id")
+    private long id;
+    
+    @Column(name="uuid")
+    private String uuid;
+    
+    @Column(name="key")
+    private String key;
+    
+    @Column(name="value")
+    String value;
+    
+    @Column(name="domain_id")
+    long domainId;
+
+    @Column(name="account_id")
+    long accountId;
+    
+    @Column(name="resource_id")
+    long resourceId;
+    
+    @Column(name="resource_uuid")
+    private String resourceUuid;
+    
+    @Column(name="resource_type")
+    @Enumerated(value=EnumType.STRING)
+    private TaggedResourceType resourceType;
+    
+    @Column(name="customer")
+    String customer;
+
+    
+    protected ResourceTagVO(){
+        this.uuid = UUID.randomUUID().toString();
+    }
+    
+    /**
+     * @param key
+     * @param value
+     * @param accountId
+     * @param domainId
+     * @param resourceId
+     * @param resourceType
+     * @param customer TODO
+     * @param resourceUuid TODO
+     */
+    public ResourceTagVO(String key, String value, long accountId, long domainId, long resourceId, 
+            TaggedResourceType resourceType, String customer, String resourceUuid) {
+        super();
+        this.key = key;
+        this.value = value;
+        this.domainId = domainId;
+        this.accountId = accountId;
+        this.resourceId = resourceId;
+        this.resourceType = resourceType;
+        this.uuid = UUID.randomUUID().toString();
+        this.customer = customer;
+        this.resourceUuid = resourceUuid;
+    }
+    
+    
+    @Override
+    public String toString() {
+        StringBuilder buf = new StringBuilder("Tag[");
+        buf.append(id).append("|key=").append(key).append("|value=").append(domainId).append("|value=").
+        append("|resourceType=").append(resourceType).append("|resourceId=").append(resourceId)
+        .append("|accountId=").append(accountId).append("]");
+        return buf.toString();
+    }
+    
+    @Override
+    public long getId() {
+        return id;
+    }
+
+    @Override
+    public String getKey() {
+        return key;
+    }
+
+    @Override
+    public String getValue() {
+        return value;
+    }
+
+    @Override
+    public long getDomainId() {
+        return domainId;
+    }
+
+    @Override
+    public long getAccountId() {
+        return accountId;
+    }
+
+    @Override
+    public long getResourceId() {
+        return resourceId;
+    }
+
+    @Override
+    public TaggedResourceType getResourceType() {
+        return resourceType;
+    }
+
+    @Override
+    public String getUuid() {
+        return uuid;
+    }
+    
+    @Override
+    public String getCustomer() {
+        return customer;
+    }
+
+    @Override
+    public String getResourceUuid() {
+        return resourceUuid;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/572e71e5/engine/schema/src/com/cloud/tags/dao/ResourceTagDao.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/tags/dao/ResourceTagDao.java b/engine/schema/src/com/cloud/tags/dao/ResourceTagDao.java
new file mode 100644
index 0000000..335c748
--- /dev/null
+++ b/engine/schema/src/com/cloud/tags/dao/ResourceTagDao.java
@@ -0,0 +1,37 @@
+// 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.tags.dao;
+
+import java.util.List;
+
+import com.cloud.server.ResourceTag;
+import com.cloud.server.ResourceTag.TaggedResourceType;
+import com.cloud.tags.ResourceTagVO;
+import com.cloud.utils.db.GenericDao;
+
+public interface ResourceTagDao extends GenericDao<ResourceTagVO, Long>{
+
+    /**
+     * @param resourceId
+     * @param resourceType
+     * @return
+     */
+    boolean removeByIdAndType(long resourceId, TaggedResourceType resourceType);
+    
+    List<? extends ResourceTag> listBy(long resourceId, TaggedResourceType resourceType);
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/572e71e5/engine/schema/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java b/engine/schema/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java
new file mode 100644
index 0000000..a8e1393
--- /dev/null
+++ b/engine/schema/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java
@@ -0,0 +1,62 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.tags.dao;
+
+import java.util.List;
+
+import javax.ejb.Local;
+
+import org.springframework.stereotype.Component;
+
+import com.cloud.server.ResourceTag;
+import com.cloud.server.ResourceTag.TaggedResourceType;
+import com.cloud.tags.ResourceTagVO;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Op;
+
+@Component
+@Local(value = { ResourceTagDao.class })
+public class ResourceTagsDaoImpl extends GenericDaoBase<ResourceTagVO, Long> implements ResourceTagDao{
+    final SearchBuilder<ResourceTagVO> AllFieldsSearch;
+    
+    public ResourceTagsDaoImpl() {
+        AllFieldsSearch = createSearchBuilder();
+        AllFieldsSearch.and("resourceId", AllFieldsSearch.entity().getResourceId(), Op.EQ);
+        AllFieldsSearch.and("uuid", AllFieldsSearch.entity().getResourceUuid(), Op.EQ);
+        AllFieldsSearch.and("resourceType", AllFieldsSearch.entity().getResourceType(), Op.EQ);
+        AllFieldsSearch.done();
+    }
+    
+    @Override
+    public boolean removeByIdAndType(long resourceId, ResourceTag.TaggedResourceType resourceType) {
+        SearchCriteria<ResourceTagVO> sc = AllFieldsSearch.create();
+        sc.setParameters("resourceId", resourceId);
+        sc.setParameters("resourceType", resourceType);
+        remove(sc);
+        return true;
+    }
+
+    @Override
+    public List<? extends ResourceTag> listBy(long resourceId, TaggedResourceType resourceType) {
+        SearchCriteria<ResourceTagVO> sc = AllFieldsSearch.create();
+        sc.setParameters("resourceId", resourceId);
+        sc.setParameters("resourceType", resourceType);
+        return listBy(sc);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/572e71e5/engine/schema/src/com/cloud/upgrade/DatabaseCreator.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/upgrade/DatabaseCreator.java b/engine/schema/src/com/cloud/upgrade/DatabaseCreator.java
new file mode 100755
index 0000000..9b1be6b
--- /dev/null
+++ b/engine/schema/src/com/cloud/upgrade/DatabaseCreator.java
@@ -0,0 +1,233 @@
+/*
+ * 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.upgrade;
+
+import java.io.*;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+import com.cloud.utils.PropertiesUtil;
+
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.utils.component.SystemIntegrityChecker;
+import com.cloud.utils.db.ScriptRunner;
+import com.cloud.utils.db.Transaction;
+
+// Creates the CloudStack Database by using the 4.0 schema and apply
+// upgrade steps to it.
+public class DatabaseCreator {
+
+    protected static void printHelp(String cmd) {
+        System.out.println(
+                "\nDatabaseCreator creates the database schema by removing the \n" +
+                "previous schema, creating the schema, and running \n" +
+                "through the database updaters.");
+        System.out.println("Usage: " + cmd + " [options] [db.properties file] [schema.sql files] [database upgrade class]\nOptions:"
+                + "\n   --database=a,b comma separate databases to initialize, use the db name in db.properties defined as db.xyz.host, xyz should be passed"
+                + "\n   --rootpassword=password, by default it will try with an empty password"
+                + "\n   --dry or -d, this would not run any process, just does a dry run"
+                + "\n   --verbose or -v to print running sql commands, by default it won't print them"
+                + "\n   --help or -h for help");
+    }
+
+    private static boolean fileExists(String file) {
+        File f = new File(file);
+        if (!f.exists())
+            System.out.println("========> WARNING: Provided file does not exist: " + file);
+        return f.exists();
+    }
+
+    private static void runScript(Connection conn, Reader reader, String filename, boolean verbosity) {
+        ScriptRunner runner = new ScriptRunner(conn, false, true, verbosity);
+        try {
+            runner.runScript(reader);
+        } catch (IOException e) {
+            System.err.println("Unable to read " + filename + ": " + e.getMessage());
+            System.exit(1);
+        } catch (SQLException e) {
+            System.err.println("Unable to execute " + filename + ": " + e.getMessage());
+            System.exit(1);
+        }
+    }
+
+    private static void runQuery(String host, String port, String rootPassword, String query, boolean dryRun) {
+        System.out.println("============> Running query: " + query);
+        Connection conn = null;
+        try {
+            conn = DriverManager.getConnection(String.format("jdbc:mysql://%s:%s/", host, port),
+                    "root", rootPassword);
+            Statement stmt = conn.createStatement();
+            if (!dryRun)
+                stmt.executeUpdate(query);
+            conn.close();
+        } catch (SQLException e) {
+            System.out.println("SQL exception in trying initDB: " + e);
+            System.exit(1);
+        }
+    }
+
+    private static void initDB(String dbPropsFile, String rootPassword, String[] databases, boolean dryRun) {
+        Properties dbProperties = new Properties();
+        try {
+            dbProperties.load(new FileInputStream(new File(dbPropsFile)));
+        } catch (IOException e) {
+            System.out.println("IOError: unable to load/read db properties file: " + e);
+            System.exit(1);
+        }
+
+        for (String database: databases) {
+            String host = dbProperties.getProperty(String.format("db.%s.host", database));
+            String port = dbProperties.getProperty(String.format("db.%s.port", database));
+            String username = dbProperties.getProperty(String.format("db.%s.username", database));
+            String password = dbProperties.getProperty(String.format("db.%s.password", database));
+            String dbName = dbProperties.getProperty(String.format("db.%s.name", database));
+            System.out.println(String.format("========> Initializing database=%s with host=%s port=%s username=%s password=%s", dbName, host, port, username, password));
+
+            List<String> queries = new ArrayList<String>();
+            queries.add(String.format("drop database if exists `%s`", dbName));
+            queries.add(String.format("create database `%s`", dbName));
+            queries.add(String.format("GRANT ALL ON %s.* to '%s'@`localhost` identified by '%s'", dbName, username, password));
+            queries.add(String.format("GRANT ALL ON %s.* to '%s'@`%%` identified by '%s'", dbName, username, password));
+
+            for (String query: queries) {
+                runQuery(host, port, rootPassword, query, dryRun);
+            }
+        }
+    }
+
+    public static void main(String[] args) {
+    	
+    	ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(
+    	        new String[] {"/com/cloud/upgrade/databaseCreatorContext.xml"});
+    	appContext.getBean(ComponentContext.class);
+    	
+        String dbPropsFile = "";
+        List<String> sqlFiles = new ArrayList<String>();
+        List<String> upgradeClasses = new ArrayList<String>();
+        String[] databases = new String[] {};
+        String rootPassword = "";
+        boolean verbosity = false;
+        boolean dryRun = false;
+
+        // Process opts
+        for (String arg: args) {
+            if (arg.equals("--help") || arg.equals("-h")) {
+                printHelp("DatabaseCreator");
+                System.exit(0);
+            } else if (arg.equals("--verbose") || arg.equals("-v")) {
+                verbosity = true;
+            } else if (arg.equals("--dry") || arg.equals("-d")) {
+                dryRun = true;
+            } else if (arg.startsWith("--rootpassword=")) {
+                rootPassword = arg.substring(arg.lastIndexOf("=") + 1, arg.length());
+            } else if (arg.startsWith("--database=")) {
+                databases = arg.substring(arg.lastIndexOf("=") + 1, arg.length()).split(",");
+            } else if (arg.endsWith(".sql")) {
+                sqlFiles.add(arg);
+            } else if (arg.endsWith(".properties")) {
+                if (!dbPropsFile.endsWith("properties.override") && fileExists(arg))
+                    dbPropsFile = arg;
+            } else if (arg.endsWith("properties.override")) {
+                if (fileExists(arg))
+                    dbPropsFile = arg;
+            } else {
+                upgradeClasses.add(arg);
+            }
+        }
+
+        if ((dbPropsFile.isEmpty())
+                || (sqlFiles.size() == 0) && upgradeClasses.size() == 0) {
+            printHelp("DatabaseCreator");
+            System.exit(1);
+        }
+
+        try {
+            Transaction.initDataSource(dbPropsFile);
+        } catch (NullPointerException e) {
+        }
+        initDB(dbPropsFile, rootPassword, databases, dryRun);
+
+        // Process sql files
+        for (String sqlFile: sqlFiles) {
+            File sqlScript = PropertiesUtil.findConfigFile(sqlFile);
+            if (sqlScript == null) {
+                System.err.println("Unable to find " + sqlFile);
+                printHelp("DatabaseCreator");
+                System.exit(1);
+            }
+
+            System.out.println("========> Processing SQL file at " + sqlScript.getAbsolutePath());
+            Connection conn = Transaction.getStandaloneConnection();
+            try {
+                FileReader reader = null;
+                try {
+                    reader = new FileReader(sqlScript);
+                } catch (FileNotFoundException e) {
+                    System.err.println("Unable to read " + sqlFile + ": " + e.getMessage());
+                    System.exit(1);
+                }
+                if (!dryRun)
+                    runScript(conn, reader, sqlFile, verbosity);
+            } finally {
+                try {
+                    conn.close();
+                } catch (SQLException e) {
+                    System.err.println("Unable to close DB connection: " + e.getMessage());
+                }
+            }
+        }
+
+        Transaction txn = Transaction.open(Transaction.CLOUD_DB);
+        try {
+        // Process db upgrade classes
+        for (String upgradeClass: upgradeClasses) {
+            System.out.println("========> Processing upgrade: " + upgradeClass);
+            Class<?> clazz = null;
+            try {
+                clazz = Class.forName(upgradeClass);
+                if (!SystemIntegrityChecker.class.isAssignableFrom(clazz)) {
+                    System.err.println("The class must be of SystemIntegrityChecker: " + clazz.getName());
+                    System.exit(1);
+                }
+                SystemIntegrityChecker checker = (SystemIntegrityChecker)clazz.newInstance();
+                checker.check();
+            } catch (ClassNotFoundException e) {
+                System.err.println("Unable to find " + upgradeClass + ": " + e.getMessage());
+                System.exit(1);
+            } catch (InstantiationException e) {
+                System.err.println("Unable to instantiate " + upgradeClass + ": " + e.getMessage());
+                System.exit(1);
+            } catch (IllegalAccessException e) {
+                System.err.println("Unable to access " + upgradeClass + ": " + e.getMessage());
+                System.exit(1);
+            }
+
+         }
+        } finally {
+            txn.close();
+        }
+    }
+}


Mime
View raw message