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,20 @@ 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+ logger .debug ("Skipping patch for LB pool {} on Tier-1 {}: members unchanged" , lbServerPoolName , tier1GatewayName );
672+ return ;
673+ }
674+ }
675+ String activeMonitorPath = getLbActiveMonitorPath (lbServerPoolName , privatePort , protocol );
662676 LBPool lbPool = new LBPool .Builder ()
663677 .setId (lbServerPoolName )
664678 .setDisplayName (lbServerPoolName )
@@ -676,9 +690,52 @@ public void createNsxLbServerPool(List<NsxLoadBalancerMember> memberList, String
676690 }
677691 }
678692
693+ private Optional <LBPool > getNsxLbServerPool (LbPools lbPools , String lbServerPoolName ) {
694+ try {
695+ return Optional .ofNullable (lbPools .get (lbServerPoolName ));
696+ } catch (NotFound e ) {
697+ logger .warn ("Server Pool not found: {}" , lbServerPoolName );
698+ return Optional .empty ();
699+ }
700+ }
701+
702+ private boolean hasSamePoolMembers (List <LBPoolMember > existingMembers , List <LBPoolMember > membersUpdate ) {
703+ Set <String > existingMembersSet = existingMembers .stream ()
704+ .map (this ::buildPoolMemberKey )
705+ .collect (toSet ());
706+ Set <String > updateMembersSet = membersUpdate .stream ()
707+ .map (this ::buildPoolMemberKey )
708+ .collect (toSet ());
709+
710+ return existingMembersSet .size () == updateMembersSet .size ()
711+ && existingMembersSet .containsAll (updateMembersSet );
712+ }
713+
714+ private String buildPoolMemberKey (LBPoolMember member ) {
715+ return member .getIpAddress () + ':' + member .getPort () + ':' + member .getDisplayName ();
716+ }
717+
679718 private String getLbActiveMonitorPath (String lbServerPoolName , String port , String protocol ) {
680719 LbMonitorProfiles lbActiveMonitor = (LbMonitorProfiles ) nsxService .apply (LbMonitorProfiles .class );
681720 String lbMonitorProfileId = getActiveMonitorProfileName (lbServerPoolName , port , protocol );
721+ Optional <Structure > monitorProfile = getMonitorProfile (lbActiveMonitor , lbMonitorProfileId );
722+ if (monitorProfile .isEmpty ()) {
723+ patchMonitoringProfile (port , protocol , lbMonitorProfileId , lbActiveMonitor );
724+ monitorProfile = getMonitorProfile (lbActiveMonitor , lbMonitorProfileId );
725+ }
726+ return monitorProfile .map (structure -> structure ._getDataValue ().getField ("path" ).toString ()).orElse (null );
727+ }
728+
729+ private Optional <Structure > getMonitorProfile (LbMonitorProfiles lbActiveMonitor , String lbMonitorProfileId ) {
730+ try {
731+ return Optional .ofNullable (lbActiveMonitor .get (lbMonitorProfileId ));
732+ } catch (NotFound e ) {
733+ logger .warn ("LB Monitor Profile not found: {}" , lbMonitorProfileId );
734+ return Optional .empty ();
735+ }
736+ }
737+
738+ private void patchMonitoringProfile (String port , String protocol , String lbMonitorProfileId , LbMonitorProfiles lbActiveMonitor ) {
682739 if ("TCP" .equals (protocol .toUpperCase (Locale .ROOT ))) {
683740 LBTcpMonitorProfile lbTcpMonitorProfile = new LBTcpMonitorProfile .Builder (TCP_MONITOR_PROFILE )
684741 .setDisplayName (lbMonitorProfileId )
@@ -691,10 +748,6 @@ private String getLbActiveMonitorPath(String lbServerPoolName, String port, Stri
691748 .build ();
692749 lbActiveMonitor .patch (lbMonitorProfileId , icmpMonitorProfile );
693750 }
694-
695- LBMonitorProfileListResult listResult = listLBActiveMonitors (lbActiveMonitor );
696- Optional <Structure > monitorProfile = listResult .getResults ().stream ().filter (profile -> profile ._getDataValue ().getField ("id" ).toString ().equals (lbMonitorProfileId )).findFirst ();
697- return monitorProfile .map (structure -> structure ._getDataValue ().getField ("path" ).toString ()).orElse (null );
698751 }
699752
700753 LBMonitorProfileListResult listLBActiveMonitors (LbMonitorProfiles lbActiveMonitor ) {
@@ -735,7 +788,7 @@ public void createAndAddNsxLbVirtualServer(String tier1GatewayName, long lbId, S
735788 String lbVirtualServerName = getVirtualServerName (tier1GatewayName , lbId );
736789 String lbServiceName = getLoadBalancerName (tier1GatewayName );
737790 LbVirtualServers lbVirtualServers = (LbVirtualServers ) nsxService .apply (LbVirtualServers .class );
738- if (Objects .nonNull (getLbVirtualServerService (lbVirtualServers , lbServiceName ))) {
791+ if (Objects .nonNull (getLbVirtualServerService (lbVirtualServers , lbVirtualServerName ))) {
739792 return ;
740793 }
741794 LBVirtualServer lbVirtualServer = new LBVirtualServer .Builder ()
0 commit comments