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