You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ed...@apache.org on 2012/11/28 04:17:39 UTC
[6/6] seperate code into different modules: storage, storage/volume,
storage/image, storage/snapshot, storage/backup, storage/integration-test
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/225ad3c2/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeManagerImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeManagerImpl.java
new file mode 100644
index 0000000..e6508e6
--- /dev/null
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeManagerImpl.java
@@ -0,0 +1,103 @@
+/*
+ * 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.engine.subsystem.api.storage.VolumeProfile;
+import org.apache.cloudstack.storage.volume.db.VolumeDao;
+import org.apache.cloudstack.storage.volume.db.VolumeVO;
+import org.springframework.stereotype.Component;
+
+import com.cloud.storage.Volume;
+import com.cloud.storage.Volume.Event;
+import com.cloud.storage.Volume.State;
+import com.cloud.utils.component.Inject;
+import com.cloud.utils.fsm.NoTransitionException;
+import com.cloud.utils.fsm.StateMachine2;
+
+@Component
+public class VolumeManagerImpl implements VolumeManager {
+ @Inject
+ protected VolumeDao _volumeDao;
+ private final static StateMachine2<State, Event, VolumeVO> s_fsm = new StateMachine2<State, Event, VolumeVO>();
+ public VolumeManagerImpl() {
+ initStateMachine();
+ }
+
+ 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);
+ }
+
+ private void initStateMachine() {
+ s_fsm.addTransition(Volume.State.Allocated, Event.CreateRequested, Volume.State.Creating);
+ s_fsm.addTransition(Volume.State.Allocated, Event.DestroyRequested, Volume.State.Destroy);
+ s_fsm.addTransition(Volume.State.Creating, Event.OperationRetry, Volume.State.Creating);
+ s_fsm.addTransition(Volume.State.Creating, Event.OperationFailed, Volume.State.Allocated);
+ s_fsm.addTransition(Volume.State.Creating, Event.OperationSucceeded, Volume.State.Ready);
+ s_fsm.addTransition(Volume.State.Creating, Event.DestroyRequested, Volume.State.Destroy);
+ s_fsm.addTransition(Volume.State.Creating, Event.CreateRequested, Volume.State.Creating);
+ s_fsm.addTransition(Volume.State.Allocated, Event.UploadRequested, Volume.State.UploadOp);
+ s_fsm.addTransition(Volume.State.UploadOp, Event.CopyRequested, Volume.State.Creating);// CopyRequested for volume from sec to primary storage
+ s_fsm.addTransition(Volume.State.Creating, Event.CopySucceeded, Volume.State.Ready);
+ s_fsm.addTransition(Volume.State.Creating, Event.CopyFailed, Volume.State.UploadOp);// Copying volume from sec to primary failed.
+ s_fsm.addTransition(Volume.State.UploadOp, Event.DestroyRequested, Volume.State.Destroy);
+ s_fsm.addTransition(Volume.State.Ready, Event.DestroyRequested, Volume.State.Destroy);
+ s_fsm.addTransition(Volume.State.Destroy, Event.ExpungingRequested, Volume.State.Expunging);
+ s_fsm.addTransition(Volume.State.Ready, Event.SnapshotRequested, Volume.State.Snapshotting);
+ s_fsm.addTransition(Volume.State.Snapshotting, Event.OperationSucceeded, Volume.State.Ready);
+ s_fsm.addTransition(Volume.State.Snapshotting, Event.OperationFailed, Volume.State.Ready);
+ s_fsm.addTransition(Volume.State.Ready, Event.MigrationRequested, Volume.State.Migrating);
+ s_fsm.addTransition(Volume.State.Migrating, Event.OperationSucceeded, Volume.State.Ready);
+ s_fsm.addTransition(Volume.State.Migrating, Event.OperationFailed, Volume.State.Ready);
+ s_fsm.addTransition(Volume.State.Destroy, Event.OperationSucceeded, Volume.State.Destroy);
+ }
+
+ @Override
+ public StateMachine2<State, Event, VolumeVO> getStateMachine() {
+ return s_fsm;
+ }
+
+ 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/225ad3c2/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeMotionService.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeMotionService.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeMotionService.java
new file mode 100644
index 0000000..9349e6b
--- /dev/null
+++ b/engine/storage/volume/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/225ad3c2/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
new file mode 100644
index 0000000..f0eb1b5
--- /dev/null
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
@@ -0,0 +1,143 @@
+package org.apache.cloudstack.storage.volume;
+
+import java.util.Date;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskType;
+import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskTypeHelper;
+import org.apache.cloudstack.engine.subsystem.api.storage.type.VolumeType;
+import org.apache.cloudstack.engine.subsystem.api.storage.type.VolumeTypeHelper;
+import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
+import org.apache.cloudstack.storage.volume.db.VolumeDao;
+import org.apache.cloudstack.storage.volume.db.VolumeVO;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.storage.Volume;
+import com.cloud.storage.Volume.State;
+import com.cloud.utils.component.ComponentInject;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.NoTransitionException;
+import com.cloud.utils.fsm.StateMachine2;
+
+public class VolumeObject implements VolumeInfo {
+ private static final Logger s_logger = Logger.getLogger(VolumeObject.class);
+ protected VolumeVO volumeVO;
+ private StateMachine2<Volume.State, Volume.Event, VolumeVO> _volStateMachine;
+ protected PrimaryDataStore dataStore;
+ @Inject
+ VolumeDiskTypeHelper diskTypeHelper;
+ @Inject
+ VolumeTypeHelper volumeTypeHelper;
+ @Inject
+ VolumeDao volumeDao;
+ @Inject
+ VolumeManager volumeMgr;
+ private VolumeObject(PrimaryDataStore dataStore, VolumeVO volumeVO) {
+ this.volumeVO = volumeVO;
+ this.dataStore = dataStore;
+ }
+
+ public static VolumeObject getVolumeObject(PrimaryDataStore dataStore, VolumeVO volumeVO) {
+ VolumeObject vo = new VolumeObject(dataStore, volumeVO);
+ vo = ComponentInject.inject(vo);
+ return vo;
+ }
+
+ public String getUuid() {
+ return volumeVO.getUuid();
+ }
+
+ public void setPath(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 Volume.State 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(Volume.Event event) {
+ boolean result = false;
+ _volStateMachine = volumeMgr.getStateMachine();
+ try {
+ result = _volStateMachine.transitTo(volumeVO, event, null, volumeDao);
+ } catch (NoTransitionException e) {
+ String errorMessage = "Failed to transit volume: " + this.getVolumeId() + ", due to: " + e.toString();
+ s_logger.debug(errorMessage);
+ throw new CloudRuntimeException(errorMessage);
+ }
+ return result;
+ }
+
+ public void update() {
+ volumeDao.update(volumeVO.getId(), volumeVO);
+ volumeVO = volumeDao.findById(volumeVO.getId());
+ }
+
+ @Override
+ public long getId() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public State getCurrentState() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public State getDesiredState() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Date getCreatedData() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/225ad3c2/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
new file mode 100644
index 0000000..0e6ed9f
--- /dev/null
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
@@ -0,0 +1,187 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.volume;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.cloud.entity.api.TemplateEntity;
+import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskType;
+import org.apache.cloudstack.engine.subsystem.api.storage.type.BaseImage;
+import org.apache.cloudstack.engine.subsystem.api.storage.type.VolumeType;
+import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
+import org.apache.cloudstack.storage.datastore.manager.PrimaryDataStoreManager;
+import org.apache.cloudstack.storage.image.TemplateEntityImpl;
+import org.apache.cloudstack.storage.image.TemplateInfo;
+import org.apache.cloudstack.storage.image.motion.ImageMotionService;
+import org.apache.cloudstack.storage.volume.db.VolumeDao;
+import org.apache.cloudstack.storage.volume.db.VolumeVO;
+
+import org.springframework.stereotype.Service;
+
+import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
+import com.cloud.storage.Volume;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+//1. change volume state
+//2. orchestrator of volume, control most of the information of volume, storage pool id, voluem state, scope etc.
+
+@Service
+public class VolumeServiceImpl implements VolumeService {
+ @Inject
+ VolumeDao volDao;
+ @Inject
+ PrimaryDataStoreManager dataStoreMgr;
+ @Inject
+ TemplatePrimaryDataStoreManager templatePrimaryStoreMgr;
+ @Inject
+ ImageMotionService imageMotion;
+
+ @Override
+ public VolumeInfo createVolume(VolumeInfo volume, long dataStoreId, VolumeDiskType diskType) {
+ PrimaryDataStore dataStore = dataStoreMgr.getPrimaryDataStore(dataStoreId);
+ if (dataStore == null) {
+ throw new CloudRuntimeException("Can't find dataStoreId: " + dataStoreId);
+ }
+
+ if (dataStore.exists(volume)) {
+ return volume;
+ }
+
+ VolumeObject vo = (VolumeObject) volume;
+ vo.stateTransit(Volume.Event.CreateRequested);
+
+ try {
+ VolumeInfo vi = dataStore.createVolume(vo, diskType);
+ vo.stateTransit(Volume.Event.OperationSucceeded);
+ return vi;
+ } catch (Exception e) {
+ vo.stateTransit(Volume.Event.OperationFailed);
+ throw new CloudRuntimeException(e.toString());
+ }
+ }
+
+ @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 boolean rokeAccess(long volumeId, long endpointId) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public VolumeEntity allocateVolumeInDb(long size, VolumeType type, String volName, Long templateId) {
+ VolumeVO vo = volDao.allocVolume(size, type, volName, templateId);
+ return new VolumeEntityImpl(VolumeObject.getVolumeObject(null, vo), this);
+ }
+
+ @Override
+ public VolumeEntity getVolumeEntity(long volumeId) {
+ VolumeVO vo = volDao.findById(volumeId);
+ if (vo == null) {
+ return null;
+ }
+
+ if (vo.getPoolId() == null) {
+ return new VolumeEntityImpl(VolumeObject.getVolumeObject(null, vo), this);
+ } else {
+ PrimaryDataStore dataStore = dataStoreMgr.getPrimaryDataStore(vo.getPoolId());
+ return new VolumeEntityImpl(dataStore.getVolume(volumeId), this);
+ }
+ }
+
+ @Override
+ public String grantAccess(VolumeInfo volume, EndPoint endpointId) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ protected TemplateOnPrimaryDataStoreObject createBaseImage(PrimaryDataStore dataStore, TemplateInfo template) {
+ TemplateOnPrimaryDataStoreObject templateOnPrimaryStoreObj = (TemplateOnPrimaryDataStoreObject) templatePrimaryStoreMgr.createTemplateOnPrimaryDataStore(template, dataStore);
+ templateOnPrimaryStoreObj.updateStatus(Status.CREATING);
+ try {
+ dataStore.installTemplate(templateOnPrimaryStoreObj);
+ templateOnPrimaryStoreObj.updateStatus(Status.CREATED);
+ } catch (Exception e) {
+ templateOnPrimaryStoreObj.updateStatus(Status.ABANDONED);
+ throw new CloudRuntimeException(e.toString());
+ }
+
+ templateOnPrimaryStoreObj.updateStatus(Status.DOWNLOAD_IN_PROGRESS);
+ try {
+ imageMotion.copyTemplate(templateOnPrimaryStoreObj);
+ templateOnPrimaryStoreObj.updateStatus(Status.DOWNLOADED);
+ } catch (Exception e) {
+ templateOnPrimaryStoreObj.updateStatus(Status.ABANDONED);
+ throw new CloudRuntimeException(e.toString());
+ }
+
+ return templateOnPrimaryStoreObj;
+ }
+
+ @Override
+ public VolumeInfo createVolumeFromTemplate(VolumeInfo volume, long dataStoreId, VolumeDiskType diskType, TemplateInfo template) {
+ PrimaryDataStore pd = dataStoreMgr.getPrimaryDataStore(dataStoreId);
+ TemplateOnPrimaryDataStoreInfo templateOnPrimaryStore = pd.getTemplate(template);
+ if (templateOnPrimaryStore == null) {
+ templateOnPrimaryStore = createBaseImage(pd, template);
+ }
+
+ VolumeObject vo = (VolumeObject) volume;
+ try {
+ vo.stateTransit(Volume.Event.CreateRequested);
+ } catch (Exception e) {
+ throw new CloudRuntimeException(e.toString());
+ }
+
+ try {
+ volume = pd.createVoluemFromBaseImage(volume, templateOnPrimaryStore);
+ vo.stateTransit(Volume.Event.OperationSucceeded);
+ } catch (Exception e) {
+ vo.stateTransit(Volume.Event.OperationFailed);
+ throw new CloudRuntimeException(e.toString());
+ }
+ return volume;
+ }
+
+ @Override
+ public TemplateOnPrimaryDataStoreInfo grantAccess(TemplateOnPrimaryDataStoreInfo template, EndPoint endPoint) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+}