This is an automated email from the ASF dual-hosted git repository.
sureshanaparti pushed a commit to branch 4.22
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/4.22 by this push:
new 05c59630e0a fix: LB Creation avoid 404 API errors due to non-needed
patches (#12835)
05c59630e0a is described below
commit 05c59630e0ae0fb3e7df8b15ff00af0ae005197a
Author: Daniil Zhyliaiev <[email protected]>
AuthorDate: Thu Apr 16 11:28:20 2026 +0300
fix: LB Creation avoid 404 API errors due to non-needed patches (#12835)
---
.../apache/cloudstack/service/NsxApiClient.java | 65 ++++-
.../cloudstack/service/NsxApiClientTest.java | 311 +++++++++++++++++++++
2 files changed, 370 insertions(+), 6 deletions(-)
diff --git
a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxApiClient.java
b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxApiClient.java
index 7ad27c4a635..868417f1d60 100644
---
a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxApiClient.java
+++
b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxApiClient.java
@@ -83,6 +83,7 @@ import com.vmware.vapi.internal.protocol.RestProtocol;
import
com.vmware.vapi.internal.protocol.client.rest.authn.BasicAuthenticationAppender;
import com.vmware.vapi.protocol.HttpConfiguration;
import com.vmware.vapi.std.errors.Error;
+import com.vmware.vapi.std.errors.NotFound;
import org.apache.cloudstack.resource.NsxLoadBalancerMember;
import org.apache.cloudstack.resource.NsxNetworkRule;
import org.apache.cloudstack.utils.NsxControllerUtils;
@@ -96,9 +97,11 @@ import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Optional;
+import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
+import static java.util.stream.Collectors.toSet;
import static
org.apache.cloudstack.utils.NsxControllerUtils.getServerPoolMemberName;
import static org.apache.cloudstack.utils.NsxControllerUtils.getServerPoolName;
import static org.apache.cloudstack.utils.NsxControllerUtils.getServiceName;
@@ -656,9 +659,20 @@ public class NsxApiClient {
public void createNsxLbServerPool(List<NsxLoadBalancerMember> memberList,
String tier1GatewayName, String lbServerPoolName,
String algorithm, String privatePort,
String protocol) {
try {
- String activeMonitorPath =
getLbActiveMonitorPath(lbServerPoolName, privatePort, protocol);
List<LBPoolMember> members = getLbPoolMembers(memberList,
tier1GatewayName);
LbPools lbPools = (LbPools) nsxService.apply(LbPools.class);
+ Optional<LBPool> nsxLbServerPool = getNsxLbServerPool(lbPools,
lbServerPoolName);
+ // Skip if pool exists and members unchanged
+ if (nsxLbServerPool.isPresent()) {
+ List<LBPoolMember> existingMembers = nsxLbServerPool
+ .map(LBPool::getMembers)
+ .orElseGet(List::of);
+ if (hasSamePoolMembers(existingMembers, members)) {
+ logger.debug("Skipping patch for LB pool {} on Tier-1 {}:
members unchanged", lbServerPoolName, tier1GatewayName);
+ return;
+ }
+ }
+ String activeMonitorPath =
getLbActiveMonitorPath(lbServerPoolName, privatePort, protocol);
LBPool lbPool = new LBPool.Builder()
.setId(lbServerPoolName)
.setDisplayName(lbServerPoolName)
@@ -676,9 +690,52 @@ public class NsxApiClient {
}
}
+ private Optional<LBPool> getNsxLbServerPool(LbPools lbPools, String
lbServerPoolName) {
+ try {
+ return Optional.ofNullable(lbPools.get(lbServerPoolName));
+ } catch (NotFound e) {
+ logger.warn("Server Pool not found: {}", lbServerPoolName);
+ return Optional.empty();
+ }
+ }
+
+ private boolean hasSamePoolMembers(List<LBPoolMember> existingMembers,
List<LBPoolMember> membersUpdate) {
+ Set<String> existingMembersSet = existingMembers.stream()
+ .map(this::buildPoolMemberKey)
+ .collect(toSet());
+ Set<String> updateMembersSet = membersUpdate.stream()
+ .map(this::buildPoolMemberKey)
+ .collect(toSet());
+
+ return existingMembersSet.size() == updateMembersSet.size()
+ && existingMembersSet.containsAll(updateMembersSet);
+ }
+
+ private String buildPoolMemberKey(LBPoolMember member) {
+ return member.getIpAddress() + ':' + member.getPort() + ':' +
member.getDisplayName();
+ }
+
private String getLbActiveMonitorPath(String lbServerPoolName, String
port, String protocol) {
LbMonitorProfiles lbActiveMonitor = (LbMonitorProfiles)
nsxService.apply(LbMonitorProfiles.class);
String lbMonitorProfileId =
getActiveMonitorProfileName(lbServerPoolName, port, protocol);
+ Optional<Structure> monitorProfile =
getMonitorProfile(lbActiveMonitor, lbMonitorProfileId);
+ if (monitorProfile.isEmpty()) {
+ patchMonitoringProfile(port, protocol, lbMonitorProfileId,
lbActiveMonitor);
+ monitorProfile = getMonitorProfile(lbActiveMonitor,
lbMonitorProfileId);
+ }
+ return monitorProfile.map(structure ->
structure._getDataValue().getField("path").toString()).orElse(null);
+ }
+
+ private Optional<Structure> getMonitorProfile(LbMonitorProfiles
lbActiveMonitor, String lbMonitorProfileId) {
+ try {
+ return
Optional.ofNullable(lbActiveMonitor.get(lbMonitorProfileId));
+ } catch (NotFound e) {
+ logger.warn("LB Monitor Profile not found: {}",
lbMonitorProfileId);
+ return Optional.empty();
+ }
+ }
+
+ private void patchMonitoringProfile(String port, String protocol, String
lbMonitorProfileId, LbMonitorProfiles lbActiveMonitor) {
if ("TCP".equals(protocol.toUpperCase(Locale.ROOT))) {
LBTcpMonitorProfile lbTcpMonitorProfile = new
LBTcpMonitorProfile.Builder(TCP_MONITOR_PROFILE)
.setDisplayName(lbMonitorProfileId)
@@ -691,10 +748,6 @@ public class NsxApiClient {
.build();
lbActiveMonitor.patch(lbMonitorProfileId, icmpMonitorProfile);
}
-
- LBMonitorProfileListResult listResult =
listLBActiveMonitors(lbActiveMonitor);
- Optional<Structure> monitorProfile =
listResult.getResults().stream().filter(profile ->
profile._getDataValue().getField("id").toString().equals(lbMonitorProfileId)).findFirst();
- return monitorProfile.map(structure ->
structure._getDataValue().getField("path").toString()).orElse(null);
}
LBMonitorProfileListResult listLBActiveMonitors(LbMonitorProfiles
lbActiveMonitor) {
@@ -735,7 +788,7 @@ public class NsxApiClient {
String lbVirtualServerName =
getVirtualServerName(tier1GatewayName, lbId);
String lbServiceName = getLoadBalancerName(tier1GatewayName);
LbVirtualServers lbVirtualServers = (LbVirtualServers)
nsxService.apply(LbVirtualServers.class);
- if (Objects.nonNull(getLbVirtualServerService(lbVirtualServers,
lbServiceName))) {
+ if (Objects.nonNull(getLbVirtualServerService(lbVirtualServers,
lbVirtualServerName))) {
return;
}
LBVirtualServer lbVirtualServer = new LBVirtualServer.Builder()
diff --git
a/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxApiClientTest.java
b/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxApiClientTest.java
index f9ee8daea4b..5f8d771f75d 100644
---
a/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxApiClientTest.java
+++
b/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxApiClientTest.java
@@ -18,13 +18,32 @@ package org.apache.cloudstack.service;
import com.cloud.network.Network;
import com.cloud.network.SDNProviderNetworkRule;
+import com.cloud.utils.exception.CloudRuntimeException;
import com.vmware.nsx.cluster.Status;
import com.vmware.nsx.model.ClusterStatus;
import com.vmware.nsx.model.ControllerClusterStatus;
+import com.vmware.nsx_policy.infra.LbAppProfiles;
+import com.vmware.nsx_policy.infra.LbMonitorProfiles;
+import com.vmware.nsx_policy.infra.LbPools;
+import com.vmware.nsx_policy.infra.LbServices;
+import com.vmware.nsx_policy.infra.LbVirtualServers;
import com.vmware.nsx_policy.infra.domains.Groups;
+import com.vmware.nsx_policy.model.ApiError;
import com.vmware.nsx_policy.model.Group;
+import com.vmware.nsx_policy.model.LBAppProfileListResult;
+import com.vmware.nsx_policy.model.LBIcmpMonitorProfile;
+import com.vmware.nsx_policy.model.LBService;
+import com.vmware.nsx_policy.model.LBTcpMonitorProfile;
+import com.vmware.nsx_policy.model.LBPool;
+import com.vmware.nsx_policy.model.LBPoolMember;
+import com.vmware.nsx_policy.model.LBVirtualServer;
import com.vmware.nsx_policy.model.PathExpression;
import com.vmware.vapi.bindings.Service;
+import com.vmware.vapi.bindings.Structure;
+import com.vmware.vapi.std.errors.Error;
+import com.vmware.vapi.std.errors.NotFound;
+import org.apache.cloudstack.resource.NsxLoadBalancerMember;
+import org.apache.cloudstack.utils.NsxControllerUtils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -36,8 +55,20 @@ import org.mockito.MockitoAnnotations;
import java.util.List;
import java.util.function.Function;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
public class NsxApiClientTest {
+ private static final String TIER_1_GATEWAY_NAME = "t1";
+
@Mock
private Function<Class<? extends Service>, Service> nsxService;
@Mock
@@ -108,4 +139,284 @@ public class NsxApiClientTest {
Mockito.when(clusterStatus.getControlClusterStatus()).thenReturn(status);
Assert.assertTrue(client.isNsxControllerActive());
}
+
+ @Test
+ public void
testCreateNsxLbServerPoolExistingMonitorProfileSkipsMonitorPatch() {
+ String lbServerPoolName =
NsxControllerUtils.getServerPoolName(TIER_1_GATEWAY_NAME, 1L);
+ List<NsxLoadBalancerMember> memberList = List.of(new
NsxLoadBalancerMember(1L, "10.0.0.1", 80));
+
+ LbPools lbPools = Mockito.mock(LbPools.class);
+ LbMonitorProfiles lbMonitorProfiles = mockLbMonitorProfiles();
+
+ Mockito.when(nsxService.apply(LbPools.class)).thenReturn(lbPools);
+ Mockito.when(lbPools.get(lbServerPoolName)).thenThrow(new
NotFound(null, null));
+
+ client.createNsxLbServerPool(memberList, TIER_1_GATEWAY_NAME,
lbServerPoolName, "roundrobin", "80", "TCP");
+
+ verify(lbMonitorProfiles, never()).patch(anyString(),
any(LBTcpMonitorProfile.class));
+ verify(lbPools).patch(eq(lbServerPoolName), any(LBPool.class));
+ }
+
+ @Test
+ public void
testCreateNsxLbServerPoolMissingMonitorTCPProfilePerformsPatch() {
+ String lbServerPoolName =
NsxControllerUtils.getServerPoolName(TIER_1_GATEWAY_NAME, 1L);
+ List<NsxLoadBalancerMember> memberList = List.of(new
NsxLoadBalancerMember(1L, "10.0.0.1", 80));
+
+ LbPools lbPools = Mockito.mock(LbPools.class);
+ LbMonitorProfiles lbMonitorProfiles =
Mockito.mock(LbMonitorProfiles.class);
+ Structure monitorStructure = Mockito.mock(Structure.class,
Mockito.RETURNS_DEEP_STUBS);
+
+ Mockito.when(nsxService.apply(LbPools.class)).thenReturn(lbPools);
+
Mockito.when(nsxService.apply(LbMonitorProfiles.class)).thenReturn(lbMonitorProfiles);
+ Mockito.when(lbMonitorProfiles.get(anyString())).thenThrow(new
NotFound(null, null)).thenReturn(monitorStructure);
+
Mockito.when(monitorStructure._getDataValue().getField("path").toString()).thenReturn("/infra/lb-monitor-profiles/test");
+ Mockito.when(lbPools.get(lbServerPoolName)).thenThrow(new
NotFound(null, null));
+
+ client.createNsxLbServerPool(memberList, TIER_1_GATEWAY_NAME,
lbServerPoolName, "roundrobin", "80", "TCP");
+
+ verify(lbMonitorProfiles).patch(anyString(),
any(LBTcpMonitorProfile.class));
+ verify(lbPools).patch(eq(lbServerPoolName), any(LBPool.class));
+ }
+
+ @Test
+ public void
testCreateNsxLbServerPoolMissingMonitorUDPProfilePerformsPatch() {
+ String lbServerPoolName =
NsxControllerUtils.getServerPoolName(TIER_1_GATEWAY_NAME, 1L);
+ List<NsxLoadBalancerMember> memberList = List.of(new
NsxLoadBalancerMember(1L, "10.0.0.1", 80));
+
+ LbPools lbPools = Mockito.mock(LbPools.class);
+ LbMonitorProfiles lbMonitorProfiles =
Mockito.mock(LbMonitorProfiles.class);
+ Structure monitorStructure = Mockito.mock(Structure.class,
Mockito.RETURNS_DEEP_STUBS);
+
+ Mockito.when(nsxService.apply(LbPools.class)).thenReturn(lbPools);
+
Mockito.when(nsxService.apply(LbMonitorProfiles.class)).thenReturn(lbMonitorProfiles);
+ Mockito.when(lbMonitorProfiles.get(anyString())).thenThrow(new
NotFound(null, null)).thenReturn(monitorStructure);
+
Mockito.when(monitorStructure._getDataValue().getField("path").toString()).thenReturn("/infra/lb-monitor-profiles/test");
+ Mockito.when(lbPools.get(lbServerPoolName)).thenThrow(new
NotFound(null, null));
+
+ client.createNsxLbServerPool(memberList, TIER_1_GATEWAY_NAME,
lbServerPoolName, "roundrobin", "80", "UDP");
+
+ verify(lbMonitorProfiles).patch(anyString(),
any(LBIcmpMonitorProfile.class));
+ verify(lbPools).patch(eq(lbServerPoolName), any(LBPool.class));
+ }
+
+ @Test
+ public void testCreateNsxLbServerPoolPoolExistsWithSameMembersSkipsPatch()
{
+ long lbId = 1L;
+ String lbServerPoolName =
NsxControllerUtils.getServerPoolName(TIER_1_GATEWAY_NAME, lbId);
+ List<NsxLoadBalancerMember> memberList = List.of(
+ new NsxLoadBalancerMember(1L, "10.0.0.1", 80),
+ new NsxLoadBalancerMember(2L, "10.0.0.2", 80)
+ );
+ List<LBPoolMember> sameMembers = List.of(
+ createPoolMember(2L, "10.0.0.2", 80),
+ createPoolMember(1L, "10.0.0.1", 80)
+ );
+
+ LbPools lbPools = Mockito.mock(LbPools.class);
+ LBPool existingPool = Mockito.mock(LBPool.class);
+
+ Mockito.when(nsxService.apply(LbPools.class)).thenReturn(lbPools);
+ Mockito.when(lbPools.get(lbServerPoolName)).thenReturn(existingPool);
+ Mockito.when(existingPool.getMembers()).thenReturn(sameMembers);
+
+ client.createNsxLbServerPool(memberList, TIER_1_GATEWAY_NAME,
lbServerPoolName, "roundrobin", "80", "TCP");
+
+ verify(nsxService, never()).apply(LbMonitorProfiles.class);
+ verify(lbPools, never()).patch(anyString(), any(LBPool.class));
+ }
+
+ @Test
+ public void
testCreateNsxLbServerPoolPoolExistsWithoutMembersAndEmptyUpdateSkipsPatch() {
+ String lbServerPoolName =
NsxControllerUtils.getServerPoolName(TIER_1_GATEWAY_NAME, 1L);
+
+ LbPools lbPools = Mockito.mock(LbPools.class);
+ LBPool existingPool = Mockito.mock(LBPool.class);
+
+ Mockito.when(nsxService.apply(LbPools.class)).thenReturn(lbPools);
+ Mockito.when(lbPools.get(lbServerPoolName)).thenReturn(existingPool);
+ Mockito.when(existingPool.getMembers()).thenReturn(null);
+
+ client.createNsxLbServerPool(List.of(), TIER_1_GATEWAY_NAME,
lbServerPoolName, "roundrobin", "80", "TCP");
+
+ verify(nsxService, never()).apply(LbMonitorProfiles.class);
+ verify(lbPools, never()).patch(anyString(), any(LBPool.class));
+ }
+
+ @Test
+ public void
testCreateNsxLbServerPoolPoolExistsWithDuplicateMembersSkipsPatch() {
+ long lbId = 1L;
+ String lbServerPoolName =
NsxControllerUtils.getServerPoolName(TIER_1_GATEWAY_NAME, lbId);
+ List<NsxLoadBalancerMember> memberList = List.of(
+ new NsxLoadBalancerMember(1L, "10.0.0.1", 80),
+ new NsxLoadBalancerMember(2L, "10.0.0.2", 80)
+ );
+
+ LbPools lbPools = Mockito.mock(LbPools.class);
+ LBPool existingPool = Mockito.mock(LBPool.class);
+
+ Mockito.when(nsxService.apply(LbPools.class)).thenReturn(lbPools);
+ Mockito.when(lbPools.get(lbServerPoolName)).thenReturn(existingPool);
+ Mockito.when(existingPool.getMembers()).thenReturn(List.of(
+ createPoolMember(1L, "10.0.0.1", 80),
+ createPoolMember(1L, "10.0.0.1", 80),
+ createPoolMember(2L, "10.0.0.2", 80)
+ ));
+
+ client.createNsxLbServerPool(memberList, TIER_1_GATEWAY_NAME,
lbServerPoolName, "roundrobin", "80", "TCP");
+
+ verify(nsxService, never()).apply(LbMonitorProfiles.class);
+ verify(lbPools, never()).patch(anyString(), any(LBPool.class));
+ }
+
+ @Test
+ public void
testCreateNsxLbServerPoolPoolExistsWithDifferentMembersPerformsPatch() {
+ long lbId = 1L;
+ String lbServerPoolName =
NsxControllerUtils.getServerPoolName(TIER_1_GATEWAY_NAME, lbId);
+ List<NsxLoadBalancerMember> memberList = List.of(
+ new NsxLoadBalancerMember(1L, "10.0.0.1", 80),
+ new NsxLoadBalancerMember(2L, "10.0.0.2", 80)
+ );
+
+ LbPools lbPools = Mockito.mock(LbPools.class);
+ LBPool existingPool = Mockito.mock(LBPool.class);
+
+ mockLbMonitorProfiles();
+ Mockito.when(nsxService.apply(LbPools.class)).thenReturn(lbPools);
+ Mockito.when(lbPools.get(lbServerPoolName)).thenReturn(existingPool);
+ Mockito.when(existingPool.getMembers()).thenReturn(List.of(
+ createPoolMember(1L, "10.0.0.10", 80)
+ ));
+
+ client.createNsxLbServerPool(memberList, TIER_1_GATEWAY_NAME,
lbServerPoolName, "roundrobin", "80", "TCP");
+
+ verify(lbPools).patch(eq(lbServerPoolName), any(LBPool.class));
+ }
+
+ @Test
+ public void testCreateNsxLbServerPoolPoolDoesNotExistPerformsPatch() {
+ String lbServerPoolName =
NsxControllerUtils.getServerPoolName(TIER_1_GATEWAY_NAME, 1L);
+ List<NsxLoadBalancerMember> memberList = List.of(new
NsxLoadBalancerMember(1L, "10.0.0.1", 80));
+
+ LbPools lbPools = Mockito.mock(LbPools.class);
+
+ mockLbMonitorProfiles();
+ Mockito.when(nsxService.apply(LbPools.class)).thenReturn(lbPools);
+ Mockito.when(lbPools.get(lbServerPoolName)).thenThrow(new
NotFound(null, null));
+
+ client.createNsxLbServerPool(memberList, TIER_1_GATEWAY_NAME,
lbServerPoolName, "roundrobin", "80", "TCP");
+
+ verify(lbPools).patch(eq(lbServerPoolName), any(LBPool.class));
+ }
+
+ @Test
+ public void
testCreateAndAddNsxLbVirtualServerVirtualServerAlreadyExistsSkipsPatch() {
+ long lbId = 1L;
+ String lbVirtualServerName =
NsxControllerUtils.getVirtualServerName(TIER_1_GATEWAY_NAME, lbId);
+ String lbServiceName =
NsxControllerUtils.getLoadBalancerName(TIER_1_GATEWAY_NAME);
+ List<NsxLoadBalancerMember> memberList = List.of(new
NsxLoadBalancerMember(1L, "10.0.0.1", 80));
+
+ LbPools lbPools = Mockito.mock(LbPools.class);
+ LbServices lbServices = Mockito.mock(LbServices.class);
+ LbVirtualServers lbVirtualServers =
Mockito.mock(LbVirtualServers.class);
+ LBVirtualServer existingVs = Mockito.mock(LBVirtualServer.class);
+
+ mockLbMonitorProfiles();
+ Mockito.when(nsxService.apply(LbPools.class)).thenReturn(lbPools);
+
Mockito.when(nsxService.apply(LbServices.class)).thenReturn(lbServices);
+
Mockito.when(nsxService.apply(LbVirtualServers.class)).thenReturn(lbVirtualServers);
+ Mockito.when(lbPools.get(anyString())).thenThrow(new NotFound(null,
null));
+ Mockito.when(lbServices.get(anyString())).thenReturn(null);
+
Mockito.when(lbVirtualServers.get(lbVirtualServerName)).thenReturn(existingVs);
+
+ client.createAndAddNsxLbVirtualServer(TIER_1_GATEWAY_NAME, lbId,
"192.168.1.1", "443",
+ memberList, "roundrobin", "TCP", "80");
+
+ verify(lbVirtualServers).get(lbVirtualServerName);
+ verify(lbVirtualServers, never()).get(lbServiceName);
+ verify(lbVirtualServers, never()).patch(anyString(),
any(LBVirtualServer.class));
+ }
+
+ @Test
+ public void
testCreateAndAddNsxLbVirtualServerVirtualServerNotFoundPerformsPatch() {
+ long lbId = 1L;
+ String lbServerPoolName =
NsxControllerUtils.getServerPoolName(TIER_1_GATEWAY_NAME, lbId);
+ String lbVirtualServerName =
NsxControllerUtils.getVirtualServerName(TIER_1_GATEWAY_NAME, lbId);
+ String lbServiceName =
NsxControllerUtils.getLoadBalancerName(TIER_1_GATEWAY_NAME);
+ List<NsxLoadBalancerMember> memberList = List.of(new
NsxLoadBalancerMember(1L, "10.0.0.1", 80));
+
+ LbPools lbPools = Mockito.mock(LbPools.class);
+ LBPool lbPool = Mockito.mock(LBPool.class);
+ LbServices lbServices = Mockito.mock(LbServices.class);
+ LBService lbService = Mockito.mock(LBService.class);
+ LbVirtualServers lbVirtualServers =
Mockito.mock(LbVirtualServers.class);
+
+ mockLbMonitorProfiles();
+ mockLbAppProfiles();
+ Mockito.when(nsxService.apply(LbPools.class)).thenReturn(lbPools);
+
Mockito.when(nsxService.apply(LbServices.class)).thenReturn(lbServices);
+
Mockito.when(nsxService.apply(LbVirtualServers.class)).thenReturn(lbVirtualServers);
+ Mockito.when(lbPools.get(lbServerPoolName)).thenThrow(new
NotFound(null, null)).thenReturn(lbPool);
+ Mockito.when(lbPool.getPath()).thenReturn("/infra/lb-pools/" +
lbServerPoolName);
+ Mockito.when(lbServices.get(lbServiceName)).thenReturn(lbService);
+ Mockito.when(lbService.getPath()).thenReturn("/infra/lb-services/" +
lbServiceName);
+ Mockito.when(lbVirtualServers.get(lbVirtualServerName)).thenThrow(new
NotFound(null, null));
+
+ client.createAndAddNsxLbVirtualServer(TIER_1_GATEWAY_NAME, lbId,
"192.168.1.1", "443",
+ memberList, "roundrobin", "TCP", "80");
+
+ verify(lbVirtualServers).get(lbVirtualServerName);
+ verify(lbVirtualServers, never()).get(lbServiceName);
+ verify(lbVirtualServers).patch(eq(lbVirtualServerName),
any(LBVirtualServer.class));
+ }
+
+ @Test
+ public void testCreateNsxLbServerPoolThrowsExceptionOnPatchError() {
+ String lbServerPoolName =
NsxControllerUtils.getServerPoolName(TIER_1_GATEWAY_NAME, 1L);
+ List<NsxLoadBalancerMember> memberList = List.of(new
NsxLoadBalancerMember(1L, "10.0.0.1", 80));
+
+ LbPools lbPools = Mockito.mock(LbPools.class);
+ Structure errorData = Mockito.mock(Structure.class);
+ ApiError apiError = new ApiError();
+ apiError.setErrorData(errorData);
+
+ mockLbMonitorProfiles();
+ Mockito.when(nsxService.apply(LbPools.class)).thenReturn(lbPools);
+ Mockito.when(lbPools.get(lbServerPoolName)).thenThrow(new
NotFound(null, null));
+ when(errorData._convertTo(ApiError.class)).thenReturn(apiError);
+ doThrow(new Error(List.of(),
errorData)).when(lbPools).patch(eq(lbServerPoolName), any(LBPool.class));
+
+ CloudRuntimeException thrownException =
assertThrows(CloudRuntimeException.class, () -> {
+ client.createNsxLbServerPool(memberList, TIER_1_GATEWAY_NAME,
lbServerPoolName, "roundrobin", "80", "TCP");
+ });
+ assertTrue(thrownException.getMessage().startsWith("Failed to create
NSX LB server pool, due to"));
+ }
+
+ private LbMonitorProfiles mockLbMonitorProfiles() {
+ LbMonitorProfiles lbMonitorProfiles =
Mockito.mock(LbMonitorProfiles.class);
+ Structure monitorStructure = Mockito.mock(Structure.class,
Mockito.RETURNS_DEEP_STUBS);
+
+
Mockito.when(nsxService.apply(LbMonitorProfiles.class)).thenReturn(lbMonitorProfiles);
+
Mockito.when(lbMonitorProfiles.get(anyString())).thenReturn(monitorStructure);
+
Mockito.when(monitorStructure._getDataValue().getField("path").toString()).thenReturn("/infra/lb-monitor-profiles/test");
+ return lbMonitorProfiles;
+ }
+
+ private void mockLbAppProfiles() {
+ LbAppProfiles lbAppProfiles = Mockito.mock(LbAppProfiles.class);
+ LBAppProfileListResult appProfileListResult =
Mockito.mock(LBAppProfileListResult.class);
+ Structure appProfile = Mockito.mock(Structure.class,
Mockito.RETURNS_DEEP_STUBS);
+
+
Mockito.when(nsxService.apply(LbAppProfiles.class)).thenReturn(lbAppProfiles);
+ Mockito.when(lbAppProfiles.list(null, null, null, null, null,
null)).thenReturn(appProfileListResult);
+
Mockito.when(appProfileListResult.getResults()).thenReturn(List.of(appProfile));
+
Mockito.when(appProfile._getDataValue().getField("path").toString()).thenReturn("/infra/lb-app-profiles/default-tcp-profile");
+ }
+
+ private LBPoolMember createPoolMember(long vmId, String ipAddress, int
port) {
+ return new LBPoolMember.Builder()
+
.setDisplayName(NsxControllerUtils.getServerPoolMemberName(TIER_1_GATEWAY_NAME,
vmId))
+ .setIpAddress(ipAddress)
+ .setPort(String.valueOf(port))
+ .build();
+ }
}