add state machine for templateonprimarystorage, thus we don't need hold lock

This commit is contained in:
Edison Su 2012-12-04 19:01:58 -08:00
parent eee58d7804
commit 0836bb8ec9
15 changed files with 270 additions and 142 deletions

View File

@ -21,6 +21,7 @@ package org.apache.cloudstack.engine.subsystem.api.storage;
import java.util.List; 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 org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskType;
import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.Hypervisor.HypervisorType;
@ -34,4 +35,6 @@ public interface PrimaryDataStoreInfo {
public List<EndPoint> getEndPoints(); public List<EndPoint> getEndPoints();
public long getId(); public long getId();
public String getUuid(); public String getUuid();
public State getManagedState();
public String getName();
} }

View File

@ -137,14 +137,12 @@ public class PrimaryDataStoreEntityImpl implements StorageEntity {
@Override @Override
public State getState() { public State getState() {
// TODO Auto-generated method stub return this.dataStore.getManagedState();
return null;
} }
@Override @Override
public String getName() { public String getName() {
// TODO Auto-generated method stub return this.dataStore.getName();
return null;
} }
@Override @Override

View File

@ -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<TemplateOnPrimaryDataStoreStateMachine.State> {
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,
}
}

View File

@ -18,7 +18,12 @@
*/ */
package org.apache.cloudstack.storage.volume.db; 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<TemplatePrimaryDataStoreVO, Long> { import com.cloud.utils.db.GenericDao;
import com.cloud.utils.fsm.StateDao;
public interface TemplatePrimaryDataStoreDao extends GenericDao<TemplatePrimaryDataStoreVO, Long>, StateDao<TemplateOnPrimaryDataStoreStateMachine.State, TemplateOnPrimaryDataStoreStateMachine.Event, TemplatePrimaryDataStoreVO> {
public TemplatePrimaryDataStoreVO findByTemplateIdAndPoolId(long templateId, long poolId);
public TemplatePrimaryDataStoreVO findByTemplateIdAndPoolIdAndReady(long templateId, long poolId);
} }

View File

@ -18,11 +18,79 @@
*/ */
package org.apache.cloudstack.storage.volume.db; 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 org.springframework.stereotype.Component;
import com.cloud.utils.db.GenericDaoBase; 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 @Component
public class TemplatePrimaryDataStoreDaoImpl extends GenericDaoBase<TemplatePrimaryDataStoreVO, Long> implements TemplatePrimaryDataStoreDao { public class TemplatePrimaryDataStoreDaoImpl extends GenericDaoBase<TemplatePrimaryDataStoreVO, Long> implements TemplatePrimaryDataStoreDao {
private static final Logger s_logger = Logger.getLogger(TemplatePrimaryDataStoreDaoImpl.class);
protected final SearchBuilder<TemplatePrimaryDataStoreVO> 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<TemplatePrimaryDataStoreVO, TemplatePrimaryDataStoreVO> 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<TemplatePrimaryDataStoreVO, TemplatePrimaryDataStoreVO> 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<TemplatePrimaryDataStoreVO> 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;
}
} }

View File

@ -32,12 +32,13 @@ import javax.persistence.Temporal;
import javax.persistence.TemporalType; import javax.persistence.TemporalType;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreStateMachine;
import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.fsm.StateObject;
@Entity @Entity
@Table(name = "template_spool_ref") @Table(name = "template_spool_ref")
public class TemplatePrimaryDataStoreVO { public class TemplatePrimaryDataStoreVO implements StateObject<TemplateOnPrimaryDataStoreStateMachine.State> {
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
long id; long id;
@ -80,6 +81,25 @@ public class TemplatePrimaryDataStoreVO {
@Column(name = "marked_for_gc") @Column(name = "marked_for_gc")
boolean markedForGC; 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() { public String getInstallPath() {
return installPath; 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(); 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;
}
} }

View File

@ -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<HypervisorType> supportedHypervs;
protected List<VolumeDiskType> supportedDiskTypes;
protected long caapcity;
protected long avail;
protected boolean localStorage;
public PrimaryDataStoreInfoImpl(List<HypervisorType> hypers, List<VolumeDiskType> 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<EndPoint> getEndPoints() {
// TODO Auto-generated method stub
return null;
}
@Override
public long getId() {
// TODO Auto-generated method stub
return 0;
}
}

View File

@ -4,7 +4,6 @@ import java.util.Map;
import javax.inject.Inject; 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.DefaultPrimaryDataStore;
import org.apache.cloudstack.storage.datastore.PrimaryDataStore; import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreProviderVO; 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.apache.cloudstack.storage.datastore.lifecycle.PrimaryDataStoreLifeCycle;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.cloud.utils.component.ComponentInject;
@Component @Component
public class DefaultPrimaryDatastoreProviderImpl implements PrimaryDataStoreProvider { public class DefaultPrimaryDatastoreProviderImpl implements PrimaryDataStoreProvider {
private final String providerName = "default primary data store provider"; private final String providerName = "default primary data store provider";
protected PrimaryDataStoreDriver driver; protected PrimaryDataStoreDriver driver;
private PrimaryDataStoreProviderVO provider; private PrimaryDataStoreProviderVO provider;
protected final PrimaryDataStoreDao dataStoreDao; @Inject
protected PrimaryDataStoreDao dataStoreDao;
protected PrimaryDataStoreLifeCycle dataStoreLifeCycle; protected PrimaryDataStoreLifeCycle dataStoreLifeCycle;
@Inject public DefaultPrimaryDatastoreProviderImpl() {
public DefaultPrimaryDatastoreProviderImpl(PrimaryDataStoreDao dataStoreDao) {
this.driver = new DefaultPrimaryDataStoreDriverImpl(); this.driver = new DefaultPrimaryDataStoreDriverImpl();
this.dataStoreDao = dataStoreDao;
this.dataStoreLifeCycle = new DefaultPrimaryDataStoreLifeCycleImpl(this, dataStoreDao); this.dataStoreLifeCycle = new DefaultPrimaryDataStoreLifeCycleImpl(this, dataStoreDao);
} }
@ -44,12 +40,6 @@ public class DefaultPrimaryDatastoreProviderImpl implements PrimaryDataStoreProv
return pds; return pds;
} }
@Override
public PrimaryDataStoreInfo getDataStoreInfo(long dataStoreId) {
// TODO Auto-generated method stub
return null;
}
@Override @Override
public PrimaryDataStoreLifeCycle getDataStoreLifeCycle() { public PrimaryDataStoreLifeCycle getDataStoreLifeCycle() {
return dataStoreLifeCycle; return dataStoreLifeCycle;

View File

@ -10,7 +10,6 @@ import org.apache.cloudstack.storage.datastore.lifecycle.PrimaryDataStoreLifeCyc
public interface PrimaryDataStoreProvider { public interface PrimaryDataStoreProvider {
public PrimaryDataStore getDataStore(long dataStoreId); public PrimaryDataStore getDataStore(long dataStoreId);
public PrimaryDataStoreLifeCycle getDataStoreLifeCycle(); public PrimaryDataStoreLifeCycle getDataStoreLifeCycle();
public PrimaryDataStoreInfo getDataStoreInfo(long dataStoreId);
public long getId(); public long getId();
public String getName(); public String getName();
public boolean register(PrimaryDataStoreProviderVO provider, Map<String, Object> params); public boolean register(PrimaryDataStoreProviderVO provider, Map<String, Object> params);

View File

@ -20,23 +20,32 @@ package org.apache.cloudstack.storage.volume;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
import org.apache.cloudstack.storage.image.TemplateInfo; 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.TemplatePrimaryDataStoreDao;
import org.apache.cloudstack.storage.volume.db.TemplatePrimaryDataStoreVO; import org.apache.cloudstack.storage.volume.db.TemplatePrimaryDataStoreVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; 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 { public class TemplateOnPrimaryDataStoreObject implements TemplateOnPrimaryDataStoreInfo {
protected PrimaryDataStoreInfo dataStore; protected PrimaryDataStoreInfo dataStore;
protected TemplateInfo template; protected TemplateInfo template;
protected TemplatePrimaryDataStoreVO vo; protected TemplatePrimaryDataStoreVO vo;
TemplatePrimaryDataStoreDao templateStoreDao; protected TemplatePrimaryDataStoreDao templateStoreDao;
protected TemplatePrimaryDataStoreManager mgr;
protected StateMachine2<State, Event, TemplatePrimaryDataStoreVO> stateMachine;
public TemplateOnPrimaryDataStoreObject(PrimaryDataStoreInfo primaryDataStore, TemplateInfo template, TemplatePrimaryDataStoreVO vo, public TemplateOnPrimaryDataStoreObject(PrimaryDataStoreInfo primaryDataStore, TemplateInfo template, TemplatePrimaryDataStoreVO vo,
TemplatePrimaryDataStoreDao templateStoreDao) { TemplatePrimaryDataStoreDao templateStoreDao, TemplatePrimaryDataStoreManager mgr) {
this.dataStore = primaryDataStore; this.dataStore = primaryDataStore;
this.template = template; this.template = template;
this.vo = vo; this.vo = vo;
this.templateStoreDao = templateStoreDao; this.templateStoreDao = templateStoreDao;
this.mgr = mgr;
this.stateMachine = mgr.getStateMachine();
} }
@Override @Override
@ -64,4 +73,11 @@ public class TemplateOnPrimaryDataStoreObject implements TemplateOnPrimaryDataSt
templateStoreDao.update(vo.getId(), vo); 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());
}
}
} }

View File

@ -20,9 +20,16 @@ package org.apache.cloudstack.storage.volume;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
import org.apache.cloudstack.storage.image.TemplateInfo; 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 interface TemplatePrimaryDataStoreManager {
public TemplateOnPrimaryDataStoreInfo createTemplateOnPrimaryDataStore(TemplateInfo template, PrimaryDataStoreInfo dataStore); public TemplateOnPrimaryDataStoreInfo createTemplateOnPrimaryDataStore(TemplateInfo template, PrimaryDataStoreInfo dataStore);
public TemplateOnPrimaryDataStoreInfo findTemplateOnPrimaryDataStore(TemplateInfo template, PrimaryDataStoreInfo dataStore); public TemplateOnPrimaryDataStoreInfo findTemplateOnPrimaryDataStore(TemplateInfo template, PrimaryDataStoreInfo dataStore);
public StateMachine2<State, Event, TemplatePrimaryDataStoreVO> getStateMachine();
} }

View File

@ -22,6 +22,8 @@ import javax.inject.Inject;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
import org.apache.cloudstack.storage.image.TemplateInfo; 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.TemplatePrimaryDataStoreDao;
import org.apache.cloudstack.storage.volume.db.TemplatePrimaryDataStoreVO; import org.apache.cloudstack.storage.volume.db.TemplatePrimaryDataStoreVO;
import org.springframework.stereotype.Component; 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.SearchCriteria2;
import com.cloud.utils.db.SearchCriteriaService; import com.cloud.utils.db.SearchCriteriaService;
import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.SearchCriteria.Op;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.fsm.StateMachine2;
@Component @Component
public class TemplatePrimaryDataStoreManagerImpl implements TemplatePrimaryDataStoreManager { public class TemplatePrimaryDataStoreManagerImpl implements TemplatePrimaryDataStoreManager {
@Inject @Inject
TemplatePrimaryDataStoreDao templateStoreDao; TemplatePrimaryDataStoreDao templateStoreDao;
protected long waitingTime = 1800; //half an hour
protected long waitingReties = 10;
protected StateMachine2<State, Event, TemplatePrimaryDataStoreVO> stateMachines;
public TemplatePrimaryDataStoreManagerImpl() {
stateMachines = new StateMachine2<State, Event, TemplatePrimaryDataStoreVO>();
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 @Override
public TemplateOnPrimaryDataStoreObject createTemplateOnPrimaryDataStore(TemplateInfo template, PrimaryDataStoreInfo dataStore) { public TemplateOnPrimaryDataStoreObject createTemplateOnPrimaryDataStore(TemplateInfo template, PrimaryDataStoreInfo dataStore) {
TemplatePrimaryDataStoreVO templateStoreVO = new TemplatePrimaryDataStoreVO(dataStore.getId(), template.getId()); TemplatePrimaryDataStoreVO templateStoreVO = new TemplatePrimaryDataStoreVO(dataStore.getId(), template.getId());
try {
templateStoreVO = templateStoreDao.persist(templateStoreVO); templateStoreVO = templateStoreDao.persist(templateStoreVO);
TemplateOnPrimaryDataStoreObject templateStoreObject = new TemplateOnPrimaryDataStoreObject(dataStore, template, templateStoreVO, templateStoreDao); } 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; return templateStoreObject;
} }
@ -56,7 +104,13 @@ public class TemplatePrimaryDataStoreManagerImpl implements TemplatePrimaryDataS
return null; return null;
} }
TemplateOnPrimaryDataStoreObject templateStoreObject = new TemplateOnPrimaryDataStoreObject(dataStore, template, templateStoreVO, templateStoreDao); TemplateOnPrimaryDataStoreObject templateStoreObject = new TemplateOnPrimaryDataStoreObject(dataStore, template, templateStoreVO, templateStoreDao, this);
return templateStoreObject; return templateStoreObject;
} }
@Override
public StateMachine2<State, Event, TemplatePrimaryDataStoreVO> getStateMachine() {
return stateMachines;
}
} }

View File

@ -134,12 +134,15 @@ public class VolumeServiceImpl implements VolumeService {
protected TemplateOnPrimaryDataStoreObject createBaseImage(PrimaryDataStore dataStore, TemplateInfo template) { protected TemplateOnPrimaryDataStoreObject createBaseImage(PrimaryDataStore dataStore, TemplateInfo template) {
TemplateOnPrimaryDataStoreObject templateOnPrimaryStoreObj = (TemplateOnPrimaryDataStoreObject) templatePrimaryStoreMgr.createTemplateOnPrimaryDataStore(template, dataStore); TemplateOnPrimaryDataStoreObject templateOnPrimaryStoreObj = (TemplateOnPrimaryDataStoreObject) templatePrimaryStoreMgr.createTemplateOnPrimaryDataStore(template, dataStore);
templateOnPrimaryStoreObj.stateTransit(TemplateOnPrimaryDataStoreStateMachine.Event.CreateRequested);
templateOnPrimaryStoreObj.updateStatus(Status.CREATING); templateOnPrimaryStoreObj.updateStatus(Status.CREATING);
try { try {
dataStore.installTemplate(templateOnPrimaryStoreObj); dataStore.installTemplate(templateOnPrimaryStoreObj);
templateOnPrimaryStoreObj.updateStatus(Status.CREATED); templateOnPrimaryStoreObj.updateStatus(Status.CREATED);
} catch (Exception e) { } catch (Exception e) {
templateOnPrimaryStoreObj.updateStatus(Status.ABANDONED); templateOnPrimaryStoreObj.updateStatus(Status.ABANDONED);
templateOnPrimaryStoreObj.stateTransit(TemplateOnPrimaryDataStoreStateMachine.Event.OperationFailed);
throw new CloudRuntimeException(e.toString()); throw new CloudRuntimeException(e.toString());
} }
@ -147,8 +150,10 @@ public class VolumeServiceImpl implements VolumeService {
try { try {
imageMotion.copyTemplate(templateOnPrimaryStoreObj); imageMotion.copyTemplate(templateOnPrimaryStoreObj);
templateOnPrimaryStoreObj.updateStatus(Status.DOWNLOADED); templateOnPrimaryStoreObj.updateStatus(Status.DOWNLOADED);
templateOnPrimaryStoreObj.stateTransit(TemplateOnPrimaryDataStoreStateMachine.Event.OperationSuccessed);
} catch (Exception e) { } catch (Exception e) {
templateOnPrimaryStoreObj.updateStatus(Status.ABANDONED); templateOnPrimaryStoreObj.updateStatus(Status.ABANDONED);
templateOnPrimaryStoreObj.stateTransit(TemplateOnPrimaryDataStoreStateMachine.Event.OperationFailed);
throw new CloudRuntimeException(e.toString()); throw new CloudRuntimeException(e.toString());
} }

View File

@ -1,34 +1,22 @@
<!-- <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor
Licensed to the Apache Software Foundation (ASF) under one license agreements. See the NOTICE file distributed with this work for additional
or more contributor license agreements. See the NOTICE file information regarding copyright ownership. The ASF licenses this file to
distributed with this work for additional information you under the Apache License, Version 2.0 (the "License"); you may not use
regarding copyright ownership. The ASF licenses this file this file except in compliance with the License. You may obtain a copy of
to you under the Apache License, Version 2.0 (the the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required
"License"); you may not use this file except in compliance by applicable law or agreed to in writing, software distributed under the
with the License. You may obtain a copy of the License at 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
http://www.apache.org/licenses/LICENSE-2.0 language governing permissions and limitations under the License. -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
Unless required by applicable law or agreed to in writing, xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.apache.cloudstack</groupId> <groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-framework-ipc</artifactId> <artifactId>cloud-framework-ipc</artifactId>
<version>4.1.0-SNAPSHOT</version> <version>4.1.0-SNAPSHOT</version>
<dependencies> <dependencies>
<!-- <!-- <dependency> <groupId>org.hornetq</groupId> <artifactId>hornetq-core-client</artifactId>
<dependency> <version>snap-r9548</version> </dependency> -->
<groupId>org.hornetq</groupId>
<artifactId>hornetq-core-client</artifactId>
<version>snap-r9548</version>
</dependency>
-->
<dependency> <dependency>
<groupId>org.apache.cloudstack</groupId> <groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-core</artifactId> <artifactId>cloud-core</artifactId>
@ -42,4 +30,9 @@
</dependency> </dependency>
</dependencies> </dependencies>
<build>
<defaultGoal>install</defaultGoal>
<sourceDirectory>src</sourceDirectory>
</build>
</project> </project>

View File

@ -9,8 +9,6 @@ import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreVO;
import org.apache.cloudstack.storage.datastore.driver.SolidfirePrimaryDataStoreDriver; import org.apache.cloudstack.storage.datastore.driver.SolidfirePrimaryDataStoreDriver;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.cloud.utils.component.ComponentInject;
@Component @Component
public class SolidfirePrimaryDataStoreProvider extends public class SolidfirePrimaryDataStoreProvider extends
DefaultPrimaryDatastoreProviderImpl { DefaultPrimaryDatastoreProviderImpl {
@ -36,8 +34,7 @@ public class SolidfirePrimaryDataStoreProvider extends
return null; return null;
} }
PrimaryDataStore pds = new DefaultPrimaryDataStore(driver, dsv, null); PrimaryDataStore pds = DefaultPrimaryDataStore.createDataStore(driver, dsv, null);
pds = ComponentInject.inject(pds);
return pds; return pds;
} }
} }