8383import com .vmware .vapi .internal .protocol .client .rest .authn .BasicAuthenticationAppender ;
8484import com .vmware .vapi .protocol .HttpConfiguration ;
8585import com .vmware .vapi .std .errors .Error ;
86+ import com .vmware .vapi .std .errors .NotFound ;
8687import org .apache .cloudstack .resource .NsxLoadBalancerMember ;
8788import org .apache .cloudstack .resource .NsxNetworkRule ;
8889import org .apache .cloudstack .utils .NsxControllerUtils ;
9697import java .util .Locale ;
9798import java .util .Objects ;
9899import java .util .Optional ;
100+ import java .util .Set ;
99101import java .util .function .Function ;
100102import java .util .stream .Collectors ;
101103
104+ import static java .util .stream .Collectors .toSet ;
102105import static org .apache .cloudstack .utils .NsxControllerUtils .getServerPoolMemberName ;
103106import static org .apache .cloudstack .utils .NsxControllerUtils .getServerPoolName ;
104107import static org .apache .cloudstack .utils .NsxControllerUtils .getServiceName ;
@@ -656,9 +659,19 @@ List<LBPoolMember> getLbPoolMembers(List<NsxLoadBalancerMember> memberList, Stri
656659 public void createNsxLbServerPool (List <NsxLoadBalancerMember > memberList , String tier1GatewayName , String lbServerPoolName ,
657660 String algorithm , String privatePort , String protocol ) {
658661 try {
659- String activeMonitorPath = getLbActiveMonitorPath (lbServerPoolName , privatePort , protocol );
660662 List <LBPoolMember > members = getLbPoolMembers (memberList , tier1GatewayName );
661663 LbPools lbPools = (LbPools ) nsxService .apply (LbPools .class );
664+ Optional <LBPool > nsxLbServerPool = getNsxLbServerPool (lbPools , lbServerPoolName );
665+ // Skip if pool exists and members unchanged
666+ if (nsxLbServerPool .isPresent ()) {
667+ List <LBPoolMember > existingMembers = nsxLbServerPool
668+ .map (LBPool ::getMembers )
669+ .orElseGet (List ::of );
670+ if (hasSamePoolMembers (existingMembers , members )) {
671+ return ;
672+ }
673+ }
674+ String activeMonitorPath = getLbActiveMonitorPath (lbServerPoolName , privatePort , protocol );
662675 LBPool lbPool = new LBPool .Builder ()
663676 .setId (lbServerPoolName )
664677 .setDisplayName (lbServerPoolName )
@@ -676,27 +689,62 @@ public void createNsxLbServerPool(List<NsxLoadBalancerMember> memberList, String
676689 }
677690 }
678691
692+ private Optional <LBPool > getNsxLbServerPool (LbPools lbPools , String lbServerPoolName ) {
693+ try {
694+ return Optional .ofNullable (lbPools .get (lbServerPoolName ));
695+ } catch (NotFound e ) {
696+ logger .debug ("Server Pool not found: {}" , lbServerPoolName );
697+ return Optional .empty ();
698+ }
699+ }
700+
701+ private boolean hasSamePoolMembers (List <LBPoolMember > existingMembers , List <LBPoolMember > membersUpdate ) {
702+ Set <String > existingMembersSet = existingMembers .stream ()
703+ .map (this ::buildPoolMemberKey )
704+ .collect (toSet ());
705+ Set <String > updateMembersSet = membersUpdate .stream ()
706+ .map (this ::buildPoolMemberKey )
707+ .collect (toSet ());
708+
709+ return existingMembersSet .size () == updateMembersSet .size ()
710+ && existingMembersSet .containsAll (updateMembersSet );
711+ }
712+
713+ private String buildPoolMemberKey (LBPoolMember member ) {
714+ return member .getIpAddress () + ':' + member .getPort () + ':' + member .getDisplayName ();
715+ }
716+
679717 private String getLbActiveMonitorPath (String lbServerPoolName , String port , String protocol ) {
680718 LbMonitorProfiles lbActiveMonitor = (LbMonitorProfiles ) nsxService .apply (LbMonitorProfiles .class );
681719 String lbMonitorProfileId = getActiveMonitorProfileName (lbServerPoolName , port , protocol );
682- if ("TCP" .equals (protocol .toUpperCase (Locale .ROOT ))) {
683- LBTcpMonitorProfile lbTcpMonitorProfile = new LBTcpMonitorProfile .Builder (TCP_MONITOR_PROFILE )
684- .setDisplayName (lbMonitorProfileId )
685- .setMonitorPort (Long .parseLong (port ))
686- .build ();
687- lbActiveMonitor .patch (lbMonitorProfileId , lbTcpMonitorProfile );
688- } else if ("UDP" .equals (protocol .toUpperCase (Locale .ROOT ))) {
689- LBIcmpMonitorProfile icmpMonitorProfile = new LBIcmpMonitorProfile .Builder (ICMP_MONITOR_PROFILE )
690- .setDisplayName (lbMonitorProfileId )
691- .build ();
692- lbActiveMonitor .patch (lbMonitorProfileId , icmpMonitorProfile );
720+ Optional <Structure > monitorProfile = getMonitorProfile (lbActiveMonitor , lbMonitorProfileId );
721+ if (monitorProfile .isEmpty ()) {
722+ if ("TCP" .equals (protocol .toUpperCase (Locale .ROOT ))) {
723+ LBTcpMonitorProfile lbTcpMonitorProfile = new LBTcpMonitorProfile .Builder (TCP_MONITOR_PROFILE )
724+ .setDisplayName (lbMonitorProfileId )
725+ .setMonitorPort (Long .parseLong (port ))
726+ .build ();
727+ lbActiveMonitor .patch (lbMonitorProfileId , lbTcpMonitorProfile );
728+ } else if ("UDP" .equals (protocol .toUpperCase (Locale .ROOT ))) {
729+ LBIcmpMonitorProfile icmpMonitorProfile = new LBIcmpMonitorProfile .Builder (ICMP_MONITOR_PROFILE )
730+ .setDisplayName (lbMonitorProfileId )
731+ .build ();
732+ lbActiveMonitor .patch (lbMonitorProfileId , icmpMonitorProfile );
733+ }
734+ monitorProfile = getMonitorProfile (lbActiveMonitor , lbMonitorProfileId );
693735 }
694-
695- LBMonitorProfileListResult listResult = listLBActiveMonitors (lbActiveMonitor );
696- Optional <Structure > monitorProfile = listResult .getResults ().stream ().filter (profile -> profile ._getDataValue ().getField ("id" ).toString ().equals (lbMonitorProfileId )).findFirst ();
697736 return monitorProfile .map (structure -> structure ._getDataValue ().getField ("path" ).toString ()).orElse (null );
698737 }
699738
739+ private Optional <Structure > getMonitorProfile (LbMonitorProfiles lbActiveMonitor , String lbMonitorProfileId ) {
740+ try {
741+ return Optional .ofNullable (lbActiveMonitor .get (lbMonitorProfileId ));
742+ } catch (NotFound e ) {
743+ logger .debug ("LB Monitor Profile not found: {}" , lbMonitorProfileId );
744+ return Optional .empty ();
745+ }
746+ }
747+
700748 LBMonitorProfileListResult listLBActiveMonitors (LbMonitorProfiles lbActiveMonitor ) {
701749 return lbActiveMonitor .list (null , false , null , null , null , null );
702750 }
@@ -735,7 +783,7 @@ public void createAndAddNsxLbVirtualServer(String tier1GatewayName, long lbId, S
735783 String lbVirtualServerName = getVirtualServerName (tier1GatewayName , lbId );
736784 String lbServiceName = getLoadBalancerName (tier1GatewayName );
737785 LbVirtualServers lbVirtualServers = (LbVirtualServers ) nsxService .apply (LbVirtualServers .class );
738- if (Objects .nonNull (getLbVirtualServerService (lbVirtualServers , lbServiceName ))) {
786+ if (Objects .nonNull (getLbVirtualServerService (lbVirtualServers , lbVirtualServerName ))) {
739787 return ;
740788 }
741789 LBVirtualServer lbVirtualServer = new LBVirtualServer .Builder ()
0 commit comments