mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
add state machine for templateonprimarystorage, thus we don't need hold lock
This commit is contained in:
parent
eee58d7804
commit
0836bb8ec9
@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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,
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -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;
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user