Skip to content

Commit 0836bb8

Browse files
committed
add state machine for templateonprimarystorage, thus we don't need hold lock
1 parent eee58d7 commit 0836bb8

15 files changed

Lines changed: 269 additions & 141 deletions

File tree

engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import java.util.List;
2323

24+
import org.apache.cloudstack.engine.datacenter.entity.api.DataCenterResourceEntity.State;
2425
import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskType;
2526

2627
import com.cloud.hypervisor.Hypervisor.HypervisorType;
@@ -34,4 +35,6 @@ public interface PrimaryDataStoreInfo {
3435
public List<EndPoint> getEndPoints();
3536
public long getId();
3637
public String getUuid();
38+
public State getManagedState();
39+
public String getName();
3740
}

engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreEntityImpl.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,14 +137,12 @@ public List<Method> getApplicableActions() {
137137

138138
@Override
139139
public State getState() {
140-
// TODO Auto-generated method stub
141-
return null;
140+
return this.dataStore.getManagedState();
142141
}
143142

144143
@Override
145144
public String getName() {
146-
// TODO Auto-generated method stub
147-
return null;
145+
return this.dataStore.getName();
148146
}
149147

150148
@Override
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.cloudstack.storage.volume;
20+
21+
import com.cloud.utils.fsm.StateObject;
22+
23+
public interface TemplateOnPrimaryDataStoreStateMachine extends StateObject<TemplateOnPrimaryDataStoreStateMachine.State> {
24+
enum State {
25+
Allocated("The initial state"),
26+
Creating("The template is being downloading to data store"),
27+
Ready("Template downloading is complished"),
28+
Destroying("Template is destroying"),
29+
Destroyed("Template is destroyed"),
30+
Failed("Failed to download template");
31+
String _description;
32+
33+
private State(String description) {
34+
_description = description;
35+
}
36+
37+
public String getDescription() {
38+
return _description;
39+
}
40+
}
41+
42+
enum Event {
43+
CreateRequested,
44+
DestroyRequested,
45+
OperationSuccessed,
46+
OperationFailed,
47+
}
48+
}

engine/storage/src/org/apache/cloudstack/storage/volume/db/TemplatePrimaryDataStoreDao.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,12 @@
1818
*/
1919
package org.apache.cloudstack.storage.volume.db;
2020

21+
import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreStateMachine;
22+
2123
import com.cloud.utils.db.GenericDao;
24+
import com.cloud.utils.fsm.StateDao;
2225

23-
public interface TemplatePrimaryDataStoreDao extends GenericDao<TemplatePrimaryDataStoreVO, Long> {
26+
public interface TemplatePrimaryDataStoreDao extends GenericDao<TemplatePrimaryDataStoreVO, Long>, StateDao<TemplateOnPrimaryDataStoreStateMachine.State, TemplateOnPrimaryDataStoreStateMachine.Event, TemplatePrimaryDataStoreVO> {
27+
public TemplatePrimaryDataStoreVO findByTemplateIdAndPoolId(long templateId, long poolId);
28+
public TemplatePrimaryDataStoreVO findByTemplateIdAndPoolIdAndReady(long templateId, long poolId);
2429
}

engine/storage/src/org/apache/cloudstack/storage/volume/db/TemplatePrimaryDataStoreDaoImpl.java

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,79 @@
1818
*/
1919
package org.apache.cloudstack.storage.volume.db;
2020

21+
import java.util.Date;
22+
23+
import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreStateMachine;
24+
import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreStateMachine.Event;
25+
import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreStateMachine.State;
26+
import org.apache.log4j.Logger;
2127
import org.springframework.stereotype.Component;
2228

2329
import com.cloud.utils.db.GenericDaoBase;
30+
import com.cloud.utils.db.SearchCriteria.Op;
31+
import com.cloud.utils.db.SearchBuilder;
32+
import com.cloud.utils.db.SearchCriteria;
33+
import com.cloud.utils.db.SearchCriteria2;
34+
import com.cloud.utils.db.SearchCriteriaService;
35+
import com.cloud.utils.db.UpdateBuilder;
2436

2537
@Component
2638
public class TemplatePrimaryDataStoreDaoImpl extends GenericDaoBase<TemplatePrimaryDataStoreVO, Long> implements TemplatePrimaryDataStoreDao {
39+
private static final Logger s_logger = Logger.getLogger(TemplatePrimaryDataStoreDaoImpl.class);
40+
protected final SearchBuilder<TemplatePrimaryDataStoreVO> updateSearchBuilder;
41+
public TemplatePrimaryDataStoreDaoImpl() {
42+
updateSearchBuilder = createSearchBuilder();
43+
updateSearchBuilder.and("id", updateSearchBuilder.entity().getId(), Op.EQ);
44+
updateSearchBuilder.and("state", updateSearchBuilder.entity().getState(), Op.EQ);
45+
updateSearchBuilder.and("updatedCount", updateSearchBuilder.entity().getUpdatedCount(), Op.EQ);
46+
updateSearchBuilder.done();
47+
}
48+
@Override
49+
public TemplatePrimaryDataStoreVO findByTemplateIdAndPoolId(long templateId, long poolId) {
50+
SearchCriteriaService<TemplatePrimaryDataStoreVO, TemplatePrimaryDataStoreVO> sc = SearchCriteria2.create(TemplatePrimaryDataStoreVO.class);
51+
sc.addAnd(sc.getEntity().getTemplateId(), Op.EQ, templateId);
52+
sc.addAnd(sc.getEntity().getPoolId(), Op.EQ, poolId);
53+
return sc.find();
54+
}
55+
56+
@Override
57+
public TemplatePrimaryDataStoreVO findByTemplateIdAndPoolIdAndReady(long templateId, long poolId) {
58+
SearchCriteriaService<TemplatePrimaryDataStoreVO, TemplatePrimaryDataStoreVO> sc = SearchCriteria2.create(TemplatePrimaryDataStoreVO.class);
59+
sc.addAnd(sc.getEntity().getTemplateId(), Op.EQ, templateId);
60+
sc.addAnd(sc.getEntity().getPoolId(), Op.EQ, poolId);
61+
sc.addAnd(sc.getEntity().getState(), Op.EQ, TemplateOnPrimaryDataStoreStateMachine.State.Ready);
62+
return sc.find();
63+
}
2764

65+
@Override
66+
public boolean updateState(State currentState, Event event, State nextState, TemplatePrimaryDataStoreVO vo, Object data) {
67+
Long oldUpdated = vo.getUpdatedCount();
68+
Date oldUpdatedTime = vo.getLastUpdated();
69+
70+
SearchCriteria<TemplatePrimaryDataStoreVO> sc = updateSearchBuilder.create();
71+
sc.setParameters("id", vo.getId());
72+
sc.setParameters("state", currentState);
73+
sc.setParameters("updatedCount", vo.getUpdatedCount());
74+
75+
vo.incrUpdatedCount();
76+
77+
UpdateBuilder builder = getUpdateBuilder(vo);
78+
builder.set(vo, "state", nextState);
79+
builder.set(vo, "lastUpdated", new Date());
80+
81+
int rows = update((TemplatePrimaryDataStoreVO)vo, sc);
82+
if (rows == 0 && s_logger.isDebugEnabled()) {
83+
TemplatePrimaryDataStoreVO template = findByIdIncludingRemoved(vo.getId());
84+
if (template != null) {
85+
StringBuilder str = new StringBuilder("Unable to update ").append(vo.toString());
86+
str.append(": DB Data={id=").append(template.getId()).append("; state=").append(template.getState()).append("; updatecount=").append(template.getUpdatedCount()).append(";updatedTime=").append(template.getLastUpdated());
87+
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());
88+
str.append(": stale Data={id=").append(vo.getId()).append("; state=").append(currentState).append("; event=").append(event).append("; updatecount=").append(oldUpdated).append("; updatedTime=").append(oldUpdatedTime);
89+
} else {
90+
s_logger.debug("Unable to update template: id=" + vo.getId() + ", as there is no such template exists in the database anymore");
91+
}
92+
}
93+
return rows > 0;
94+
}
95+
2896
}

engine/storage/src/org/apache/cloudstack/storage/volume/db/TemplatePrimaryDataStoreVO.java

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,13 @@
3232
import javax.persistence.TemporalType;
3333

3434
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
35-
35+
import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreStateMachine;
3636
import com.cloud.utils.db.GenericDaoBase;
37+
import com.cloud.utils.fsm.StateObject;
3738

3839
@Entity
3940
@Table(name = "template_spool_ref")
40-
public class TemplatePrimaryDataStoreVO {
41+
public class TemplatePrimaryDataStoreVO implements StateObject<TemplateOnPrimaryDataStoreStateMachine.State> {
4142
@Id
4243
@GeneratedValue(strategy = GenerationType.IDENTITY)
4344
long id;
@@ -79,6 +80,25 @@ public class TemplatePrimaryDataStoreVO {
7980

8081
@Column(name = "marked_for_gc")
8182
boolean markedForGC;
83+
84+
@Column(name = "state")
85+
@Enumerated(EnumType.STRING)
86+
TemplateOnPrimaryDataStoreStateMachine.State state;
87+
88+
@Column(name="update_count", updatable = true, nullable=false)
89+
protected long updatedCount;
90+
91+
public long getUpdatedCount() {
92+
return this.updatedCount;
93+
}
94+
95+
public void incrUpdatedCount() {
96+
this.updatedCount++;
97+
}
98+
99+
public void decrUpdatedCount() {
100+
this.updatedCount--;
101+
}
82102

83103
public String getInstallPath() {
84104
return installPath;
@@ -224,4 +244,9 @@ public String toString() {
224244
return new StringBuilder("TmplPool[").append(id).append("-").append(templateId).append("-").append("poolId").append("-").append(installPath).append("]").toString();
225245
}
226246

247+
@Override
248+
public TemplateOnPrimaryDataStoreStateMachine.State getState() {
249+
return this.state;
250+
}
251+
227252
}

engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreInfoImpl.java

Lines changed: 0 additions & 80 deletions
This file was deleted.

engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultPrimaryDatastoreProviderImpl.java

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
import javax.inject.Inject;
66

7-
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
87
import org.apache.cloudstack.storage.datastore.DefaultPrimaryDataStore;
98
import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
109
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreProviderVO;
@@ -16,20 +15,17 @@
1615
import org.apache.cloudstack.storage.datastore.lifecycle.PrimaryDataStoreLifeCycle;
1716
import org.springframework.stereotype.Component;
1817

19-
import com.cloud.utils.component.ComponentInject;
20-
2118
@Component
2219
public class DefaultPrimaryDatastoreProviderImpl implements PrimaryDataStoreProvider {
2320
private final String providerName = "default primary data store provider";
2421
protected PrimaryDataStoreDriver driver;
2522
private PrimaryDataStoreProviderVO provider;
26-
protected final PrimaryDataStoreDao dataStoreDao;
23+
@Inject
24+
protected PrimaryDataStoreDao dataStoreDao;
2725
protected PrimaryDataStoreLifeCycle dataStoreLifeCycle;
2826

29-
@Inject
30-
public DefaultPrimaryDatastoreProviderImpl(PrimaryDataStoreDao dataStoreDao) {
27+
public DefaultPrimaryDatastoreProviderImpl() {
3128
this.driver = new DefaultPrimaryDataStoreDriverImpl();
32-
this.dataStoreDao = dataStoreDao;
3329
this.dataStoreLifeCycle = new DefaultPrimaryDataStoreLifeCycleImpl(this, dataStoreDao);
3430
}
3531

@@ -44,12 +40,6 @@ public PrimaryDataStore getDataStore(long dataStoreId) {
4440
return pds;
4541
}
4642

47-
@Override
48-
public PrimaryDataStoreInfo getDataStoreInfo(long dataStoreId) {
49-
// TODO Auto-generated method stub
50-
return null;
51-
}
52-
5343
@Override
5444
public PrimaryDataStoreLifeCycle getDataStoreLifeCycle() {
5545
return dataStoreLifeCycle;

engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/PrimaryDataStoreProvider.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
public interface PrimaryDataStoreProvider {
1111
public PrimaryDataStore getDataStore(long dataStoreId);
1212
public PrimaryDataStoreLifeCycle getDataStoreLifeCycle();
13-
public PrimaryDataStoreInfo getDataStoreInfo(long dataStoreId);
1413
public long getId();
1514
public String getName();
1615
public boolean register(PrimaryDataStoreProviderVO provider, Map<String, Object> params);

0 commit comments

Comments
 (0)