Skip to content

Commit 0633608

Browse files
author
frank
committed
CLOUDSTACK-3453
UCS:API: List Blades after decommissioning a blade, listUcsBlades API returns wrong number of total blades fixed resolved
1 parent 0cdda29 commit 0633608

2 files changed

Lines changed: 87 additions & 3 deletions

File tree

plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManagerImpl.java

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@
2222
import java.util.List;
2323
import java.util.Map;
2424
import java.util.UUID;
25+
import java.util.concurrent.Executors;
26+
import java.util.concurrent.ScheduledExecutorService;
2527
import java.util.concurrent.TimeUnit;
2628

2729
import javax.ejb.Local;
2830
import javax.inject.Inject;
2931
import javax.naming.ConfigurationException;
3032

31-
import org.apache.log4j.Logger;
32-
3333
import org.apache.cloudstack.api.AddUcsManagerCmd;
3434
import org.apache.cloudstack.api.AssociateUcsProfileToBladeCmd;
3535
import org.apache.cloudstack.api.ListUcsBladeCmd;
@@ -39,7 +39,10 @@
3939
import org.apache.cloudstack.api.response.UcsBladeResponse;
4040
import org.apache.cloudstack.api.response.UcsManagerResponse;
4141
import org.apache.cloudstack.api.response.UcsProfileResponse;
42+
import org.apache.log4j.Logger;
4243

44+
import com.cloud.configuration.Config;
45+
import com.cloud.configuration.dao.ConfigurationDao;
4346
import com.cloud.dc.ClusterDetailsDao;
4447
import com.cloud.dc.DataCenterVO;
4548
import com.cloud.dc.dao.ClusterDao;
@@ -54,6 +57,7 @@
5457
import com.cloud.ucs.structure.ComputeBlade;
5558
import com.cloud.ucs.structure.UcsCookie;
5659
import com.cloud.ucs.structure.UcsProfile;
60+
import com.cloud.utils.concurrency.NamedThreadFactory;
5761
import com.cloud.utils.db.DB;
5862
import com.cloud.utils.db.SearchCriteria.Op;
5963
import com.cloud.utils.db.SearchCriteria2;
@@ -83,11 +87,86 @@ public class UcsManagerImpl implements UcsManager {
8387
private HostDao hostDao;
8488
@Inject
8589
private DataCenterDao dcDao;
90+
@Inject
91+
private ConfigurationDao configDao;
8692

8793
private final Map<Long, UcsCookie> cookies = new HashMap<Long, UcsCookie>();
8894
private String name;
8995
private int runLevel;
9096
private Map<String, Object> params;
97+
private ScheduledExecutorService syncBladesExecutor;
98+
private int syncBladeInterval;
99+
100+
private class SyncBladesThread implements Runnable {
101+
102+
private void discoverNewBlades(Map<String, UcsBladeVO> previous,
103+
Map<String, ComputeBlade> now, UcsManagerVO mgr) {
104+
for (Map.Entry<String, ComputeBlade> e : now.entrySet()) {
105+
String dn = e.getKey();
106+
if (previous.keySet().contains(dn)) {
107+
continue;
108+
}
109+
110+
ComputeBlade nc = e.getValue();
111+
UcsBladeVO vo = new UcsBladeVO();
112+
vo.setDn(nc.getDn());
113+
vo.setUcsManagerId(mgr.getId());
114+
vo.setUuid(UUID.randomUUID().toString());
115+
bladeDao.persist(vo);
116+
s_logger.debug(String.format("discovered a new UCS blade[dn:%s] during sync", nc.getDn()));
117+
}
118+
}
119+
120+
private void decommissionFadedBlade(Map<String, UcsBladeVO> previous, Map<String, ComputeBlade> now) {
121+
for (Map.Entry<String, UcsBladeVO> e : previous.entrySet()) {
122+
String dn = e.getKey();
123+
if (now.keySet().contains(dn)) {
124+
continue;
125+
}
126+
127+
UcsBladeVO vo = e.getValue();
128+
bladeDao.remove(vo.getId());
129+
s_logger.debug(String.format("decommission faded blade[dn:%s] during sync", vo.getDn()));
130+
}
131+
}
132+
133+
private void syncBlades(UcsManagerVO mgr) {
134+
SearchCriteriaService<UcsBladeVO, UcsBladeVO> q = SearchCriteria2.create(UcsBladeVO.class);
135+
q.addAnd(q.getEntity().getUcsManagerId(), Op.EQ, mgr.getId());
136+
List<UcsBladeVO> pblades = q.list();
137+
if (pblades.isEmpty()) {
138+
return;
139+
}
140+
141+
142+
Map<String, UcsBladeVO> previousBlades = new HashMap<String, UcsBladeVO>(pblades.size());
143+
for (UcsBladeVO b : pblades) {
144+
previousBlades.put(b.getDn(), b);
145+
}
146+
147+
List<ComputeBlade> cblades = listBlades(mgr.getId());
148+
Map<String, ComputeBlade> currentBlades = new HashMap<String, ComputeBlade>(cblades.size());
149+
for (ComputeBlade c : cblades) {
150+
currentBlades.put(c.getDn(), c);
151+
}
152+
153+
discoverNewBlades(previousBlades, currentBlades, mgr);
154+
decommissionFadedBlade(previousBlades, currentBlades);
155+
}
156+
157+
@Override
158+
public void run() {
159+
try {
160+
List<UcsManagerVO> mgrs = ucsDao.listAll();
161+
for (UcsManagerVO mgr : mgrs) {
162+
syncBlades(mgr);
163+
}
164+
} catch (Throwable t) {
165+
s_logger.warn(t.getMessage(), t);
166+
}
167+
}
168+
169+
}
91170

92171
@Override
93172
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
@@ -96,6 +175,9 @@ public boolean configure(String name, Map<String, Object> params) throws Configu
96175

97176
@Override
98177
public boolean start() {
178+
syncBladeInterval = Integer.valueOf(configDao.getValue(Config.UCSSyncBladeInterval.key()));
179+
syncBladesExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("UCS-SyncBlades"));
180+
syncBladesExecutor.scheduleAtFixedRate(new SyncBladesThread(), syncBladeInterval, syncBladeInterval, TimeUnit.SECONDS);
99181
return true;
100182
}
101183

server/src/com/cloud/configuration/Config.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,9 @@ public enum Config {
437437
ExecuteInSequence("Advanced", ManagementServer.class, Boolean.class, "execute.in.sequence.hypervisor.commands", "false", "If set to true, StartCommand, StopCommand, CopyCommand will be synchronized on the agent side." +
438438
" If set to false, these commands become asynchronous. Default value is false.", null),
439439
ExecuteInSequenceNetworkElementCommands("Advanced", NetworkManager.class, Boolean.class, "execute.in.sequence.network.element.commands", "false", "If set to true, DhcpEntryCommand, SavePasswordCommand, UserDataCommand, VmDataCommand will be synchronized on the agent side." +
440-
" If set to false, these commands become asynchronous. Default value is false.", null);
440+
" If set to false, these commands become asynchronous. Default value is false.", null),
441+
442+
UCSSyncBladeInterval("Advanced", ManagementServer.class, Integer.class, "ucs.sync.blade.interval", "3600", "the interval cloudstack sync with UCS manager for available blades in case user remove blades from chassis without notifying CloudStack", null);
441443

442444
private final String _category;
443445
private final Class<?> _componentClass;

0 commit comments

Comments
 (0)