cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ahu...@apache.org
Subject [10/18] Added engine
Date Mon, 05 Nov 2012 17:23:42 GMT
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/src/org/apache/cloudstack/storage/strategy/DefaultVolumeStrategy.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/strategy/DefaultVolumeStrategy.java b/engine/storage/src/org/apache/cloudstack/storage/strategy/DefaultVolumeStrategy.java
new file mode 100644
index 0000000..35e284f
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/strategy/DefaultVolumeStrategy.java
@@ -0,0 +1,90 @@
+package org.apache.cloudstack.storage.strategy;
+
+import java.util.List;
+
+import org.apache.cloudstack.platform.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.platform.subsystem.api.storage.DataStoreDriver;
+
+import org.apache.cloudstack.platform.subsystem.api.storage.DataStoreEndPoint;
+import org.apache.cloudstack.platform.subsystem.api.storage.DataStoreEndPointSelector;
+import org.apache.cloudstack.platform.subsystem.api.storage.SnapshotProfile;
+import org.apache.cloudstack.platform.subsystem.api.storage.StorageEvent;
+import org.apache.cloudstack.platform.subsystem.api.storage.TemplateProfile;
+import org.apache.cloudstack.platform.subsystem.api.storage.VolumeProfile;
+import org.apache.cloudstack.platform.subsystem.api.storage.VolumeStrategy;
+import org.apache.cloudstack.storage.volume.VolumeManager;
+
+import org.apache.log4j.Logger;
+
+
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.utils.component.Inject;
+
+
+public class DefaultVolumeStrategy implements VolumeStrategy {
+	private static final Logger s_logger = Logger.getLogger(DefaultVolumeStrategy.class);
+	protected DataStore _ds;
+	protected DataStoreDriver _driver;
+	@Inject
+	VolumeManager _volumeMgr;
+	
+	public VolumeProfile get(long volumeId) {
+		return _volumeMgr.getProfile(volumeId);
+	}
+
+	public DefaultVolumeStrategy(DataStore ds) {
+		_ds = ds;
+	}
+	public Volume createVolume(Volume vol) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+	public Volume createDataVolume(Volume vol) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+	public Volume copyVolumeFromBackup(VolumeProfile srcVol, Volume destVol) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+	public Volume createVolumeFromSnapshot(SnapshotProfile snapshot, Volume vol) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+	public Volume createVolumeFromTemplate(TemplateProfile template, Volume vol) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+	public Volume migrateVolume(Volume srcVol, Volume destVol, DataStore destStore) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+	
+	public Volume createVolumeFromBaseTemplate(Volume volume, TemplateProfile tp) {
+		DataStoreEndPointSelector dsep = _ds.getEndPointSelector();
+		List<DataStoreEndPoint> dseps = dsep.getEndPoints(StorageEvent.CreateVolumeFromTemplate);
+		DataStoreEndPoint dp = dseps.get(0);
+		
+		VolumeProfile vp = _driver.createVolumeFromTemplate(get(volume.getId()), tp, dp);
+		
+		VolumeVO vlvo = _volumeMgr.getVolume(volume.getId());
+		
+		vlvo.setFolder(_ds.getPath());
+		vlvo.setPath(vp.getPath());
+		vlvo.setSize(vp.getSize());
+		vlvo.setPoolType(_ds.getPoolType());
+		vlvo.setPoolId(_ds.getId());
+		vlvo.setPodId(_ds.getPodId());
+		
+		return _volumeMgr.updateVolume(vlvo);
+	}
+	public boolean deleteVolume(Volume vol) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+	
+	
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/src/org/apache/cloudstack/storage/strategy/XenBackupStrategy.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/strategy/XenBackupStrategy.java b/engine/storage/src/org/apache/cloudstack/storage/strategy/XenBackupStrategy.java
new file mode 100644
index 0000000..5ac839d
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/strategy/XenBackupStrategy.java
@@ -0,0 +1,11 @@
+package org.apache.cloudstack.storage.strategy;
+
+import org.apache.cloudstack.platform.subsystem.api.storage.BackupStrategy;
+import org.apache.cloudstack.platform.subsystem.api.storage.DataStore;
+
+public class XenBackupStrategy implements BackupStrategy {
+	protected DataStore _ds;
+	public XenBackupStrategy(DataStore ds) {
+		_ds = ds;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/src/org/apache/cloudstack/storage/strategy/XenSnapshotStrategy.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/strategy/XenSnapshotStrategy.java b/engine/storage/src/org/apache/cloudstack/storage/strategy/XenSnapshotStrategy.java
new file mode 100644
index 0000000..1b93880
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/strategy/XenSnapshotStrategy.java
@@ -0,0 +1,11 @@
+package org.apache.cloudstack.storage.strategy;
+
+import org.apache.cloudstack.platform.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.platform.subsystem.api.storage.SnapshotStrategy;
+
+public class XenSnapshotStrategy implements SnapshotStrategy {
+	protected DataStore _ds;
+	public XenSnapshotStrategy(DataStore ds) {
+		_ds = ds;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/src/org/apache/cloudstack/storage/volume/Volume.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/Volume.java b/engine/storage/src/org/apache/cloudstack/storage/volume/Volume.java
new file mode 100644
index 0000000..35eaa3b
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/volume/Volume.java
@@ -0,0 +1,101 @@
+package org.apache.cloudstack.storage.volume;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
+import org.apache.cloudstack.storage.datastore.PrimaryDataStoreInfo;
+import org.apache.cloudstack.storage.volume.db.VolumeDao;
+import org.apache.cloudstack.storage.volume.db.VolumeVO;
+import org.apache.cloudstack.storage.volume.disktype.VolumeDiskType;
+import org.apache.cloudstack.storage.volume.disktype.VolumeDiskTypeHelper;
+import org.apache.cloudstack.storage.volume.type.VolumeType;
+import org.apache.cloudstack.storage.volume.type.VolumeTypeHelper;
+import org.apache.log4j.Logger;
+
+import com.cloud.utils.fsm.NoTransitionException;
+import com.cloud.utils.fsm.StateMachine2;
+
+public class Volume {
+	private static final Logger s_logger = Logger.getLogger(Volume.class);
+	protected VolumeVO volumeVO;
+	private StateMachine2<VolumeState, VolumeEvent, VolumeVO> _volStateMachine;
+	protected PrimaryDataStore dataStore;
+	@Inject
+	VolumeDiskTypeHelper diskTypeHelper;
+	@Inject
+	VolumeTypeHelper volumeTypeHelper;
+	@Inject
+	VolumeDao volumeDao;
+	
+	public Volume(PrimaryDataStore dataStore, VolumeVO volumeVO) {
+		this.volumeVO = volumeVO;
+		this.dataStore = dataStore;
+	}
+	
+	public String getUuid() {
+		return volumeVO.getUuid();
+	}
+	
+	public void setUuid(String uuid) {
+		volumeVO.setUuid(uuid);
+	}
+	
+	public String getPath() {
+		return volumeVO.getPath();
+	}
+	
+	public String getTemplateUuid() {
+		return null;
+	}
+	
+	public String getTemplatePath() {
+		return null;
+	}
+	
+	public PrimaryDataStoreInfo getDataStoreInfo() {
+		return dataStore.getDataStoreInfo();
+	}
+	
+	public VolumeState getState() {
+		return volumeVO.getState();
+	}
+
+	public PrimaryDataStore getDataStore() {
+		return dataStore;
+	}
+	
+	public long getSize() {
+		return volumeVO.getSize();
+	}
+	
+	public VolumeDiskType getDiskType() {
+		return diskTypeHelper.getDiskType(volumeVO.getDiskType());
+	}
+	
+	public VolumeType getType() {
+		return volumeTypeHelper.getType(volumeVO.getVolumeType());
+	}
+	
+	public long getVolumeId() {
+		return volumeVO.getId();
+	}
+	
+	public void setVolumeDiskType(VolumeDiskType type) {
+		volumeVO.setDiskType(type.toString());
+	}
+	
+	public boolean stateTransit(VolumeEvent event) {
+		boolean result = false;
+		try {
+			result = _volStateMachine.transitTo(volumeVO, event, null, volumeDao);
+		} catch (NoTransitionException e) {
+			s_logger.debug("Failed to transit volume: " + this.getVolumeId() + ", due to: " + e.toString());
+		}
+		return result;
+	}
+	
+	public void update() {
+		volumeDao.update(volumeVO.getId(), volumeVO);
+		volumeVO = volumeDao.findById(volumeVO.getId());
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeEvent.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeEvent.java b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeEvent.java
new file mode 100644
index 0000000..33d1261
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeEvent.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.volume;
+
+public enum VolumeEvent {
+	CreateRequested,
+	CopyRequested,
+	CopySucceeded,
+	CopyFailed,
+	OperationFailed,
+	OperationSucceeded,
+	OperationRetry,
+	UploadRequested,
+	MigrationRequested,
+	SnapshotRequested,
+	DestroyRequested,
+	ExpungingRequested;
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeInfo.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeInfo.java b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeInfo.java
new file mode 100644
index 0000000..0c6981a
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeInfo.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.volume;
+
+import org.apache.cloudstack.storage.datastore.PrimaryDataStoreInfo;
+import org.apache.cloudstack.storage.volume.disktype.VolumeDiskType;
+import org.apache.cloudstack.storage.volume.type.VolumeType;
+
+public class VolumeInfo {
+	private long size;
+	private String uuid;
+	private String path;
+	private PrimaryDataStoreInfo dataStoreInfo;
+	private String baseTemplateUuid;
+	private String baseTemplatePath;
+	private VolumeType type;
+	private VolumeDiskType diskType;
+	
+	public VolumeInfo(Volume volume) {
+		this.size = volume.getSize();
+		this.uuid = volume.getUuid();
+		this.baseTemplatePath = volume.getTemplatePath();
+		this.baseTemplateUuid = volume.getTemplateUuid();
+		this.dataStoreInfo = volume.getDataStoreInfo();
+		this.diskType = volume.getDiskType();
+		this.type = volume.getType();
+	}
+	
+	public long getSize() {
+		return this.size;
+	}
+	
+	public String getUuid() {
+		return this.uuid;
+	}
+	
+	public String getPath() {
+		return this.path;
+	}
+	
+	public PrimaryDataStoreInfo getDataStore() {
+		return this.dataStoreInfo;
+	}
+	
+	public String getTemplateUuid() {
+		return this.baseTemplateUuid;
+	}
+	
+	public String getTemplatePath() {
+		return this.baseTemplatePath;
+	}
+	
+	public VolumeType getType() {
+		return this.type;
+	}
+	
+	public VolumeDiskType getDiskType() {
+		return this.diskType;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeManager.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeManager.java b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeManager.java
new file mode 100644
index 0000000..1b4bc93
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeManager.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 org.apache.cloudstack.storage.volume;
+
+import org.apache.cloudstack.platform.subsystem.api.storage.VolumeProfile;
+
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.utils.fsm.NoTransitionException;
+
+public interface VolumeManager {
+	VolumeVO allocateDuplicateVolume(VolumeVO oldVol);
+	VolumeVO processEvent(Volume vol, Volume.Event event) throws NoTransitionException;
+	VolumeProfile getProfile(long volumeId);
+	VolumeVO getVolume(long volumeId);
+	VolumeVO updateVolume(VolumeVO volume);
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeManagerImpl.java
new file mode 100644
index 0000000..19e61a8
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeManagerImpl.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.volume;
+
+import org.apache.cloudstack.platform.subsystem.api.storage.VolumeProfile;
+
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.Volume;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.utils.component.Inject;
+import com.cloud.utils.fsm.NoTransitionException;
+import com.cloud.utils.fsm.StateMachine2;
+
+public class VolumeManagerImpl implements VolumeManager {
+	private StateMachine2<Volume.State, Volume.Event, Volume> _volStateMachine;
+	@Inject
+	protected VolumeDao _volumeDao;
+	
+
+	public VolumeVO allocateDuplicateVolume(VolumeVO oldVol) {
+		VolumeVO newVol = new VolumeVO(oldVol.getVolumeType(), oldVol.getName(), oldVol.getDataCenterId(), oldVol.getDomainId(), oldVol.getAccountId(), oldVol.getDiskOfferingId(), oldVol.getSize());
+		newVol.setTemplateId(oldVol.getTemplateId());
+		newVol.setDeviceId(oldVol.getDeviceId());
+		newVol.setInstanceId(oldVol.getInstanceId());
+		newVol.setRecreatable(oldVol.isRecreatable());
+		newVol.setReservationId(oldVol.getReservationId());
+		return null;
+		//return _volumeDao.persist(newVol);
+	}
+	
+
+	public VolumeVO processEvent(Volume vol, Volume.Event event) throws NoTransitionException {
+		//_volStateMachine.transitTo(vol, event, null, _volumeDao);
+		return _volumeDao.findById(vol.getId());
+	}
+
+
+	public VolumeProfile getProfile(long volumeId) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+
+	public VolumeVO getVolume(long volumeId) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+
+	public VolumeVO updateVolume(VolumeVO volume) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeMotionService.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeMotionService.java b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeMotionService.java
new file mode 100644
index 0000000..9814ecb
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeMotionService.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.volume;
+
+public interface VolumeMotionService {
+	boolean copyVolume(String volumeUri, String destVolumeUri);
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeService.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeService.java b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeService.java
new file mode 100644
index 0000000..63e247c
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeService.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.volume;
+
+import org.apache.cloudstack.storage.volume.disktype.VolumeDiskType;
+import org.apache.cloudstack.storage.volume.type.VolumeType;
+
+public interface VolumeService {
+
+	/**
+	 * 
+	 */
+	Volume allocateVolumeInDb(long size, VolumeType type,String volName, Long templateId);
+	
+    /**
+     * Creates the volume based on the given criteria
+     * 
+     * @param cmd
+     *            
+     * @return the volume object
+     */
+    Volume createVolume(long volumeId, long dataStoreId, VolumeDiskType diskType);
+
+    /**
+     * Delete volume
+     * @param volumeId
+     * @return
+     * @throws ConcurrentOperationException
+     */
+    boolean deleteVolume(long volumeId);
+    
+    /**
+     * 
+     */
+    boolean cloneVolume(long volumeId, long baseVolId);
+    
+    /**
+     * 
+     */
+    boolean createVolumeFromSnapshot(long volumeId, long snapshotId);
+    
+    /**
+     * 
+     */
+    String grantAccess(long volumeId, long endpointId);
+    
+    /**
+     * 
+     */
+    boolean rokeAccess(long volumeId, long endpointId);
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
new file mode 100644
index 0000000..145813f
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.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.volume;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
+import org.apache.cloudstack.storage.datastore.manager.PrimaryDataStoreManager;
+import org.apache.cloudstack.storage.volume.db.VolumeDao;
+import org.apache.cloudstack.storage.volume.disktype.VolumeDiskType;
+import org.apache.cloudstack.storage.volume.type.VolumeType;
+import org.springframework.stereotype.Service;
+
+import com.cloud.utils.db.DB;
+
+@Service
+public class VolumeServiceImpl implements VolumeService {
+	@Inject
+	VolumeDao volDao;
+	@Inject
+	PrimaryDataStoreManager dataStoreMgr;
+	@Override
+	public Volume createVolume(long volumeId, long dataStoreId, VolumeDiskType diskType) {
+		PrimaryDataStore dataStore = dataStoreMgr.getPrimaryDataStore(dataStoreId);
+		return dataStore.createVolume(volumeId, diskType);
+	}
+
+	@DB
+	@Override
+	public boolean deleteVolume(long volumeId) {
+		return true;
+	}
+
+	@Override
+	public boolean cloneVolume(long volumeId, long baseVolId) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	@Override
+	public boolean createVolumeFromSnapshot(long volumeId, long snapshotId) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	@Override
+	public String grantAccess(long volumeId, long endpointId) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public boolean rokeAccess(long volumeId, long endpointId) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	@Override
+	public Volume allocateVolumeInDb(long size, VolumeType type, String volName, Long templateId) {
+		volDao.allocVolume(size, type, volName, templateId);
+		return null;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeState.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeState.java b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeState.java
new file mode 100644
index 0000000..f2ebafa
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeState.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.volume;
+
+import org.apache.cloudstack.storage.volume.db.VolumeVO;
+
+import com.cloud.utils.fsm.StateMachine2;
+
+public enum VolumeState {
+	Allocated("The volume is allocated but has not been created yet."),
+    Creating("The volume is being created.  getPoolId() should reflect the pool where it is being created."),
+    Ready("The volume is ready to be used."),
+    Migrating("The volume is migrating to other storage pool"),
+    Snapshotting("There is a snapshot created on this volume, not backed up to secondary storage yet"),
+    Expunging("The volume is being expunging"),
+    Destroy("The volume is destroyed, and can't be recovered."),        
+    UploadOp ("The volume upload operation is in progress or in short the volume is on secondary storage");            
+
+    String _description;
+
+    private VolumeState(String description) {
+        _description = description;
+    }
+
+    public static StateMachine2<VolumeState, VolumeEvent, VolumeVO> getStateMachine() {
+        return s_fsm;
+    }
+
+    public String getDescription() {
+        return _description;
+    }
+
+    private final static StateMachine2<VolumeState, VolumeEvent, VolumeVO> s_fsm = new StateMachine2<VolumeState, VolumeEvent, VolumeVO>();
+    static {
+        s_fsm.addTransition(Allocated, VolumeEvent.CreateRequested, Creating);
+        s_fsm.addTransition(Allocated, VolumeEvent.DestroyRequested, Destroy);
+        s_fsm.addTransition(Creating, VolumeEvent.OperationRetry, Creating);
+        s_fsm.addTransition(Creating, VolumeEvent.OperationFailed, Allocated);
+        s_fsm.addTransition(Creating, VolumeEvent.OperationSucceeded, Ready);
+        s_fsm.addTransition(Creating, VolumeEvent.DestroyRequested, Destroy);
+        s_fsm.addTransition(Creating, VolumeEvent.CreateRequested, Creating);            
+        s_fsm.addTransition(Allocated, VolumeEvent.UploadRequested, UploadOp);
+        s_fsm.addTransition(UploadOp, VolumeEvent.CopyRequested, Creating);// CopyRequested for volume from sec to primary storage            
+        s_fsm.addTransition(Creating, VolumeEvent.CopySucceeded, Ready);
+        s_fsm.addTransition(Creating, VolumeEvent.CopyFailed, UploadOp);// Copying volume from sec to primary failed.  
+        s_fsm.addTransition(UploadOp, VolumeEvent.DestroyRequested, Destroy);
+        s_fsm.addTransition(Ready, VolumeEvent.DestroyRequested, Destroy);
+        s_fsm.addTransition(Destroy, VolumeEvent.ExpungingRequested, Expunging);
+        s_fsm.addTransition(Ready, VolumeEvent.SnapshotRequested, Snapshotting);
+        s_fsm.addTransition(Snapshotting, VolumeEvent.OperationSucceeded, Ready);
+        s_fsm.addTransition(Snapshotting, VolumeEvent.OperationFailed, Ready);
+        s_fsm.addTransition(Ready, VolumeEvent.MigrationRequested, Migrating);
+        s_fsm.addTransition(Migrating, VolumeEvent.OperationSucceeded, Ready);
+        s_fsm.addTransition(Migrating, VolumeEvent.OperationFailed, Ready);
+        s_fsm.addTransition(Destroy, VolumeEvent.OperationSucceeded, Destroy);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/src/org/apache/cloudstack/storage/volume/db/VolumeDao.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/db/VolumeDao.java b/engine/storage/src/org/apache/cloudstack/storage/volume/db/VolumeDao.java
new file mode 100644
index 0000000..0f29727
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/volume/db/VolumeDao.java
@@ -0,0 +1,82 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.storage.volume.db;
+
+import java.util.List;
+
+import org.apache.cloudstack.storage.volume.Volume;
+import org.apache.cloudstack.storage.volume.VolumeEvent;
+import org.apache.cloudstack.storage.volume.VolumeState;
+import org.apache.cloudstack.storage.volume.disktype.VolumeDiskType;
+import org.apache.cloudstack.storage.volume.type.VolumeType;
+
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.storage.Storage.ImageFormat;
+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<VolumeState, VolumeEvent, VolumeVO> {
+    
+	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, VolumeType 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);
+
+    VolumeVO allocVolume(long size, VolumeType type, String volName, Long templateId);
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/src/org/apache/cloudstack/storage/volume/db/VolumeDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/db/VolumeDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/volume/db/VolumeDaoImpl.java
new file mode 100644
index 0000000..ca51bac
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/volume/db/VolumeDaoImpl.java
@@ -0,0 +1,427 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.storage.volume.db;
+
+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.storage.volume.Volume;
+import org.apache.cloudstack.storage.volume.VolumeEvent;
+import org.apache.cloudstack.storage.volume.VolumeState;
+import org.apache.cloudstack.storage.volume.disktype.VolumeDiskType;
+import org.apache.cloudstack.storage.volume.type.RootDisk;
+import org.apache.cloudstack.storage.volume.type.VolumeType;
+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.tags.dao.ResourceTagsDaoImpl;
+import com.cloud.utils.Pair;
+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.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;
+
+@Local(value=VolumeDao.class)
+@Component
+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;
+    ResourceTagsDaoImpl _tagsDao = ComponentLocator.inject(ResourceTagsDaoImpl.class);
+    
+    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", VolumeState.Destroy);
+    	return listBy(sc);
+    }
+    
+    @Override
+    public List<VolumeVO> findByAccount(long accountId) {
+        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+        sc.setParameters("accountId", accountId);
+        sc.setParameters("state", VolumeState.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", VolumeState.Destroy);
+        sc.setParameters("vType", new RootDisk().toString());
+	    return listBy(sc);
+	}
+    
+    @Override 
+    public List<VolumeVO> findCreatedByInstance(long id) {
+        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+        sc.setParameters("instanceId", id);
+        sc.setParameters("state", VolumeState.Ready);
+        return listBy(sc);
+    }
+    
+    @Override
+    public List<VolumeVO> findUsableVolumesForInstance(long instanceId) {
+        SearchCriteria<VolumeVO> sc = InstanceStatesSearch.create();
+        sc.setParameters("instance", instanceId);
+        sc.setParameters("states", VolumeState.Creating, VolumeState.Ready, VolumeState.Allocated);
+        
+        return listBy(sc);
+    }
+    
+	@Override
+	public List<VolumeVO> findByInstanceAndType(long id, VolumeType 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", VolumeState.Destroy);
+		return listBy(sc);
+	}
+	
+	@Override
+	public List<VolumeVO> findReadyRootVolumesByInstance(long instanceId) {
+		SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+		sc.setParameters("instanceId", instanceId);
+		sc.setParameters("state", VolumeState.Ready);
+		sc.setParameters("vType", new RootDisk().toString());		
+		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", VolumeState.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;
+        }
+    }
+    
+	protected 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();
+	}
+
+	@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", VolumeState.Destroy);
+        return customSearch(sc, null).get(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", VolumeState.Destroy);
+        
+        return listBy(sc);
+    }
+
+	@Override
+	public boolean updateState(VolumeState currentState,
+			VolumeEvent event, VolumeState nextState, VolumeVO 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", VolumeState.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;
+    }
+    
+    @Override
+    @DB
+    public VolumeVO allocVolume(long size, VolumeType type, String volName, Long templateId) {
+    	VolumeVO vol = new VolumeVO(size, type.toString(), volName, templateId);
+    	vol = this.persist(vol);
+    	return vol;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/src/org/apache/cloudstack/storage/volume/db/VolumeVO.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/db/VolumeVO.java b/engine/storage/src/org/apache/cloudstack/storage/volume/db/VolumeVO.java
new file mode 100644
index 0000000..48da123
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/volume/db/VolumeVO.java
@@ -0,0 +1,425 @@
+//Licensed to the Apache Software Foundation (ASF) under one
+//or more contributor license agreements.  See the NOTICE file
+//distributed with this work for additional information
+//regarding copyright ownership.  The ASF licenses this file
+//to you under the Apache License, Version 2.0 (the
+//"License"); you may not use this file except in compliance
+//with the License.  You may obtain a copy of the License at
+//
+//http://www.apache.org/licenses/LICENSE-2.0
+//
+//Unless required by applicable law or agreed to in writing,
+//software distributed under the License is distributed on an
+//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+//KIND, either express or implied.  See the License for the
+//specific language governing permissions and limitations
+//under the License.
+
+package org.apache.cloudstack.storage.volume.db;
+import java.util.Date;
+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 javax.persistence.TableGenerator;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+import org.apache.cloudstack.storage.volume.VolumeState;
+import org.apache.cloudstack.storage.volume.disktype.Unknown;
+import org.apache.cloudstack.storage.volume.type.VolumeType;
+
+import com.cloud.api.Identity;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.db.GenericDao;
+import com.cloud.utils.fsm.StateObject;
+
+@Entity
+@Table(name = "volumes")
+public class VolumeVO implements Identity, StateObject<VolumeState>{
+ @Id
+ @TableGenerator(name = "volume_sq", table = "sequence", pkColumnName = "name", valueColumnName = "value", pkColumnValue = "volume_seq", allocationSize = 1)
+ @GeneratedValue(strategy = GenerationType.TABLE)
+ @Column(name = "id")
+ long id;
+
+ @Column(name = "name")
+ String name;
+
+ @Column(name = "pool_id")
+ Long poolId;
+ 
+ @Column(name = "last_pool_id")
+ Long lastPoolId;
+ 
+ @Column(name = "account_id")
+ long accountId;
+
+ @Column(name = "domain_id")
+ long domainId;
+
+ @Column(name = "instance_id")
+ Long instanceId = null;
+
+ @Column(name = "device_id")
+ Long deviceId = null;
+
+ @Column(name = "size")
+ long size;
+
+ @Column(name = "folder")
+ String folder;
+
+ @Column(name = "path")
+ String path;
+
+ @Column(name = "pod_id")
+ Long podId;
+
+ @Column(name = "created")
+ Date created;
+
+ @Column(name = "attached")
+ @Temporal(value = TemporalType.TIMESTAMP)
+ Date attached;
+
+ @Column(name = "data_center_id")
+ long dataCenterId;
+
+ @Column(name = "host_ip")
+ String hostip;
+
+ @Column(name = "disk_offering_id")
+ long diskOfferingId;
+
+ @Column(name = "template_id")
+ Long templateId;
+
+ @Column(name = "first_snapshot_backup_uuid")
+ String firstSnapshotBackupUuid;
+
+ @Column(name = "volume_type")
+ String volumeType = "UNKNOWN";
+
+ @Column(name = "pool_type")
+ @Enumerated(EnumType.STRING)
+ StoragePoolType poolType;
+ 
+ @Column(name = "disk_type")
+ String diskType = new Unknown().toString();
+ 
+ @Column(name = GenericDao.REMOVED_COLUMN)
+ Date removed;
+
+ @Column(name = "updated")
+ @Temporal(value = TemporalType.TIMESTAMP)
+ Date updated;
+ 
+ @Column(name="update_count", updatable = true, nullable=false)
+ protected long updatedCount;	// This field should be updated everytime the state is updated.  There's no set method in the vo object because it is done with in the dao code.
+
+ @Column(name = "recreatable")
+ boolean recreatable;
+
+ @Column(name = "state")
+ @Enumerated(value = EnumType.STRING)
+ private VolumeState state;
+
+ @Column(name = "chain_info")
+ String chainInfo;
+
+ @Column(name = "uuid")
+ String uuid;
+ 
+ @Column(name="reservation")
+ String reservationId;
+ 
+ // Real Constructor
+ public VolumeVO(long size, String type, String name, Long templateId) {
+     this.volumeType = type.toString();
+     this.size = size;
+     this.name = name;
+     this.templateId = templateId;
+     this.uuid = UUID.randomUUID().toString();
+ }
+
+ // Copy Constructor
+ public VolumeVO(VolumeVO that) {
+     this(that.getSize(), that.getVolumeType(), that.getName(), that.getTemplateId());
+     this.recreatable = that.isRecreatable();
+     this.state = that.getState();
+     this.size = that.getSize();
+     this.diskOfferingId = that.getDiskOfferingId();
+     this.poolId = that.getPoolId();
+     this.attached = that.getAttached();
+     this.chainInfo = that.getChainInfo();
+     this.templateId = that.getTemplateId();
+     this.deviceId = that.getDeviceId();
+     this.uuid = UUID.randomUUID().toString();
+ }
+
+ public long getUpdatedCount() {
+ 	return this.updatedCount;
+ }
+ 
+ public void incrUpdatedCount() {
+ 	this.updatedCount++;
+ }
+ 
+ public void decrUpdatedCount() {
+ 	this.updatedCount--;
+ }
+ 
+ public boolean isRecreatable() {
+     return recreatable;
+ }
+
+ public void setRecreatable(boolean recreatable) {
+     this.recreatable = recreatable;
+ }
+
+ public long getId() {
+     return id;
+ }
+
+
+ public Long getPodId() {
+     return podId;
+ }
+
+
+ public long getDataCenterId() {
+     return dataCenterId;
+ }
+
+ public String getName() {
+     return name;
+ }
+
+ public long getAccountId() {
+     return accountId;
+ }
+
+ public void setPoolType(StoragePoolType poolType) {
+     this.poolType = poolType;
+ }
+
+ public StoragePoolType getPoolType() {
+     return poolType;
+ }
+
+ public long getDomainId() {
+     return domainId;
+ }
+
+ public String getFolder() {
+     return folder;
+ }
+
+ public String getPath() {
+     return path;
+ }
+
+ protected VolumeVO() {
+ }
+
+ public long getSize() {
+     return size;
+ }
+
+ public void setSize(long size) {
+     this.size = size;
+ }
+
+ public Long getInstanceId() {
+     return instanceId;
+ }
+
+ public Long getDeviceId() {
+     return deviceId;
+ }
+
+ public void setDeviceId(Long deviceId) {
+     this.deviceId = deviceId;
+ }
+
+ public String getVolumeType() {
+     return volumeType;
+ }
+
+ public void setName(String name) {
+     this.name = name;
+ }
+
+ public void setFolder(String folder) {
+     this.folder = folder;
+ }
+
+ public void setAccountId(long accountId) {
+     this.accountId = accountId;
+ }
+
+ public void setDomainId(long domainId) {
+     this.domainId = domainId;
+ }
+
+ public void setInstanceId(Long instanceId) {
+     this.instanceId = instanceId;
+ }
+
+ public void setPath(String path) {
+     this.path = path;
+ }
+
+ public String getHostIp() {
+     return hostip;
+ }
+
+ public void setHostIp(String hostip) {
+     this.hostip = hostip;
+ }
+
+ public void setPodId(Long podId) {
+     this.podId = podId;
+ }
+
+ public void setDataCenterId(long dataCenterId) {
+     this.dataCenterId = dataCenterId;
+ }
+
+ public void setVolumeType(String type) {
+     volumeType = type;
+ }
+
+ public Date getCreated() {
+     return created;
+ }
+
+ public Date getRemoved() {
+     return removed;
+ }
+
+ public void setRemoved(Date removed) {
+     this.removed = removed;
+ }
+
+ public long getDiskOfferingId() {
+     return diskOfferingId;
+ }
+
+ public void setDiskOfferingId(long diskOfferingId) {
+     this.diskOfferingId = diskOfferingId;
+ }
+
+ public Long getTemplateId() {
+     return templateId;
+ }
+
+ public void setTemplateId(Long templateId) {
+     this.templateId = templateId;
+ }
+
+ public String getFirstSnapshotBackupUuid() {
+     return firstSnapshotBackupUuid;
+ }
+
+ public void setFirstSnapshotBackupUuid(String firstSnapshotBackupUuid) {
+     this.firstSnapshotBackupUuid = firstSnapshotBackupUuid;
+ }
+
+ public Long getPoolId() {
+     return poolId;
+ }
+
+ public void setPoolId(Long poolId) {
+     this.poolId = poolId;
+ }
+
+ public Date getUpdated() {
+     return updated;
+ }
+
+ public VolumeState getState() {
+     return state;
+ }
+
+ public void setUpdated(Date updated) {
+     this.updated = updated;
+ }
+
+ @Override
+ public String toString() {
+     return new StringBuilder("Vol[").append(id).append("|vm=").append(instanceId).append("|").append(volumeType).append("]").toString();
+ }
+
+ public Date getAttached() {
+     return this.attached;
+ }
+
+ public void setAttached(Date attached) {
+     this.attached = attached;
+ }
+ 
+ public String getChainInfo() {
+     return this.chainInfo;
+ }
+
+ public void setChainInfo(String chainInfo) {
+     this.chainInfo = chainInfo;
+ }
+ 
+ public Long getLastPoolId() {
+ 	return this.lastPoolId;
+ }
+ 
+ public void setLastPoolId(Long poolId) {
+ 	this.lastPoolId = poolId;
+ }
+
+ @Override
+ public int hashCode() {
+     return NumbersUtil.hash(id);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+     if (obj instanceof VolumeVO) {
+         return id == ((VolumeVO) obj).id;
+     } else {
+         return false;
+     }
+ }
+ 
+ public String getReservationId() {
+ 	return this.reservationId;
+ }
+
+ public void setReservationId(String reserv) {
+ 	this.reservationId = reserv;
+ }
+ 
+ @Override
+ public String getUuid() {
+ 	return this.uuid;
+ }
+ 
+ public void setUuid(String uuid) {
+ 	this.uuid = uuid;
+ }
+ 
+ public String getDiskType() {
+	 return diskType;
+ }
+ 
+ public void setDiskType(String type) {
+	 diskType = type;
+ }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/src/org/apache/cloudstack/storage/volume/disktype/QCOW2.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/disktype/QCOW2.java b/engine/storage/src/org/apache/cloudstack/storage/volume/disktype/QCOW2.java
new file mode 100644
index 0000000..105801c
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/volume/disktype/QCOW2.java
@@ -0,0 +1,10 @@
+package org.apache.cloudstack.storage.volume.disktype;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class QCOW2 extends VolumeDiskTypeBase {
+	public QCOW2() {
+		this.type = "QCOW2";
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/src/org/apache/cloudstack/storage/volume/disktype/Unknown.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/disktype/Unknown.java b/engine/storage/src/org/apache/cloudstack/storage/volume/disktype/Unknown.java
new file mode 100644
index 0000000..e22acce
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/volume/disktype/Unknown.java
@@ -0,0 +1,7 @@
+package org.apache.cloudstack.storage.volume.disktype;
+
+public class Unknown extends VolumeDiskTypeBase {
+	public Unknown() {
+		this.type = "Unknown";
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/src/org/apache/cloudstack/storage/volume/disktype/VHD.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/disktype/VHD.java b/engine/storage/src/org/apache/cloudstack/storage/volume/disktype/VHD.java
new file mode 100644
index 0000000..4535748
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/volume/disktype/VHD.java
@@ -0,0 +1,10 @@
+package org.apache.cloudstack.storage.volume.disktype;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class VHD extends VolumeDiskTypeBase {
+	public VHD() {
+		this.type = "VHD";
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/src/org/apache/cloudstack/storage/volume/disktype/VMDK.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/disktype/VMDK.java b/engine/storage/src/org/apache/cloudstack/storage/volume/disktype/VMDK.java
new file mode 100644
index 0000000..10623ab
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/volume/disktype/VMDK.java
@@ -0,0 +1,10 @@
+package org.apache.cloudstack.storage.volume.disktype;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class VMDK extends VolumeDiskTypeBase {
+	public VMDK() {
+		this.type = "VMDK";
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/src/org/apache/cloudstack/storage/volume/disktype/VolumeDiskType.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/disktype/VolumeDiskType.java b/engine/storage/src/org/apache/cloudstack/storage/volume/disktype/VolumeDiskType.java
new file mode 100644
index 0000000..1832fe3
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/volume/disktype/VolumeDiskType.java
@@ -0,0 +1,4 @@
+package org.apache.cloudstack.storage.volume.disktype;
+
+public interface VolumeDiskType {
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/src/org/apache/cloudstack/storage/volume/disktype/VolumeDiskTypeBase.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/disktype/VolumeDiskTypeBase.java b/engine/storage/src/org/apache/cloudstack/storage/volume/disktype/VolumeDiskTypeBase.java
new file mode 100644
index 0000000..083d49c
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/volume/disktype/VolumeDiskTypeBase.java
@@ -0,0 +1,34 @@
+package org.apache.cloudstack.storage.volume.disktype;
+
+public class VolumeDiskTypeBase implements VolumeDiskType {
+	protected String type = "Unknown";
+
+	@Override
+	public boolean equals(Object that) {
+		if (this == that) {
+			return true;
+		}
+		if (that instanceof String) {
+			if (getType().equalsIgnoreCase((String)that)) {
+				return true;
+			}
+		} else if (that instanceof VolumeDiskTypeBase) {
+			VolumeDiskTypeBase th = (VolumeDiskTypeBase)that;
+			if (this.getType().equalsIgnoreCase(th.getType())) {
+				return true;
+			}
+		} else {
+			return false;
+		}
+		return false;
+	}
+	
+	@Override
+	public String toString() {
+		return getType();
+	}
+	
+	protected String getType() {
+		return this.type;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/src/org/apache/cloudstack/storage/volume/disktype/VolumeDiskTypeHelper.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/disktype/VolumeDiskTypeHelper.java b/engine/storage/src/org/apache/cloudstack/storage/volume/disktype/VolumeDiskTypeHelper.java
new file mode 100644
index 0000000..c51e25f
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/volume/disktype/VolumeDiskTypeHelper.java
@@ -0,0 +1,29 @@
+package org.apache.cloudstack.storage.volume.disktype;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class VolumeDiskTypeHelper {
+	
+	static private List<VolumeDiskType> diskTypes;
+	static final private VolumeDiskType defaultType = new Unknown();
+	
+	@Inject
+	public void setDiskTypes(List<VolumeDiskType> diskTypes) {
+		VolumeDiskTypeHelper.diskTypes = diskTypes;
+	}
+	
+	public static VolumeDiskType getDiskType(String type) {
+		for (VolumeDiskType diskType : diskTypes) {
+			if (diskType.equals(type)) {
+				return diskType;
+			}
+		}
+		
+		return VolumeDiskTypeHelper.defaultType;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/src/org/apache/cloudstack/storage/volume/type/DataDisk.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/type/DataDisk.java b/engine/storage/src/org/apache/cloudstack/storage/volume/type/DataDisk.java
new file mode 100644
index 0000000..1e30768
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/volume/type/DataDisk.java
@@ -0,0 +1,10 @@
+package org.apache.cloudstack.storage.volume.type;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class DataDisk extends VolumeTypeBase {
+	public DataDisk() {
+		this.type = "DataDisk";
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/src/org/apache/cloudstack/storage/volume/type/Iso.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/type/Iso.java b/engine/storage/src/org/apache/cloudstack/storage/volume/type/Iso.java
new file mode 100644
index 0000000..61e4e35
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/volume/type/Iso.java
@@ -0,0 +1,10 @@
+package org.apache.cloudstack.storage.volume.type;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class Iso extends VolumeTypeBase {
+	public Iso() {
+		this.type = "iso";
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/src/org/apache/cloudstack/storage/volume/type/RootDisk.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/type/RootDisk.java b/engine/storage/src/org/apache/cloudstack/storage/volume/type/RootDisk.java
new file mode 100644
index 0000000..c616cea
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/volume/type/RootDisk.java
@@ -0,0 +1,10 @@
+package org.apache.cloudstack.storage.volume.type;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class RootDisk extends VolumeTypeBase {
+	public RootDisk() {
+		this.type = "Root";
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/src/org/apache/cloudstack/storage/volume/type/Unknown.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/type/Unknown.java b/engine/storage/src/org/apache/cloudstack/storage/volume/type/Unknown.java
new file mode 100644
index 0000000..c1a77b1
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/volume/type/Unknown.java
@@ -0,0 +1,8 @@
+package org.apache.cloudstack.storage.volume.type;
+
+public class Unknown extends VolumeTypeBase {
+	public Unknown() {
+		this.type = "Unknown";
+	}
+
+}

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

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/src/org/apache/cloudstack/storage/volume/type/VolumeTypeBase.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/type/VolumeTypeBase.java b/engine/storage/src/org/apache/cloudstack/storage/volume/type/VolumeTypeBase.java
new file mode 100644
index 0000000..830873c
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/volume/type/VolumeTypeBase.java
@@ -0,0 +1,31 @@
+package org.apache.cloudstack.storage.volume.type;
+
+public class VolumeTypeBase implements VolumeType {
+	protected String type = "Unknown";
+	
+	@Override
+	public boolean equals(Object that) {
+		if (this == that) {
+			return true;
+		}
+		if (that instanceof String) {
+			if (this.toString().equalsIgnoreCase((String)that)) {
+				return true;
+			}
+		} else if (that instanceof VolumeTypeBase) {
+			VolumeTypeBase th = (VolumeTypeBase)that;
+			if (this.toString().equalsIgnoreCase(th.toString())) {
+				return true;
+			}
+		} else {
+			return false;
+		}
+		return false;
+	}
+	
+	@Override
+	public String toString() {
+		return type;
+	}
+	
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/src/org/apache/cloudstack/storage/volume/type/VolumeTypeHelper.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/type/VolumeTypeHelper.java b/engine/storage/src/org/apache/cloudstack/storage/volume/type/VolumeTypeHelper.java
new file mode 100644
index 0000000..9443475
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/volume/type/VolumeTypeHelper.java
@@ -0,0 +1,28 @@
+package org.apache.cloudstack.storage.volume.type;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class VolumeTypeHelper {
+	static private List<VolumeType> types;
+	private static VolumeType defaultType = new Unknown();
+	
+	@Inject
+	public void setTypes(List<VolumeType> types) {
+		VolumeTypeHelper.types = types;
+	}
+	
+	public static VolumeType getType(String type) {
+		for (VolumeType ty : types) {
+			if (ty.equals(type)) {
+				return ty;
+			}
+		}
+		return VolumeTypeHelper.defaultType;
+	}
+	
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/test/org/apache/cloudstack/storage/test/AllTests.java
----------------------------------------------------------------------
diff --git a/engine/storage/test/org/apache/cloudstack/storage/test/AllTests.java b/engine/storage/test/org/apache/cloudstack/storage/test/AllTests.java
new file mode 100644
index 0000000..dde4484
--- /dev/null
+++ b/engine/storage/test/org/apache/cloudstack/storage/test/AllTests.java
@@ -0,0 +1,29 @@
+/*
+ * 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.test;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({ volumeServiceTest.class })
+public class AllTests {
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/test/org/apache/cloudstack/storage/test/AopTest.java
----------------------------------------------------------------------
diff --git a/engine/storage/test/org/apache/cloudstack/storage/test/AopTest.java b/engine/storage/test/org/apache/cloudstack/storage/test/AopTest.java
new file mode 100644
index 0000000..0c2a2ad
--- /dev/null
+++ b/engine/storage/test/org/apache/cloudstack/storage/test/AopTest.java
@@ -0,0 +1,14 @@
+package org.apache.cloudstack.storage.test;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+@Target({TYPE, METHOD})
+@Retention(RUNTIME)
+public @interface AopTest {
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/test/org/apache/cloudstack/storage/test/AopTestAdvice.java
----------------------------------------------------------------------
diff --git a/engine/storage/test/org/apache/cloudstack/storage/test/AopTestAdvice.java b/engine/storage/test/org/apache/cloudstack/storage/test/AopTestAdvice.java
new file mode 100644
index 0000000..9bdec74
--- /dev/null
+++ b/engine/storage/test/org/apache/cloudstack/storage/test/AopTestAdvice.java
@@ -0,0 +1,20 @@
+package org.apache.cloudstack.storage.test;
+
+import org.aspectj.lang.ProceedingJoinPoint;
+
+import com.cloud.utils.db.Transaction;
+
+public class AopTestAdvice {
+	public Object AopTestMethod(ProceedingJoinPoint call) throws Throwable {
+		Transaction txn = Transaction.open(call.getSignature().getName());
+		System.out.println(call.getSignature().getName());
+		Object ret = null;
+		try {
+			 ret = call.proceed();
+		} finally {
+			txn.close();
+		}
+		System.out.println("end");
+		return ret;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/test/org/apache/cloudstack/storage/test/StorageFactoryBean.java
----------------------------------------------------------------------
diff --git a/engine/storage/test/org/apache/cloudstack/storage/test/StorageFactoryBean.java b/engine/storage/test/org/apache/cloudstack/storage/test/StorageFactoryBean.java
new file mode 100644
index 0000000..68952b1
--- /dev/null
+++ b/engine/storage/test/org/apache/cloudstack/storage/test/StorageFactoryBean.java
@@ -0,0 +1,42 @@
+package org.apache.cloudstack.storage.test;
+
+
+import org.mockito.Mockito;
+import org.springframework.beans.factory.FactoryBean;
+
+/**
+ * A {@link FactoryBean} for creating mocked beans based on Mockito so that they 
+ * can be {@link @Autowired} into Spring test configurations.
+ *
+ * @author Mattias Severson, Jayway
+ *
+ * @see FactoryBean
+ * @see org.mockito.Mockito
+ */
+public class StorageFactoryBean<T> implements FactoryBean<T> {
+
+    private Class<T> classToBeMocked;
+
+    /**
+     * Creates a Mockito mock instance of the provided class.
+     * @param classToBeMocked The class to be mocked.
+     */
+    public StorageFactoryBean(Class<T> classToBeMocked) {
+        this.classToBeMocked = classToBeMocked;
+    }
+
+    @Override
+    public T getObject() throws Exception {
+        return Mockito.mock(classToBeMocked);
+    }
+
+    @Override
+    public Class<?> getObjectType() {
+        return classToBeMocked;
+    }
+
+    @Override
+    public boolean isSingleton() {
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a6df8a5b/engine/storage/test/org/apache/cloudstack/storage/test/storageContext.xml
----------------------------------------------------------------------
diff --git a/engine/storage/test/org/apache/cloudstack/storage/test/storageContext.xml b/engine/storage/test/org/apache/cloudstack/storage/test/storageContext.xml
new file mode 100644
index 0000000..c32004b
--- /dev/null
+++ b/engine/storage/test/org/apache/cloudstack/storage/test/storageContext.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
+  xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
+  xsi:schemaLocation="http://www.springframework.org/schema/beans
+                        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+                         http://www.springframework.org/schema/tx 
+       http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
+       http://www.springframework.org/schema/aop
+       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
+                                 http://www.springframework.org/schema/context
+                                          http://www.springframework.org/schema/context/spring-context-3.0.xsd">
+  <context:annotation-config />
+  <context:component-scan base-package="org.apache.cloudstack.storage" />
+  <context:component-scan base-package="com.cloud.utils.db" />
+  <context:component-scan base-package="com.cloud.utils.component" />
+  <context:component-scan base-package="com.cloud.storage.dao" />
+ 
+   <context:component-scan base-package=" com.cloud.upgrade.dao" />
+  <tx:annotation-driven transaction-manager="transactionManager" />
+  <bean id="aopTestBean" class="org.apache.cloudstack.storage.test.AopTestAdvice"/>
+  <aop:config proxy-target-class="true" >
+    <aop:aspect id="AopTestAdvice" ref="aopTestBean">
+    <aop:pointcut id="aoptest"
+      expression="@annotation(com.cloud.utils.db.DB)" />
+      <aop:around pointcut-ref="aoptest" method="AopTestMethod"/> 
+    </aop:aspect>
+    
+
+  </aop:config>
+  <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
+    <property name="entityManagerFactory" ref="entityManagerFactory" />
+  </bean>
+
+  <bean id="dataSource"
+    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
+    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
+    <property name="url" value="jdbc:mysql://localhost:3306/cloud" />
+    <property name="username" value="root" />
+    <property name="password" value="" />
+  </bean>
+
+  <bean id="openJpaVendorAdapter"
+    class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter">
+    <property name="showSql" value="true" />
+    <property name="databasePlatform"
+      value="org.apache.openjpa.jdbc.sql.MySQLDictionary" />
+  </bean>
+
+  <bean id="entityManagerFactory"
+    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
+    <property name="dataSource" ref="dataSource" />
+    <property name="jpaVendorAdapter" ref="openJpaVendorAdapter" />
+    <property name="packagesToScan" value="org.apache.cloudstack.storage" />
+  </bean>
+
+  <bean id="sharedEntityManager"
+    class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
+    <property name="entityManagerFactory" ref="entityManagerFactory" />
+  </bean>
+
+  <bean id="someDependencyMock" class="org.apache.cloudstack.storage.test.StorageFactoryBean">
+    <constructor-arg name="classToBeMocked"
+      value="org.apache.cloudstack.storage.volume.VolumeMotionService" />
+  </bean>
+
+</beans>


Mime
View raw message