You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ed...@apache.org on 2012/12/05 04:02:24 UTC
git commit: add state machine for templateonprimarystorage,
thus we don't need hold lock
Updated Branches:
refs/heads/javelin eee58d780 -> 0836bb8ec
add state machine for templateonprimarystorage, thus we don't need hold lock
Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/0836bb8e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/0836bb8e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/0836bb8e
Branch: refs/heads/javelin
Commit: 0836bb8ec9f53e6c35021489f65df5b5d554f21d
Parents: eee58d7
Author: Edison Su <su...@gmail.com>
Authored: Tue Dec 4 19:01:58 2012 -0800
Committer: Edison Su <su...@gmail.com>
Committed: Tue Dec 4 19:02:14 2012 -0800
----------------------------------------------------------------------
.../api/storage/PrimaryDataStoreInfo.java | 3 +
.../datastore/PrimaryDataStoreEntityImpl.java | 6 +-
.../TemplateOnPrimaryDataStoreStateMachine.java | 48 +++++++++
.../volume/db/TemplatePrimaryDataStoreDao.java | 7 +-
.../volume/db/TemplatePrimaryDataStoreDaoImpl.java | 68 ++++++++++++
.../volume/db/TemplatePrimaryDataStoreVO.java | 29 +++++-
.../datastore/PrimaryDataStoreInfoImpl.java | 80 ---------------
.../DefaultPrimaryDatastoreProviderImpl.java | 16 +---
.../provider/PrimaryDataStoreProvider.java | 1 -
.../volume/TemplateOnPrimaryDataStoreObject.java | 22 ++++-
.../volume/TemplatePrimaryDataStoreManager.java | 7 ++
.../TemplatePrimaryDataStoreManagerImpl.java | 62 +++++++++++-
.../storage/volume/VolumeServiceImpl.java | 5 +
framework/ipc/pom.xml | 51 ++++-----
.../SolidfirePrimaryDataStoreProvider.java | 5 +-
15 files changed, 269 insertions(+), 141 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/0836bb8e/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java
----------------------------------------------------------------------
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 dbdaaed..7c110bf 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<EndPoint> getEndPoints();
public long getId();
public String getUuid();
+ public State getManagedState();
+ public String getName();
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/0836bb8e/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreEntityImpl.java
----------------------------------------------------------------------
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 79a173c..eca4a69 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
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/0836bb8e/engine/storage/src/org/apache/cloudstack/storage/volume/TemplateOnPrimaryDataStoreStateMachine.java
----------------------------------------------------------------------
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 0000000..7f0cd9b
--- /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<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,
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/0836bb8e/engine/storage/src/org/apache/cloudstack/storage/volume/db/TemplatePrimaryDataStoreDao.java
----------------------------------------------------------------------
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 77659df..3f8f71d 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 org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreStateMachine;
+
import com.cloud.utils.db.GenericDao;
+import com.cloud.utils.fsm.StateDao;
-public interface TemplatePrimaryDataStoreDao extends GenericDao<TemplatePrimaryDataStoreVO, Long> {
+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);
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/0836bb8e/engine/storage/src/org/apache/cloudstack/storage/volume/db/TemplatePrimaryDataStoreDaoImpl.java
----------------------------------------------------------------------
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 f4698ff..00732e1 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<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;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/0836bb8e/engine/storage/src/org/apache/cloudstack/storage/volume/db/TemplatePrimaryDataStoreVO.java
----------------------------------------------------------------------
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 70e705f..522101f 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<TemplateOnPrimaryDataStoreStateMachine.State> {
@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
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/0836bb8e/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreInfoImpl.java
----------------------------------------------------------------------
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 c5ed961..0000000
--- 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<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;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/0836bb8e/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultPrimaryDatastoreProviderImpl.java
----------------------------------------------------------------------
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 7ea8a69..872673e 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);
}
@@ -45,12 +41,6 @@ public class DefaultPrimaryDatastoreProviderImpl implements PrimaryDataStoreProv
}
@Override
- public PrimaryDataStoreInfo getDataStoreInfo(long dataStoreId) {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
public PrimaryDataStoreLifeCycle getDataStoreLifeCycle() {
return dataStoreLifeCycle;
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/0836bb8e/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/PrimaryDataStoreProvider.java
----------------------------------------------------------------------
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 b4a82a8..c875426 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<String, Object> params);
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/0836bb8e/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateOnPrimaryDataStoreObject.java
----------------------------------------------------------------------
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 b3326e1..42d8e4a 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<State, Event, TemplatePrimaryDataStoreVO> 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());
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/0836bb8e/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplatePrimaryDataStoreManager.java
----------------------------------------------------------------------
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 eb0b670..9270391 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<State, Event, TemplatePrimaryDataStoreVO> getStateMachine();
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/0836bb8e/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplatePrimaryDataStoreManagerImpl.java
----------------------------------------------------------------------
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 19704be..5b2d1cb 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<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
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<State, Event, TemplatePrimaryDataStoreVO> getStateMachine() {
+ return stateMachines;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/0836bb8e/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
index 25d05b2..13ead8e 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());
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/0836bb8e/framework/ipc/pom.xml
----------------------------------------------------------------------
diff --git a/framework/ipc/pom.xml b/framework/ipc/pom.xml
index 0d69eab..7caf360 100644
--- a/framework/ipc/pom.xml
+++ b/framework/ipc/pom.xml
@@ -1,45 +1,38 @@
-<!--
- 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.
--->
-<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">
+<!-- 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. -->
+<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>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-framework-ipc</artifactId>
<version>4.1.0-SNAPSHOT</version>
<dependencies>
-<!--
- <dependency>
- <groupId>org.hornetq</groupId>
- <artifactId>hornetq-core-client</artifactId>
- <version>snap-r9548</version>
- </dependency>
- -->
- <dependency>
+ <!-- <dependency> <groupId>org.hornetq</groupId> <artifactId>hornetq-core-client</artifactId>
+ <version>snap-r9548</version> </dependency> -->
+ <dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-core</artifactId>
<version>4.1.0-SNAPSHOT</version>
</dependency>
-
+
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-utils</artifactId>
<version>4.1.0-SNAPSHOT</version>
</dependency>
-
+
</dependencies>
+
+ <build>
+ <defaultGoal>install</defaultGoal>
+ <sourceDirectory>src</sourceDirectory>
+ </build>
</project>
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/0836bb8e/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidfirePrimaryDataStoreProvider.java
----------------------------------------------------------------------
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 883346c..a66fac2 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;
}
}