Skip to content

Commit 4b30043

Browse files
committed
<fix>[rest]: fix bug<description>
Resolves: ZCF-1365 Change-Id: I696f6a6a6e6d7867746e70736d6d646861686166
1 parent 42584b7 commit 4b30043

23 files changed

Lines changed: 1040 additions & 456 deletions

File tree

compute/src/main/java/org/zstack/compute/vm/VmAllocateNicFlow.java

Lines changed: 1 addition & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -300,41 +300,6 @@ public void done(ErrorCodeList errorCodeList) {
300300
});
301301
}
302302

303-
private void callAfterReleaseVmNicExtensions(List<VmNicInventory> nics, Completion completion) {
304-
List<AfterReleaseVmNicExtensionPoint> exts = pluginRgty.getExtensionList(AfterReleaseVmNicExtensionPoint.class);
305-
if (exts.isEmpty() || nics.isEmpty()) {
306-
completion.success();
307-
return;
308-
}
309-
310-
new While<>(nics).each((nic, wcomp) -> {
311-
new While<>(exts).each((ext, wcomp2) -> {
312-
ext.afterReleaseVmNic(nic, new Completion(wcomp2) {
313-
@Override
314-
public void success() {
315-
wcomp2.done();
316-
}
317-
318-
@Override
319-
public void fail(ErrorCode errorCode) {
320-
logger.warn(String.format("failed to call afterReleaseVmNic for nic[uuid:%s], %s", nic.getUuid(), errorCode));
321-
wcomp2.done();
322-
}
323-
});
324-
}).run(new WhileDoneCompletion(wcomp) {
325-
@Override
326-
public void done(ErrorCodeList errorCodeList) {
327-
wcomp.done();
328-
}
329-
});
330-
}).run(new WhileDoneCompletion(completion) {
331-
@Override
332-
public void done(ErrorCodeList errorCodeList) {
333-
completion.success();
334-
}
335-
});
336-
}
337-
338303
@Override
339304
public void rollback(final FlowRollback chain, Map data) {
340305
final VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString());
@@ -355,18 +320,6 @@ public void rollback(final FlowRollback chain, Map data) {
355320
}
356321
dbf.removeByPrimaryKeys(destNics.stream().map(VmNicInventory::getUuid).collect(Collectors.toList()), VmNicVO.class);
357322

358-
callAfterReleaseVmNicExtensions(destNics, new Completion(chain) {
359-
@Override
360-
public void success() {
361-
chain.rollback();
362-
}
363-
364-
@Override
365-
public void fail(ErrorCode errorCode) {
366-
// best-effort: log and continue rollback even if SDN cleanup fails
367-
logger.warn(String.format("afterReleaseVmNic extensions failed during rollback: %s", errorCode));
368-
chain.rollback();
369-
}
370-
});
323+
chain.rollback();
371324
}
372325
}
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
package org.zstack.compute.vm;
2+
3+
import org.springframework.beans.factory.annotation.Autowire;
4+
import org.springframework.beans.factory.annotation.Autowired;
5+
import org.springframework.beans.factory.annotation.Configurable;
6+
import org.zstack.core.asyncbatch.While;
7+
import org.zstack.core.componentloader.PluginRegistry;
8+
import org.zstack.header.core.Completion;
9+
import org.zstack.header.core.WhileDoneCompletion;
10+
import org.zstack.header.core.workflow.Flow;
11+
import org.zstack.header.core.workflow.FlowRollback;
12+
import org.zstack.header.core.workflow.FlowTrigger;
13+
import org.zstack.header.errorcode.ErrorCode;
14+
import org.zstack.header.errorcode.ErrorCodeList;
15+
import org.zstack.header.vm.*;
16+
import org.zstack.utils.Utils;
17+
import org.zstack.utils.logging.CLogger;
18+
19+
import java.util.List;
20+
import java.util.Map;
21+
22+
import static org.zstack.core.progress.ProgressReportService.taskProgress;
23+
24+
/**
25+
* Placed after VmAllocateNicIpFlow in the flow chain.
26+
*
27+
* For each NIC belonging to an SDN-managed L2 network, this flow delegates
28+
* to the registered {@link AfterAllocateSdnNicExtensionPoint} implementations
29+
* (typically {@code SdnControllerManagerImpl}) which:
30+
*
31+
* - OVN: calls addLogicalPorts() with already-allocated IPs
32+
* - ZNS: calls createSegmentPort(), receives IP back from ZNS, writes to DB
33+
* - H3C/Sugon: default no-op
34+
*
35+
* Non-SDN NICs are skipped by the extension implementation internally.
36+
*/
37+
@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE)
38+
public class VmAllocateSdnNicFlow implements Flow {
39+
private static final CLogger logger = Utils.getLogger(VmAllocateSdnNicFlow.class);
40+
41+
@Autowired
42+
private PluginRegistry pluginRgty;
43+
44+
@Override
45+
public void run(final FlowTrigger trigger, final Map data) {
46+
taskProgress("create SDN ports for nics");
47+
48+
final VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString());
49+
final List<VmNicInventory> nics = spec.getDestNics();
50+
51+
if (nics == null || nics.isEmpty()) {
52+
trigger.next();
53+
return;
54+
}
55+
56+
List<AfterAllocateSdnNicExtensionPoint> exts =
57+
pluginRgty.getExtensionList(AfterAllocateSdnNicExtensionPoint.class);
58+
if (exts.isEmpty()) {
59+
trigger.next();
60+
return;
61+
}
62+
63+
new While<>(exts).each((ext, wcomp) -> {
64+
ext.afterAllocateSdnNic(spec, nics, new Completion(wcomp) {
65+
@Override
66+
public void success() {
67+
wcomp.done();
68+
}
69+
70+
@Override
71+
public void fail(ErrorCode errorCode) {
72+
wcomp.addError(errorCode);
73+
wcomp.allDone();
74+
}
75+
});
76+
}).run(new WhileDoneCompletion(trigger) {
77+
@Override
78+
public void done(ErrorCodeList errorCodeList) {
79+
if (!errorCodeList.getCauses().isEmpty()) {
80+
trigger.fail(errorCodeList.getCauses().get(0));
81+
} else {
82+
trigger.next();
83+
}
84+
}
85+
});
86+
}
87+
88+
@Override
89+
public void rollback(final FlowRollback chain, Map data) {
90+
final VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString());
91+
final List<VmNicInventory> nics = spec.getDestNics();
92+
93+
List<AfterAllocateSdnNicExtensionPoint> exts =
94+
pluginRgty.getExtensionList(AfterAllocateSdnNicExtensionPoint.class);
95+
96+
if (exts.isEmpty() || nics == null || nics.isEmpty()) {
97+
chain.rollback();
98+
return;
99+
}
100+
101+
new While<>(exts).each((ext, wcomp) -> {
102+
ext.rollbackSdnNic(spec, nics, new Completion(wcomp) {
103+
@Override
104+
public void success() {
105+
wcomp.done();
106+
}
107+
108+
@Override
109+
public void fail(ErrorCode errorCode) {
110+
// best-effort: log and continue
111+
logger.warn(String.format("failed to rollback SDN nic: %s", errorCode));
112+
wcomp.done();
113+
}
114+
});
115+
}).run(new WhileDoneCompletion(chain) {
116+
@Override
117+
public void done(ErrorCodeList errorCodeList) {
118+
chain.rollback();
119+
}
120+
});
121+
}
122+
}

compute/src/main/java/org/zstack/compute/vm/VmDetachNicFlow.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,15 +100,15 @@ public void run(MessageReply reply) {
100100
public void done(ErrorCodeList errorCodeList) {
101101
dbf.removeByPrimaryKey(nic.getUuid(), VmNicVO.class);
102102

103-
callAfterReleaseVmNicExtensions(nic, new Completion(trigger) {
103+
callReleaseSdnNics(java.util.Collections.singletonList(nic), new Completion(trigger) {
104104
@Override
105105
public void success() {
106106
trigger.next();
107107
}
108108

109109
@Override
110110
public void fail(ErrorCode errorCode) {
111-
logger.warn(String.format("afterReleaseVmNic extensions failed for nic[uuid:%s]: %s, continue",
111+
logger.warn(String.format("releaseSdnNics failed for nic[uuid:%s]: %s, continue",
112112
nic.getUuid(), errorCode));
113113
trigger.next();
114114
}
@@ -117,24 +117,23 @@ public void fail(ErrorCode errorCode) {
117117
});
118118
}
119119

120-
private void callAfterReleaseVmNicExtensions(VmNicInventory nic, Completion completion) {
121-
List<AfterReleaseVmNicExtensionPoint> exts = pluginRgty.getExtensionList(AfterReleaseVmNicExtensionPoint.class);
120+
private void callReleaseSdnNics(List<VmNicInventory> nics, Completion completion) {
121+
List<AfterAllocateSdnNicExtensionPoint> exts = pluginRgty.getExtensionList(AfterAllocateSdnNicExtensionPoint.class);
122122
if (exts.isEmpty()) {
123123
completion.success();
124124
return;
125125
}
126126

127127
new While<>(exts).each((ext, wcomp) -> {
128-
ext.afterReleaseVmNic(nic, new Completion(wcomp) {
128+
ext.releaseSdnNics(nics, new Completion(wcomp) {
129129
@Override
130130
public void success() {
131131
wcomp.done();
132132
}
133133

134134
@Override
135135
public void fail(ErrorCode errorCode) {
136-
logger.warn(String.format("afterReleaseVmNic extension failed for nic[uuid:%s]: %s, continue",
137-
nic.getUuid(), errorCode));
136+
logger.warn(String.format("releaseSdnNics extension failed: %s, continue", errorCode));
138137
wcomp.done();
139138
}
140139
});

compute/src/main/java/org/zstack/compute/vm/VmInstanceBase.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2287,6 +2287,7 @@ void rollback() {
22872287

22882288
flowChain.then(new VmAllocateNicFlow());
22892289
flowChain.then(new VmAllocateNicIpFlow());
2290+
flowChain.then(new VmAllocateSdnNicFlow());
22902291
flowChain.then(new VmSetDefaultL3NetworkOnAttachingFlow());
22912292
setAdditionalFlow(flowChain, spec);
22922293
if (self.getState() == VmInstanceState.Running) {

compute/src/main/java/org/zstack/compute/vm/VmReturnReleaseNicFlow.java

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -98,47 +98,39 @@ public void done(ErrorCodeList errorCodeList) {
9898
releasedNics.add(nic);
9999
}
100100

101-
callAfterReleaseVmNicExtensions(releasedNics, new Completion(chain) {
101+
callReleaseSdnNics(releasedNics, new Completion(chain) {
102102
@Override
103103
public void success() {
104104
chain.next();
105105
}
106106

107107
@Override
108108
public void fail(ErrorCode errorCode) {
109-
logger.warn(String.format("afterReleaseVmNic extensions failed: %s, continue anyway", errorCode));
109+
logger.warn(String.format("releaseSdnNics failed: %s, continue anyway", errorCode));
110110
chain.next();
111111
}
112112
});
113113
}
114114
});
115115
}
116116

117-
private void callAfterReleaseVmNicExtensions(List<VmNicInventory> nics, Completion completion) {
118-
List<AfterReleaseVmNicExtensionPoint> exts = pluginRgty.getExtensionList(AfterReleaseVmNicExtensionPoint.class);
117+
private void callReleaseSdnNics(List<VmNicInventory> nics, Completion completion) {
118+
List<AfterAllocateSdnNicExtensionPoint> exts = pluginRgty.getExtensionList(AfterAllocateSdnNicExtensionPoint.class);
119119
if (exts.isEmpty() || nics.isEmpty()) {
120120
completion.success();
121121
return;
122122
}
123123

124-
new While<>(nics).each((nic, wcomp) -> {
125-
new While<>(exts).each((ext, wcomp2) -> {
126-
ext.afterReleaseVmNic(nic, new Completion(wcomp2) {
127-
@Override
128-
public void success() {
129-
wcomp2.done();
130-
}
124+
new While<>(exts).each((ext, wcomp) -> {
125+
ext.releaseSdnNics(nics, new Completion(wcomp) {
126+
@Override
127+
public void success() {
128+
wcomp.done();
129+
}
131130

132-
@Override
133-
public void fail(ErrorCode errorCode) {
134-
logger.warn(String.format("afterReleaseVmNic extension failed for nic[uuid:%s]: %s, continue",
135-
nic.getUuid(), errorCode));
136-
wcomp2.done();
137-
}
138-
});
139-
}).run(new WhileDoneCompletion(wcomp) {
140131
@Override
141-
public void done(ErrorCodeList errorCodeList) {
132+
public void fail(ErrorCode errorCode) {
133+
logger.warn(String.format("releaseSdnNics extension failed: %s, continue", errorCode));
142134
wcomp.done();
143135
}
144136
});

compute/src/main/java/org/zstack/compute/vm/VmSystemTags.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import org.zstack.header.tag.AdminOnlyTag;
66
import org.zstack.header.tag.TagDefinition;
77
import org.zstack.header.vm.VmInstanceVO;
8+
import org.zstack.header.vm.VmNicVO;
89
import org.zstack.tag.PatternedSystemTag;
910
import org.zstack.tag.SensitiveTagOutputHandler;
1011
import org.zstack.tag.SensitiveTag;
@@ -314,4 +315,8 @@ public String desensitizeTag(SystemTag systemTag, String tag) {
314315
public static PatternedSystemTag VM_STATE_PAUSED_AFTER_MIGRATE = new PatternedSystemTag(("vmPausedAfterMigrate"), VmInstanceVO.class);
315316

316317
public static PatternedSystemTag VM_MEMORY_ACCESS_MODE_SHARED = new PatternedSystemTag(("vmMemoryAccessModeShared"), VmInstanceVO.class);
318+
319+
public static String IFACE_ID_TOKEN = "ifaceId";
320+
public static PatternedSystemTag IFACE_ID = new PatternedSystemTag(
321+
String.format("ifaceId::{%s}", IFACE_ID_TOKEN), VmNicVO.class);
317322
}

conf/springConfigXml/VmInstanceManager.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
<value>org.zstack.compute.vm.VmAllocateVolumeFlow</value>
3838
<value>org.zstack.compute.vm.VmAllocateNicFlow</value>
3939
<value>org.zstack.compute.vm.VmAllocateNicIpFlow</value>
40+
<value>org.zstack.compute.vm.VmAllocateSdnNicFlow</value>
4041
<value>org.zstack.compute.vm.VmAllocateCdRomFlow</value>
4142
<value>org.zstack.compute.vm.VmInstantiateResourcePreFlow</value>
4243
<value>org.zstack.compute.vm.VmCreateOnHypervisorFlow</value>

conf/springConfigXml/sdnController.xml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,11 @@
2626
<zstack:extension interface="org.zstack.sdnController.SdnControllerManager" />
2727
<zstack:extension interface="org.zstack.header.network.l2.L2NetworkCreateExtensionPoint" />
2828
<zstack:extension interface="org.zstack.header.network.l2.L2NetworkDeleteExtensionPoint" />
29-
<zstack:extension interface="org.zstack.header.vm.PreVmInstantiateResourceExtensionPoint"/>
30-
<zstack:extension interface="org.zstack.header.vm.VmReleaseResourceExtensionPoint" order="-500"/>
31-
<zstack:extension interface="org.zstack.header.vm.InstantiateResourceOnAttachingNicExtensionPoint"/>
32-
<zstack:extension interface="org.zstack.header.vm.ReleaseNetworkServiceOnDetachingNicExtensionPoint" order="-500"/>
3329
<zstack:extension interface="org.zstack.network.securitygroup.SecurityGroupGetSdnBackendExtensionPoint"/>
3430
<zstack:extension interface="org.zstack.header.network.l3.AfterAddIpRangeExtensionPoint"/>
3531
<zstack:extension interface="org.zstack.header.network.l3.IpRangeDeletionExtensionPoint"/>
3632
<zstack:extension interface="org.zstack.header.network.service.GetSdnControllerExtensionPoint"/>
37-
<zstack:extension interface="org.zstack.header.vm.BeforeAllocateVmNicExtensionPoint"/>
38-
<zstack:extension interface="org.zstack.header.vm.AfterReleaseVmNicExtensionPoint"/>
33+
<zstack:extension interface="org.zstack.header.vm.AfterAllocateSdnNicExtensionPoint"/>
3934
</zstack:plugin>
4035
</bean>
4136

core/src/main/java/org/zstack/core/rest/webhook/WebhookCallbackClient.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,13 +131,30 @@ public String getCallbackUrl() {
131131
return callbackUrl;
132132
}
133133

134+
/**
135+
* Override the callback URL. Use this when the callback is handled by a
136+
* dedicated HTTP endpoint (e.g. a Spring Controller) rather than the
137+
* sendCommand channel.
138+
*/
139+
public void setCallbackUrl(String callbackUrl) {
140+
this.callbackUrl = callbackUrl;
141+
}
142+
134143
/**
135144
* @return the protocol adapter
136145
*/
137146
public WebhookProtocol<T> getProtocol() {
138147
return protocol;
139148
}
140149

150+
/**
151+
* Deliver a callback that was received outside the sendCommand channel
152+
* (e.g. from a dedicated Spring Controller endpoint for external systems).
153+
*/
154+
public void deliverCallback(T cmd) {
155+
onCallback(cmd);
156+
}
157+
141158
/**
142159
* Callback handler invoked by the RESTFacade sendCommand channel.
143160
*/

0 commit comments

Comments
 (0)