diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java index dbdaaed0db8..7c110bfe122 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java @@ -21,6 +21,7 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import java.util.List; +import org.apache.cloudstack.engine.datacenter.entity.api.DataCenterResourceEntity.State; import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskType; import com.cloud.hypervisor.Hypervisor.HypervisorType; @@ -34,4 +35,6 @@ public interface PrimaryDataStoreInfo { public List getEndPoints(); public long getId(); public String getUuid(); + public State getManagedState(); + public String getName(); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreEntityImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreEntityImpl.java index 79a173c5c7f..eca4a69231d 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreEntityImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreEntityImpl.java @@ -137,14 +137,12 @@ public class PrimaryDataStoreEntityImpl implements StorageEntity { @Override public State getState() { - // TODO Auto-generated method stub - return null; + return this.dataStore.getManagedState(); } @Override public String getName() { - // TODO Auto-generated method stub - return null; + return this.dataStore.getName(); } @Override diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/TemplateOnPrimaryDataStoreStateMachine.java b/engine/storage/src/org/apache/cloudstack/storage/volume/TemplateOnPrimaryDataStoreStateMachine.java new file mode 100644 index 00000000000..7f0cd9be5ee --- /dev/null +++ b/engine/storage/src/org/apache/cloudstack/storage/volume/TemplateOnPrimaryDataStoreStateMachine.java @@ -0,0 +1,48 @@ +/* + * 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 com.cloud.utils.fsm.StateObject; + +public interface TemplateOnPrimaryDataStoreStateMachine extends StateObject { + enum State { + Allocated("The initial state"), + Creating("The template is being downloading to data store"), + Ready("Template downloading is complished"), + Destroying("Template is destroying"), + Destroyed("Template is destroyed"), + Failed("Failed to download template"); + String _description; + + private State(String description) { + _description = description; + } + + public String getDescription() { + return _description; + } + } + + enum Event { + CreateRequested, + DestroyRequested, + OperationSuccessed, + OperationFailed, + } +} diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/db/TemplatePrimaryDataStoreDao.java b/engine/storage/src/org/apache/cloudstack/storage/volume/db/TemplatePrimaryDataStoreDao.java index 77659df297c..3f8f71d35bb 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/volume/db/TemplatePrimaryDataStoreDao.java +++ b/engine/storage/src/org/apache/cloudstack/storage/volume/db/TemplatePrimaryDataStoreDao.java @@ -18,7 +18,12 @@ */ package org.apache.cloudstack.storage.volume.db; -import com.cloud.utils.db.GenericDao; +import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreStateMachine; -public interface TemplatePrimaryDataStoreDao extends GenericDao { +import com.cloud.utils.db.GenericDao; +import com.cloud.utils.fsm.StateDao; + +public interface TemplatePrimaryDataStoreDao extends GenericDao, StateDao { + public TemplatePrimaryDataStoreVO findByTemplateIdAndPoolId(long templateId, long poolId); + public TemplatePrimaryDataStoreVO findByTemplateIdAndPoolIdAndReady(long templateId, long poolId); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/db/TemplatePrimaryDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/volume/db/TemplatePrimaryDataStoreDaoImpl.java index f4698ff8075..00732e13df8 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/volume/db/TemplatePrimaryDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/volume/db/TemplatePrimaryDataStoreDaoImpl.java @@ -18,11 +18,79 @@ */ package org.apache.cloudstack.storage.volume.db; +import java.util.Date; + +import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreStateMachine; +import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreStateMachine.Event; +import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreStateMachine.State; +import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchCriteria.Op; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria2; +import com.cloud.utils.db.SearchCriteriaService; +import com.cloud.utils.db.UpdateBuilder; @Component public class TemplatePrimaryDataStoreDaoImpl extends GenericDaoBase implements TemplatePrimaryDataStoreDao { + private static final Logger s_logger = Logger.getLogger(TemplatePrimaryDataStoreDaoImpl.class); + protected final SearchBuilder updateSearchBuilder; + public TemplatePrimaryDataStoreDaoImpl() { + updateSearchBuilder = createSearchBuilder(); + updateSearchBuilder.and("id", updateSearchBuilder.entity().getId(), Op.EQ); + updateSearchBuilder.and("state", updateSearchBuilder.entity().getState(), Op.EQ); + updateSearchBuilder.and("updatedCount", updateSearchBuilder.entity().getUpdatedCount(), Op.EQ); + updateSearchBuilder.done(); + } + @Override + public TemplatePrimaryDataStoreVO findByTemplateIdAndPoolId(long templateId, long poolId) { + SearchCriteriaService sc = SearchCriteria2.create(TemplatePrimaryDataStoreVO.class); + sc.addAnd(sc.getEntity().getTemplateId(), Op.EQ, templateId); + sc.addAnd(sc.getEntity().getPoolId(), Op.EQ, poolId); + return sc.find(); + } + @Override + public TemplatePrimaryDataStoreVO findByTemplateIdAndPoolIdAndReady(long templateId, long poolId) { + SearchCriteriaService sc = SearchCriteria2.create(TemplatePrimaryDataStoreVO.class); + sc.addAnd(sc.getEntity().getTemplateId(), Op.EQ, templateId); + sc.addAnd(sc.getEntity().getPoolId(), Op.EQ, poolId); + sc.addAnd(sc.getEntity().getState(), Op.EQ, TemplateOnPrimaryDataStoreStateMachine.State.Ready); + return sc.find(); + } + + @Override + public boolean updateState(State currentState, Event event, State nextState, TemplatePrimaryDataStoreVO vo, Object data) { + Long oldUpdated = vo.getUpdatedCount(); + Date oldUpdatedTime = vo.getLastUpdated(); + + SearchCriteria sc = updateSearchBuilder.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, "lastUpdated", new Date()); + + int rows = update((TemplatePrimaryDataStoreVO)vo, sc); + if (rows == 0 && s_logger.isDebugEnabled()) { + TemplatePrimaryDataStoreVO template = findByIdIncludingRemoved(vo.getId()); + if (template != null) { + StringBuilder str = new StringBuilder("Unable to update ").append(vo.toString()); + str.append(": DB Data={id=").append(template.getId()).append("; state=").append(template.getState()).append("; updatecount=").append(template.getUpdatedCount()).append(";updatedTime=").append(template.getLastUpdated()); + 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.getLastUpdated()); + 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 template: id=" + vo.getId() + ", as there is no such template exists in the database anymore"); + } + } + return rows > 0; + } + } diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/db/TemplatePrimaryDataStoreVO.java b/engine/storage/src/org/apache/cloudstack/storage/volume/db/TemplatePrimaryDataStoreVO.java index 70e705f1ace..522101f09fb 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/volume/db/TemplatePrimaryDataStoreVO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/volume/db/TemplatePrimaryDataStoreVO.java @@ -32,12 +32,13 @@ import javax.persistence.Temporal; import javax.persistence.TemporalType; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; - +import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreStateMachine; import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.fsm.StateObject; @Entity @Table(name = "template_spool_ref") -public class TemplatePrimaryDataStoreVO { +public class TemplatePrimaryDataStoreVO implements StateObject { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) long id; @@ -79,6 +80,25 @@ public class TemplatePrimaryDataStoreVO { @Column(name = "marked_for_gc") boolean markedForGC; + + @Column(name = "state") + @Enumerated(EnumType.STRING) + TemplateOnPrimaryDataStoreStateMachine.State state; + + @Column(name="update_count", updatable = true, nullable=false) + protected long updatedCount; + + public long getUpdatedCount() { + return this.updatedCount; + } + + public void incrUpdatedCount() { + this.updatedCount++; + } + + public void decrUpdatedCount() { + this.updatedCount--; + } public String getInstallPath() { return installPath; @@ -224,4 +244,9 @@ public class TemplatePrimaryDataStoreVO { return new StringBuilder("TmplPool[").append(id).append("-").append(templateId).append("-").append("poolId").append("-").append(installPath).append("]").toString(); } + @Override + public TemplateOnPrimaryDataStoreStateMachine.State getState() { + return this.state; + } + } \ No newline at end of file diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreInfoImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreInfoImpl.java deleted file mode 100644 index c5ed961fbf1..00000000000 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreInfoImpl.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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.datastore; - -import java.util.List; - -import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; -import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; -import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskType; - -import com.cloud.hypervisor.Hypervisor.HypervisorType; - -public class PrimaryDataStoreInfoImpl implements PrimaryDataStoreInfo { - protected List supportedHypervs; - protected List supportedDiskTypes; - protected long caapcity; - protected long avail; - protected boolean localStorage; - - public PrimaryDataStoreInfoImpl(List hypers, List diskTypes, long capacity, long avail, boolean localStorage) { - this.avail = avail; - this.caapcity = capacity; - this.localStorage = localStorage; - this.supportedDiskTypes = diskTypes; - this.supportedHypervs = hypers; - } - - @Override - public boolean isHypervisorSupported(HypervisorType hypervisor) { - return this.supportedHypervs.contains(hypervisor) ? true : false; - } - - @Override - public boolean isLocalStorageSupported() { - return this.localStorage; - } - - @Override - public boolean isVolumeDiskTypeSupported(VolumeDiskType diskType) { - return this.supportedDiskTypes.contains(diskType) ? true : false; - } - - @Override - public long getCapacity() { - return this.caapcity; - } - - @Override - public long getAvailableCapacity() { - return this.avail; - } - - @Override - public List getEndPoints() { - // TODO Auto-generated method stub - return null; - } - - @Override - public long getId() { - // TODO Auto-generated method stub - return 0; - } -} diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultPrimaryDatastoreProviderImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultPrimaryDatastoreProviderImpl.java index 7ea8a696a4e..872673e03ef 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultPrimaryDatastoreProviderImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultPrimaryDatastoreProviderImpl.java @@ -4,7 +4,6 @@ import java.util.Map; import javax.inject.Inject; -import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; import org.apache.cloudstack.storage.datastore.DefaultPrimaryDataStore; import org.apache.cloudstack.storage.datastore.PrimaryDataStore; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreProviderVO; @@ -16,20 +15,17 @@ import org.apache.cloudstack.storage.datastore.lifecycle.DefaultPrimaryDataStore import org.apache.cloudstack.storage.datastore.lifecycle.PrimaryDataStoreLifeCycle; import org.springframework.stereotype.Component; -import com.cloud.utils.component.ComponentInject; - @Component public class DefaultPrimaryDatastoreProviderImpl implements PrimaryDataStoreProvider { private final String providerName = "default primary data store provider"; protected PrimaryDataStoreDriver driver; private PrimaryDataStoreProviderVO provider; - protected final PrimaryDataStoreDao dataStoreDao; + @Inject + protected PrimaryDataStoreDao dataStoreDao; protected PrimaryDataStoreLifeCycle dataStoreLifeCycle; - @Inject - public DefaultPrimaryDatastoreProviderImpl(PrimaryDataStoreDao dataStoreDao) { + public DefaultPrimaryDatastoreProviderImpl() { this.driver = new DefaultPrimaryDataStoreDriverImpl(); - this.dataStoreDao = dataStoreDao; this.dataStoreLifeCycle = new DefaultPrimaryDataStoreLifeCycleImpl(this, dataStoreDao); } @@ -44,12 +40,6 @@ public class DefaultPrimaryDatastoreProviderImpl implements PrimaryDataStoreProv return pds; } - @Override - public PrimaryDataStoreInfo getDataStoreInfo(long dataStoreId) { - // TODO Auto-generated method stub - return null; - } - @Override public PrimaryDataStoreLifeCycle getDataStoreLifeCycle() { return dataStoreLifeCycle; diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/PrimaryDataStoreProvider.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/PrimaryDataStoreProvider.java index b4a82a8fc9a..c87542623a1 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/PrimaryDataStoreProvider.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/PrimaryDataStoreProvider.java @@ -10,7 +10,6 @@ import org.apache.cloudstack.storage.datastore.lifecycle.PrimaryDataStoreLifeCyc public interface PrimaryDataStoreProvider { public PrimaryDataStore getDataStore(long dataStoreId); public PrimaryDataStoreLifeCycle getDataStoreLifeCycle(); - public PrimaryDataStoreInfo getDataStoreInfo(long dataStoreId); public long getId(); public String getName(); public boolean register(PrimaryDataStoreProviderVO provider, Map params); diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateOnPrimaryDataStoreObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateOnPrimaryDataStoreObject.java index b3326e11965..42d8e4ab03c 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateOnPrimaryDataStoreObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateOnPrimaryDataStoreObject.java @@ -20,23 +20,32 @@ package org.apache.cloudstack.storage.volume; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; import org.apache.cloudstack.storage.image.TemplateInfo; +import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreStateMachine.Event; +import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreStateMachine.State; import org.apache.cloudstack.storage.volume.db.TemplatePrimaryDataStoreDao; import org.apache.cloudstack.storage.volume.db.TemplatePrimaryDataStoreVO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.fsm.NoTransitionException; +import com.cloud.utils.fsm.StateMachine2; public class TemplateOnPrimaryDataStoreObject implements TemplateOnPrimaryDataStoreInfo { protected PrimaryDataStoreInfo dataStore; protected TemplateInfo template; protected TemplatePrimaryDataStoreVO vo; - TemplatePrimaryDataStoreDao templateStoreDao; + protected TemplatePrimaryDataStoreDao templateStoreDao; + protected TemplatePrimaryDataStoreManager mgr; + protected StateMachine2 stateMachine; public TemplateOnPrimaryDataStoreObject(PrimaryDataStoreInfo primaryDataStore, TemplateInfo template, TemplatePrimaryDataStoreVO vo, - TemplatePrimaryDataStoreDao templateStoreDao) { + TemplatePrimaryDataStoreDao templateStoreDao, TemplatePrimaryDataStoreManager mgr) { this.dataStore = primaryDataStore; this.template = template; this.vo = vo; this.templateStoreDao = templateStoreDao; + this.mgr = mgr; + this.stateMachine = mgr.getStateMachine(); } @Override @@ -63,5 +72,12 @@ public class TemplateOnPrimaryDataStoreObject implements TemplateOnPrimaryDataSt vo.setDownloadState(status); templateStoreDao.update(vo.getId(), vo); } - + + public void stateTransit(TemplateOnPrimaryDataStoreStateMachine.Event event) { + try { + this.stateMachine.transitTo(vo, event, null, templateStoreDao); + } catch (NoTransitionException e) { + throw new CloudRuntimeException(e.toString()); + } + } } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplatePrimaryDataStoreManager.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplatePrimaryDataStoreManager.java index eb0b6706fbf..92703912c1f 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplatePrimaryDataStoreManager.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplatePrimaryDataStoreManager.java @@ -20,9 +20,16 @@ package org.apache.cloudstack.storage.volume; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; import org.apache.cloudstack.storage.image.TemplateInfo; +import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreStateMachine.Event; +import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreStateMachine.State; +import org.apache.cloudstack.storage.volume.db.TemplatePrimaryDataStoreVO; + +import com.cloud.utils.fsm.StateMachine2; public interface TemplatePrimaryDataStoreManager { public TemplateOnPrimaryDataStoreInfo createTemplateOnPrimaryDataStore(TemplateInfo template, PrimaryDataStoreInfo dataStore); public TemplateOnPrimaryDataStoreInfo findTemplateOnPrimaryDataStore(TemplateInfo template, PrimaryDataStoreInfo dataStore); + + public StateMachine2 getStateMachine(); } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplatePrimaryDataStoreManagerImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplatePrimaryDataStoreManagerImpl.java index 19704be79af..5b2d1cb3bda 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplatePrimaryDataStoreManagerImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplatePrimaryDataStoreManagerImpl.java @@ -22,6 +22,8 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; import org.apache.cloudstack.storage.image.TemplateInfo; +import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreStateMachine.Event; +import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreStateMachine.State; import org.apache.cloudstack.storage.volume.db.TemplatePrimaryDataStoreDao; import org.apache.cloudstack.storage.volume.db.TemplatePrimaryDataStoreVO; import org.springframework.stereotype.Component; @@ -30,18 +32,64 @@ import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.utils.db.SearchCriteria2; import com.cloud.utils.db.SearchCriteriaService; import com.cloud.utils.db.SearchCriteria.Op; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.fsm.StateMachine2; @Component public class TemplatePrimaryDataStoreManagerImpl implements TemplatePrimaryDataStoreManager { @Inject TemplatePrimaryDataStoreDao templateStoreDao; - + protected long waitingTime = 1800; //half an hour + protected long waitingReties = 10; + protected StateMachine2 stateMachines; + public TemplatePrimaryDataStoreManagerImpl() { + stateMachines = new StateMachine2(); + stateMachines.addTransition(TemplateOnPrimaryDataStoreStateMachine.State.Allocated, Event.CreateRequested, TemplateOnPrimaryDataStoreStateMachine.State.Creating); + stateMachines.addTransition(TemplateOnPrimaryDataStoreStateMachine.State.Creating, Event.OperationSuccessed, TemplateOnPrimaryDataStoreStateMachine.State.Ready); + stateMachines.addTransition(TemplateOnPrimaryDataStoreStateMachine.State.Creating, Event.OperationFailed, TemplateOnPrimaryDataStoreStateMachine.State.Failed); + stateMachines.addTransition(TemplateOnPrimaryDataStoreStateMachine.State.Failed, Event.CreateRequested, TemplateOnPrimaryDataStoreStateMachine.State.Creating); + stateMachines.addTransition(TemplateOnPrimaryDataStoreStateMachine.State.Ready, Event.DestroyRequested, TemplateOnPrimaryDataStoreStateMachine.State.Destroying); + stateMachines.addTransition(TemplateOnPrimaryDataStoreStateMachine.State.Destroying, Event.OperationSuccessed, TemplateOnPrimaryDataStoreStateMachine.State.Destroyed); + stateMachines.addTransition(TemplateOnPrimaryDataStoreStateMachine.State.Destroying, Event.OperationFailed, TemplateOnPrimaryDataStoreStateMachine.State.Destroying); + stateMachines.addTransition(TemplateOnPrimaryDataStoreStateMachine.State.Destroying, Event.DestroyRequested, TemplateOnPrimaryDataStoreStateMachine.State.Destroying); + } + + private TemplatePrimaryDataStoreVO waitingForTemplateDownload(TemplateInfo template, PrimaryDataStoreInfo dataStore) { + //the naive version, polling. + long retries = waitingReties; + TemplatePrimaryDataStoreVO templateStoreVO = null; + do { + try { + Thread.sleep(waitingTime); + } catch (InterruptedException e) { + + } + + templateStoreVO = templateStoreDao.findByTemplateIdAndPoolIdAndReady(template.getId(), dataStore.getId()); + if (templateStoreVO != null) { + break; + } + retries--; + } while (retries > 0); + + return templateStoreVO; + } @Override public TemplateOnPrimaryDataStoreObject createTemplateOnPrimaryDataStore(TemplateInfo template, PrimaryDataStoreInfo dataStore) { TemplatePrimaryDataStoreVO templateStoreVO = new TemplatePrimaryDataStoreVO(dataStore.getId(), template.getId()); - templateStoreVO = templateStoreDao.persist(templateStoreVO); - TemplateOnPrimaryDataStoreObject templateStoreObject = new TemplateOnPrimaryDataStoreObject(dataStore, template, templateStoreVO, templateStoreDao); + try { + templateStoreVO = templateStoreDao.persist(templateStoreVO); + } catch (Throwable th) { + templateStoreVO = templateStoreDao.findByTemplateIdAndPoolId(template.getId(), dataStore.getId()); + if (templateStoreVO != null) { + templateStoreVO = waitingForTemplateDownload(template, dataStore); + } else { + throw new CloudRuntimeException("Failed create db entry: " + th.toString()); + } + } + + TemplateOnPrimaryDataStoreObject templateStoreObject = new TemplateOnPrimaryDataStoreObject(dataStore, template, templateStoreVO, templateStoreDao, this); return templateStoreObject; } @@ -56,7 +104,13 @@ public class TemplatePrimaryDataStoreManagerImpl implements TemplatePrimaryDataS return null; } - TemplateOnPrimaryDataStoreObject templateStoreObject = new TemplateOnPrimaryDataStoreObject(dataStore, template, templateStoreVO, templateStoreDao); + TemplateOnPrimaryDataStoreObject templateStoreObject = new TemplateOnPrimaryDataStoreObject(dataStore, template, templateStoreVO, templateStoreDao, this); return templateStoreObject; } + + @Override + public StateMachine2 getStateMachine() { + return stateMachines; + } + } 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 index 25d05b2a79e..13ead8eefdb 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -134,12 +134,15 @@ public class VolumeServiceImpl implements VolumeService { protected TemplateOnPrimaryDataStoreObject createBaseImage(PrimaryDataStore dataStore, TemplateInfo template) { TemplateOnPrimaryDataStoreObject templateOnPrimaryStoreObj = (TemplateOnPrimaryDataStoreObject) templatePrimaryStoreMgr.createTemplateOnPrimaryDataStore(template, dataStore); + templateOnPrimaryStoreObj.stateTransit(TemplateOnPrimaryDataStoreStateMachine.Event.CreateRequested); templateOnPrimaryStoreObj.updateStatus(Status.CREATING); try { dataStore.installTemplate(templateOnPrimaryStoreObj); templateOnPrimaryStoreObj.updateStatus(Status.CREATED); + } catch (Exception e) { templateOnPrimaryStoreObj.updateStatus(Status.ABANDONED); + templateOnPrimaryStoreObj.stateTransit(TemplateOnPrimaryDataStoreStateMachine.Event.OperationFailed); throw new CloudRuntimeException(e.toString()); } @@ -147,8 +150,10 @@ public class VolumeServiceImpl implements VolumeService { try { imageMotion.copyTemplate(templateOnPrimaryStoreObj); templateOnPrimaryStoreObj.updateStatus(Status.DOWNLOADED); + templateOnPrimaryStoreObj.stateTransit(TemplateOnPrimaryDataStoreStateMachine.Event.OperationSuccessed); } catch (Exception e) { templateOnPrimaryStoreObj.updateStatus(Status.ABANDONED); + templateOnPrimaryStoreObj.stateTransit(TemplateOnPrimaryDataStoreStateMachine.Event.OperationFailed); throw new CloudRuntimeException(e.toString()); } diff --git a/framework/ipc/pom.xml b/framework/ipc/pom.xml index 0d69eab6824..7caf3601747 100644 --- a/framework/ipc/pom.xml +++ b/framework/ipc/pom.xml @@ -1,45 +1,38 @@ - - + + 4.0.0 org.apache.cloudstack cloud-framework-ipc 4.1.0-SNAPSHOT - - + + org.apache.cloudstack cloud-core 4.1.0-SNAPSHOT - + org.apache.cloudstack cloud-utils 4.1.0-SNAPSHOT - + + + + install + src + diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidfirePrimaryDataStoreProvider.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidfirePrimaryDataStoreProvider.java index 883346c2c9e..a66fac20c48 100644 --- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidfirePrimaryDataStoreProvider.java +++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidfirePrimaryDataStoreProvider.java @@ -9,8 +9,6 @@ import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreVO; import org.apache.cloudstack.storage.datastore.driver.SolidfirePrimaryDataStoreDriver; import org.springframework.stereotype.Component; -import com.cloud.utils.component.ComponentInject; - @Component public class SolidfirePrimaryDataStoreProvider extends DefaultPrimaryDatastoreProviderImpl { @@ -36,8 +34,7 @@ public class SolidfirePrimaryDataStoreProvider extends return null; } - PrimaryDataStore pds = new DefaultPrimaryDataStore(driver, dsv, null); - pds = ComponentInject.inject(pds); + PrimaryDataStore pds = DefaultPrimaryDataStore.createDataStore(driver, dsv, null); return pds; } }