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;
+    }
+}