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