From 071bf3c52c119420c5f34174dfac9f3edde0ce1b Mon Sep 17 00:00:00 2001 From: Thushani Jayasekera Date: Wed, 11 Dec 2024 16:52:00 +0530 Subject: [PATCH 01/11] set circuitbreaker if org is paid --- adapter/internal/api/apis_impl.go | 5 +++-- adapter/internal/discovery/xds/server.go | 6 +++--- adapter/internal/oasparser/model/mgw_swagger.go | 12 +++++++----- adapter/internal/oasparser/model/types.go | 9 +++++---- adapter/internal/synchronizer/apis_fetcher.go | 6 ++++-- adapter/pkg/synchronizer/types.go | 15 ++++++++++++--- 6 files changed, 34 insertions(+), 19 deletions(-) diff --git a/adapter/internal/api/apis_impl.go b/adapter/internal/api/apis_impl.go index 585702ab43..deeec450a7 100644 --- a/adapter/internal/api/apis_impl.go +++ b/adapter/internal/api/apis_impl.go @@ -223,7 +223,7 @@ func validateAndUpdateXds(apiProject mgw.ProjectAPI, override *bool) (err error) // TODO: (renuka) optimize to update cache only once when all internal memory maps are updated for vhost, environments := range vhostToEnvsMap { - _, err = xds.UpdateAPI(vhost, apiProject, environments, common.XdsOptions{}) + _, err = xds.UpdateAPI(vhost, apiProject, environments, common.XdsOptions{}, synchronizer.ChoreoComponentInfo{}) if err != nil { return } @@ -238,6 +238,7 @@ func ApplyAPIProjectFromAPIM( vhostToEnvsMap map[string][]*synchronizer.GatewayLabel, apiEnvs map[string]map[string]synchronizer.APIEnvProps, xdsOptions common.XdsOptions, + choreoComponentInfo synchronizer.ChoreoComponentInfo, ) (deployedRevisionList []*notifier.DeployedAPIRevision, err error) { apiProject, err := extractAPIProject(payload) if err != nil { @@ -283,7 +284,7 @@ func ApplyAPIProjectFromAPIM( loggers.LoggerAPI.Debugf("Update all environments (%v) of API %v %v:%v with UUID \"%v\".", environments, vhost, apiYaml.Name, apiYaml.Version, apiYaml.ID) // first update the API for vhost - deployedRevision, err := xds.UpdateAPI(vhost, apiProject, environments, xdsOptions) + deployedRevision, err := xds.UpdateAPI(vhost, apiProject, environments, xdsOptions, choreoComponentInfo) if err != nil { return deployedRevisionList, fmt.Errorf("%v:%v with UUID \"%v\"", apiYaml.Name, apiYaml.Version, apiYaml.ID) } diff --git a/adapter/internal/discovery/xds/server.go b/adapter/internal/discovery/xds/server.go index f48de56534..b5b1a8fe22 100644 --- a/adapter/internal/discovery/xds/server.go +++ b/adapter/internal/discovery/xds/server.go @@ -273,7 +273,7 @@ func DeployReadinessAPI(envs []string) { // UpdateAPI updates the Xds Cache when OpenAPI Json content is provided func UpdateAPI(vHost string, apiProject mgw.ProjectAPI, deployedEnvironments []*synchronizer.GatewayLabel, - xdsOptions common.XdsOptions) (*notifier.DeployedAPIRevision, error) { + xdsOptions common.XdsOptions, apiChoreoComponentInfo synchronizer.ChoreoComponentInfo) (*notifier.DeployedAPIRevision, error) { var mgwSwagger mgw.MgwSwagger var deployedRevision *notifier.DeployedAPIRevision @@ -372,14 +372,14 @@ func UpdateAPI(vHost string, apiProject mgw.ProjectAPI, deployedEnvironments []* apiHashValue := generateHashValue(apiYaml.Name, apiYaml.Version) if mgwSwagger.GetProdEndpoints() != nil { - mgwSwagger.GetProdEndpoints().SetEndpointsConfig(apiYaml.EndpointConfig.ProductionEndpoints, apiYaml.EndpointConfig.EndpointType, apiYaml.OrganizationID) + mgwSwagger.GetProdEndpoints().SetEndpointsConfig(apiYaml.EndpointConfig.ProductionEndpoints, apiYaml.EndpointConfig.EndpointType, apiYaml.OrganizationID, apiChoreoComponentInfo.IsChoreoOrgPaid) if !mgwSwagger.GetProdEndpoints().SecurityConfig.Enabled && apiYaml.EndpointConfig.APIEndpointSecurity.Production.Enabled { mgwSwagger.GetProdEndpoints().SecurityConfig = apiYaml.EndpointConfig.APIEndpointSecurity.Production } } if mgwSwagger.GetSandEndpoints() != nil { - mgwSwagger.GetSandEndpoints().SetEndpointsConfig(apiYaml.EndpointConfig.SandBoxEndpoints, apiYaml.EndpointConfig.EndpointType, apiYaml.OrganizationID) + mgwSwagger.GetSandEndpoints().SetEndpointsConfig(apiYaml.EndpointConfig.SandBoxEndpoints, apiYaml.EndpointConfig.EndpointType, apiYaml.OrganizationID, apiChoreoComponentInfo.IsChoreoOrgPaid) if !mgwSwagger.GetSandEndpoints().SecurityConfig.Enabled && apiYaml.EndpointConfig.APIEndpointSecurity.Sandbox.Enabled { mgwSwagger.GetSandEndpoints().SecurityConfig = apiYaml.EndpointConfig.APIEndpointSecurity.Sandbox } diff --git a/adapter/internal/oasparser/model/mgw_swagger.go b/adapter/internal/oasparser/model/mgw_swagger.go index 8841258058..a7bccc425c 100644 --- a/adapter/internal/oasparser/model/mgw_swagger.go +++ b/adapter/internal/oasparser/model/mgw_swagger.go @@ -77,10 +77,11 @@ type MgwSwagger struct { // ChoreoComponentInfo represents the information of the Choreo component type ChoreoComponentInfo struct { - OrganizationID string - ProjectID string - ComponentID string - VersionID string + OrganizationID string + ProjectID string + ComponentID string + VersionID string + IsChoreoOrgPaid bool } // EndpointCluster represent an upstream cluster @@ -643,7 +644,7 @@ func (swagger *MgwSwagger) setXWso2Endpoints() error { } // SetEndpointsConfig set configs for Endpoints sent by api.yaml -func (endpointCluster *EndpointCluster) SetEndpointsConfig(endpointInfos []EndpointInfo, apiType string, orgID string) error { +func (endpointCluster *EndpointCluster) SetEndpointsConfig(endpointInfos []EndpointInfo, apiType string, orgID string, isChoreoOrgPaid bool) error { if endpointInfos == nil || len(endpointInfos) == 0 { return nil } @@ -685,6 +686,7 @@ func (endpointCluster *EndpointCluster) SetEndpointsConfig(endpointInfos []Endpo var selectedCircuitBreaker *CircuitBreakers for _, circuitBreaker := range conf.Envoy.Upstream.CircuitBreakers { + // check ispaidorg from here if utills.GetIsOrganizationInList(orgID, circuitBreaker.Organizations) { selectedCircuitBreaker = createCircuitBreaker( circuitBreaker.MaxConnections, diff --git a/adapter/internal/oasparser/model/types.go b/adapter/internal/oasparser/model/types.go index 5e504a6e80..ee03dd4331 100644 --- a/adapter/internal/oasparser/model/types.go +++ b/adapter/internal/oasparser/model/types.go @@ -152,10 +152,11 @@ type apiData struct { } type choreoComponentInfo struct { - OrganizationID string `json:"organizationId,omitempty"` - ProjectID string `json:"projectId,omitempty"` - ComponentID string `json:"componentId,omitempty"` - VersionID string `json:"versionId,omitempty"` + OrganizationID string `json:"organizationId,omitempty"` + ProjectID string `json:"projectId,omitempty"` + ComponentID string `json:"componentId,omitempty"` + VersionID string `json:"versionId,omitempty"` + IsChoreoOrgPaid bool `json:"isChoreoOrgPaid,omitempty"` } type backendJWTConfiguration struct { diff --git a/adapter/internal/synchronizer/apis_fetcher.go b/adapter/internal/synchronizer/apis_fetcher.go index c79235b59d..0c6f56a06d 100644 --- a/adapter/internal/synchronizer/apis_fetcher.go +++ b/adapter/internal/synchronizer/apis_fetcher.go @@ -95,6 +95,8 @@ func PushAPIProjects(payload []byte, environments []string, xdsOptions common.Xd return err } + choreoComponentInfo := deployment.ChoreoComponentInfo + vhostToEnvsMap := make(map[string][]*synchronizer.GatewayLabel) for index := range deployment.Environments { env := deployment.Environments[index] @@ -113,7 +115,7 @@ func PushAPIProjects(payload []byte, environments []string, xdsOptions common.Xd // Pass the byte slice for the XDS APIs to push it to the enforcer and router // TODO: (renuka) optimize applying API project, update maps one by one and apply xds once var deployedRevisionList []*notifier.DeployedAPIRevision - deployedRevisionList, err = apiServer.ApplyAPIProjectFromAPIM(apiFileData, vhostToEnvsMap, envProps, xdsOptions) + deployedRevisionList, err = apiServer.ApplyAPIProjectFromAPIM(apiFileData, vhostToEnvsMap, envProps, xdsOptions, choreoComponentInfo) if err != nil { logger.LoggerSync.Errorf("Error occurred while applying project %v", err) } else if deployedRevisionList != nil { @@ -123,7 +125,7 @@ func PushAPIProjects(payload []byte, environments []string, xdsOptions common.Xd // TODO: (renuka) notify the revision deployment to the control plane once all chunks are deployed. // This is not fixed as notify the control plane chunk by chunk (even though the chunk is not really applied to the Enforcer and Router) is not a drastic issue. - // This path is only happening when Adapter is restarting and at that time the deployed time is already updated in the control plane. + // This path is only happening when Adapter is restarting and at that time the deployed time is already updated in the control plane. notifier.SendRevisionUpdate(deploymentList) logger.LoggerSync.Infof("Successfully deployed %d API/s", len(deploymentList)) // Error nil for successful execution diff --git a/adapter/pkg/synchronizer/types.go b/adapter/pkg/synchronizer/types.go index 535e200d9a..3652b3b998 100644 --- a/adapter/pkg/synchronizer/types.go +++ b/adapter/pkg/synchronizer/types.go @@ -53,9 +53,10 @@ type APIDeployment struct { APIFile string `json:"apiFile"` Environments []GatewayLabel `json:"environments"` // These properties are used by global Adapter - OrganizationID string `json:"organizationId"` - APIContext string `json:"apiContext"` - Version string `json:"version"` + OrganizationID string `json:"organizationId"` + ChoreoComponentInfo ChoreoComponentInfo `json:"choreoComponentInfo"` + APIContext string `json:"apiContext"` + Version string `json:"version"` } // GatewayLabel represents gateway environment name, vhost and deployedTimeStamp of an API project. @@ -68,6 +69,14 @@ type GatewayLabel struct { DeploymentType string `json:"deploymentType"` } +type ChoreoComponentInfo struct { + OrganizationId string `json:"organizationId"` + ProjectId string `json:"projectId"` + ComponentId string `json:"componentId"` + VersionId string `json:"versionId"` + IsChoreoOrgPaid bool `json:"isChoreoOrgPaid"` // isPaidOrg +} + // APIConfigs represents env properties belongs to the API type APIConfigs struct { ProductionEndpoint string `mapstructure:"productionEndpoint,omitempty"` From 168d2c3268f170ad93d227945a4abdb31e238c4b Mon Sep 17 00:00:00 2001 From: Thushani Jayasekera Date: Thu, 12 Dec 2024 00:18:36 +0530 Subject: [PATCH 02/11] Adding circuit breaking configs if org is paid --- .../internal/oasparser/model/mgw_swagger.go | 29 +++++++------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/adapter/internal/oasparser/model/mgw_swagger.go b/adapter/internal/oasparser/model/mgw_swagger.go index a7bccc425c..164fcc4714 100644 --- a/adapter/internal/oasparser/model/mgw_swagger.go +++ b/adapter/internal/oasparser/model/mgw_swagger.go @@ -181,6 +181,7 @@ const prototypedAPI = "prototyped" // BasicCircuitBreaker is the name for free tier cluster level circuit breaker const BasicCircuitBreaker = "BasicCircuitBreaker" +const EnhancedCircuitBreaker = "EnhancedCircuitBreaker" // GetCorsConfig returns the CorsConfiguration Object. func (swagger *MgwSwagger) GetCorsConfig() *CorsConfig { @@ -686,8 +687,16 @@ func (endpointCluster *EndpointCluster) SetEndpointsConfig(endpointInfos []Endpo var selectedCircuitBreaker *CircuitBreakers for _, circuitBreaker := range conf.Envoy.Upstream.CircuitBreakers { - // check ispaidorg from here - if utills.GetIsOrganizationInList(orgID, circuitBreaker.Organizations) { + if isChoreoOrgPaid && circuitBreaker.CircuitBreakerName == EnhancedCircuitBreaker { + selectedCircuitBreaker = createCircuitBreaker( + circuitBreaker.MaxConnections, + circuitBreaker.MaxPendingRequests, + circuitBreaker.MaxRequests, + circuitBreaker.MaxRetries, + circuitBreaker.MaxConnectionPools, + ) + break + } else if !isChoreoOrgPaid && circuitBreaker.CircuitBreakerName == BasicCircuitBreaker { selectedCircuitBreaker = createCircuitBreaker( circuitBreaker.MaxConnections, circuitBreaker.MaxPendingRequests, @@ -696,22 +705,6 @@ func (endpointCluster *EndpointCluster) SetEndpointsConfig(endpointInfos []Endpo circuitBreaker.MaxConnectionPools, ) break - } - } - if selectedCircuitBreaker == nil { - for _, circuitBreaker := range conf.Envoy.Upstream.CircuitBreakers { - // breaks from the first iteration - if circuitBreaker.CircuitBreakerName == BasicCircuitBreaker { - selectedCircuitBreaker = createCircuitBreaker( - circuitBreaker.MaxConnections, - circuitBreaker.MaxPendingRequests, - circuitBreaker.MaxRequests, - circuitBreaker.MaxRetries, - circuitBreaker.MaxConnectionPools, - ) - break - } - } } endpointCluster.Config.CircuitBreakers = selectedCircuitBreaker From f8e45b9d8b45f745c372cc9c49db334b7480a4ea Mon Sep 17 00:00:00 2001 From: Thushani Jayasekera Date: Thu, 12 Dec 2024 00:33:00 +0530 Subject: [PATCH 03/11] Update defailt configs --- adapter/config/default_config.go | 12 ++++++------ resources/conf/config.toml.template | 18 +++++++++--------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/adapter/config/default_config.go b/adapter/config/default_config.go index b40c05a784..9b22d5ef7d 100644 --- a/adapter/config/default_config.go +++ b/adapter/config/default_config.go @@ -143,18 +143,18 @@ var defaultConfig = &Config{ { Organizations: "*", CircuitBreakerName: "BasicCircuitBreaker", - MaxConnections: 3, - MaxRequests: 3, + MaxConnections: 1, + MaxRequests: 1, MaxPendingRequests: 1, - MaxRetries: 3, + MaxConnectionPools: 1, }, { Organizations: "*", CircuitBreakerName: "EnhancedCircuitBreaker", - MaxConnections: 50, - MaxRequests: 50, + MaxConnections: 25, + MaxRequests: 25, MaxPendingRequests: 1, - MaxRetries: 50, + MaxConnectionPools: 2, }, }, }, diff --git a/resources/conf/config.toml.template b/resources/conf/config.toml.template index d9da67afd0..34549687e2 100644 --- a/resources/conf/config.toml.template +++ b/resources/conf/config.toml.template @@ -206,18 +206,18 @@ retainKeys = ["self_validate_jwt", "issuer", "claim_mappings", "consumer_key_cla [[router.upstream.circuitBreakers]] organizations = "*" circuitBreakerName = "BasicCircuitBreaker" -maxConnections = 3 -maxRequests = 3 -maxPendingRequests = 0 -maxConnectionPools = 3 +maxConnections = 1 +maxRequests = 1 +maxPendingRequests = 1 +maxConnectionPools = 1 [[router.upstream.circuitBreakers]] -organizations = "e0682456-2ba6-4c5f-8f36-3c5b6dc46913,4b9afefb-4bcc-4e63-85d3-ddd593841012,d3a7dfea-fb10-4371-b21d-85d1bc28667b" +organizations = "e0682456-2ba6-4c5f-8f36-3c5b6dc46913,4b9afefb-4bcc-4e63-85d3-ddd593841012" circuitBreakerName = "EnhancedCircuitBreaker" -maxConnections = 50 -maxRequests = 50 -maxPendingRequests = 0 -maxConnectionPools = 50 +maxConnections = 25 +maxRequests = 25 +maxPendingRequests = 1 +maxConnectionPools = 2 # Configs relevant to the envoy rate-limit service [router.ratelimit] From 70063f0901ee8cd443c064715eac262e2551bd7a Mon Sep 17 00:00:00 2001 From: Thushani Jayasekera Date: Thu, 12 Dec 2024 09:48:01 +0530 Subject: [PATCH 04/11] Fix build failure --- adapter/internal/oasparser/model/mgw_swagger.go | 9 ++++----- adapter/pkg/synchronizer/types.go | 8 ++++---- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/adapter/internal/oasparser/model/mgw_swagger.go b/adapter/internal/oasparser/model/mgw_swagger.go index 164fcc4714..69030b2e17 100644 --- a/adapter/internal/oasparser/model/mgw_swagger.go +++ b/adapter/internal/oasparser/model/mgw_swagger.go @@ -77,11 +77,10 @@ type MgwSwagger struct { // ChoreoComponentInfo represents the information of the Choreo component type ChoreoComponentInfo struct { - OrganizationID string - ProjectID string - ComponentID string - VersionID string - IsChoreoOrgPaid bool + OrganizationID string + ProjectID string + ComponentID string + VersionID string } // EndpointCluster represent an upstream cluster diff --git a/adapter/pkg/synchronizer/types.go b/adapter/pkg/synchronizer/types.go index 3652b3b998..de946eec6d 100644 --- a/adapter/pkg/synchronizer/types.go +++ b/adapter/pkg/synchronizer/types.go @@ -70,10 +70,10 @@ type GatewayLabel struct { } type ChoreoComponentInfo struct { - OrganizationId string `json:"organizationId"` - ProjectId string `json:"projectId"` - ComponentId string `json:"componentId"` - VersionId string `json:"versionId"` + OrganizationID string `json:"organizationId"` + ProjectID string `json:"projectId"` + ComponentID string `json:"componentId"` + VersionID string `json:"versionId"` IsChoreoOrgPaid bool `json:"isChoreoOrgPaid"` // isPaidOrg } From 7ef12d73a6dba564974ccfc2eec6732f8c5b1804 Mon Sep 17 00:00:00 2001 From: Thushani Jayasekera Date: Mon, 20 Jan 2025 15:07:14 +0530 Subject: [PATCH 05/11] Update mgw adapter changes --- adapter/internal/api/apis_impl.go | 38 +++++++++++++++++-- adapter/internal/discovery/xds/server.go | 6 +-- adapter/internal/oasparser/model/types.go | 2 +- adapter/internal/synchronizer/apis_fetcher.go | 6 +-- adapter/pkg/synchronizer/types.go | 3 +- 5 files changed, 42 insertions(+), 13 deletions(-) diff --git a/adapter/internal/api/apis_impl.go b/adapter/internal/api/apis_impl.go index deeec450a7..10f26164b0 100644 --- a/adapter/internal/api/apis_impl.go +++ b/adapter/internal/api/apis_impl.go @@ -37,6 +37,7 @@ import ( "github.com/wso2/product-microgateway/adapter/internal/oasparser/model" mgw "github.com/wso2/product-microgateway/adapter/internal/oasparser/model" "github.com/wso2/product-microgateway/adapter/pkg/synchronizer" + sync "github.com/wso2/product-microgateway/adapter/pkg/synchronizer" ) // API Controller related constants @@ -64,6 +65,14 @@ const ( apisArtifactDir string = "apis" ) +func init() { + conf, _ := config.ReadConfigs() + sync.InitializeWorkerPool(conf.ControlPlane.RequestWorkerPool.PoolSize, conf.ControlPlane.RequestWorkerPool.QueueSizePerPool, + conf.ControlPlane.RequestWorkerPool.PauseTimeAfterFailure, conf.Adapter.Truststore.Location, + conf.ControlPlane.SkipSSLVerification, conf.ControlPlane.HTTPClient.RequestTimeOut, conf.ControlPlane.RetryInterval, + conf.ControlPlane.ServiceURL, conf.ControlPlane.Username, conf.ControlPlane.Password) +} + // extractAPIProject accepts the API project as a zip file and returns the extracted content. // The apictl project must be in zipped format. // API type is decided by the type field in the api.yaml file. @@ -99,6 +108,7 @@ func extractAPIProject(payload []byte) (apiProject mgw.ProjectAPI, err error) { // ProcessMountedAPIProjects iterates through the api artifacts directory and apply the projects located within the directory. func ProcessMountedAPIProjects() (err error) { conf, _ := config.ReadConfigs() + isPaidOrg := false apisDirName := filepath.FromSlash(conf.Adapter.ArtifactsDirectory + "/" + apisArtifactDir) files, err := ioutil.ReadDir((apisDirName)) if err != nil { @@ -109,6 +119,23 @@ func ProcessMountedAPIProjects() (err error) { } } + payload, err := ioutil.ReadFile(apisDirName) + zipReader, err := zip.NewReader(bytes.NewReader(payload), int64(len(payload))) + if err != nil { + loggers.LoggerSync.Errorf("Error occured while unzipping the apictl project. Error: %v", err.Error()) + return err + } + + deploymentDescriptor, _, err := sync.ReadRootFiles(zipReader) + if err != nil { + loggers.LoggerAPI.Error("Error occured while reading root files ", err) + return err + } + + if len(deploymentDescriptor.Data.Deployments) > 0 { + isPaidOrg = deploymentDescriptor.Data.Deployments[0].IsPaidOrg + } + for _, apiProjectFile := range files { if apiProjectFile.IsDir() { apiProject := mgw.ProjectAPI{ @@ -138,6 +165,7 @@ func ProcessMountedAPIProjects() (err error) { } overrideValue := false + apiProject.IsPaidOrg = isPaidOrg err = validateAndUpdateXds(apiProject, &overrideValue) if err != nil { loggers.LoggerAPI.Errorf("Error while processing api artifact - %s during startup : %v", apiProjectFile.Name(), err) @@ -222,8 +250,9 @@ func validateAndUpdateXds(apiProject mgw.ProjectAPI, override *bool) (err error) } // TODO: (renuka) optimize to update cache only once when all internal memory maps are updated + // Step 1: Updating xds after going through each deployment. for vhost, environments := range vhostToEnvsMap { - _, err = xds.UpdateAPI(vhost, apiProject, environments, common.XdsOptions{}, synchronizer.ChoreoComponentInfo{}) + _, err = xds.UpdateAPI(vhost, apiProject, environments, common.XdsOptions{}, apiProject.IsPaidOrg) if err != nil { return } @@ -238,7 +267,7 @@ func ApplyAPIProjectFromAPIM( vhostToEnvsMap map[string][]*synchronizer.GatewayLabel, apiEnvs map[string]map[string]synchronizer.APIEnvProps, xdsOptions common.XdsOptions, - choreoComponentInfo synchronizer.ChoreoComponentInfo, + isPaidOrg bool, ) (deployedRevisionList []*notifier.DeployedAPIRevision, err error) { apiProject, err := extractAPIProject(payload) if err != nil { @@ -261,7 +290,8 @@ func ApplyAPIProjectFromAPIM( if apiProject.OrganizationID == "" { apiProject.OrganizationID = config.GetControlPlaneConnectedTenantDomain() } - loggers.LoggerAPI.Infof("Deploying api %s:%s in Organization %s", apiYaml.Name, apiYaml.Version, apiProject.OrganizationID) + apiProject.IsPaidOrg = isPaidOrg + loggers.LoggerAPI.Infof("Deploying api %s:%s in Organization %s ( isPaid: %v )", apiYaml.Name, apiYaml.Version, apiProject.OrganizationID, isPaidOrg) conf, _ := config.ReadConfigs() currentEnv := conf.ControlPlane.EnvironmentLabels[0] // assumption - adapter has only one environment @@ -284,7 +314,7 @@ func ApplyAPIProjectFromAPIM( loggers.LoggerAPI.Debugf("Update all environments (%v) of API %v %v:%v with UUID \"%v\".", environments, vhost, apiYaml.Name, apiYaml.Version, apiYaml.ID) // first update the API for vhost - deployedRevision, err := xds.UpdateAPI(vhost, apiProject, environments, xdsOptions, choreoComponentInfo) + deployedRevision, err := xds.UpdateAPI(vhost, apiProject, environments, xdsOptions, apiProject.IsPaidOrg) if err != nil { return deployedRevisionList, fmt.Errorf("%v:%v with UUID \"%v\"", apiYaml.Name, apiYaml.Version, apiYaml.ID) } diff --git a/adapter/internal/discovery/xds/server.go b/adapter/internal/discovery/xds/server.go index b5b1a8fe22..08b1280dc7 100644 --- a/adapter/internal/discovery/xds/server.go +++ b/adapter/internal/discovery/xds/server.go @@ -273,7 +273,7 @@ func DeployReadinessAPI(envs []string) { // UpdateAPI updates the Xds Cache when OpenAPI Json content is provided func UpdateAPI(vHost string, apiProject mgw.ProjectAPI, deployedEnvironments []*synchronizer.GatewayLabel, - xdsOptions common.XdsOptions, apiChoreoComponentInfo synchronizer.ChoreoComponentInfo) (*notifier.DeployedAPIRevision, error) { + xdsOptions common.XdsOptions, isPaidOrg bool) (*notifier.DeployedAPIRevision, error) { var mgwSwagger mgw.MgwSwagger var deployedRevision *notifier.DeployedAPIRevision @@ -372,14 +372,14 @@ func UpdateAPI(vHost string, apiProject mgw.ProjectAPI, deployedEnvironments []* apiHashValue := generateHashValue(apiYaml.Name, apiYaml.Version) if mgwSwagger.GetProdEndpoints() != nil { - mgwSwagger.GetProdEndpoints().SetEndpointsConfig(apiYaml.EndpointConfig.ProductionEndpoints, apiYaml.EndpointConfig.EndpointType, apiYaml.OrganizationID, apiChoreoComponentInfo.IsChoreoOrgPaid) + mgwSwagger.GetProdEndpoints().SetEndpointsConfig(apiYaml.EndpointConfig.ProductionEndpoints, apiYaml.EndpointConfig.EndpointType, apiYaml.OrganizationID, isPaidOrg) if !mgwSwagger.GetProdEndpoints().SecurityConfig.Enabled && apiYaml.EndpointConfig.APIEndpointSecurity.Production.Enabled { mgwSwagger.GetProdEndpoints().SecurityConfig = apiYaml.EndpointConfig.APIEndpointSecurity.Production } } if mgwSwagger.GetSandEndpoints() != nil { - mgwSwagger.GetSandEndpoints().SetEndpointsConfig(apiYaml.EndpointConfig.SandBoxEndpoints, apiYaml.EndpointConfig.EndpointType, apiYaml.OrganizationID, apiChoreoComponentInfo.IsChoreoOrgPaid) + mgwSwagger.GetSandEndpoints().SetEndpointsConfig(apiYaml.EndpointConfig.SandBoxEndpoints, apiYaml.EndpointConfig.EndpointType, apiYaml.OrganizationID, isPaidOrg) if !mgwSwagger.GetSandEndpoints().SecurityConfig.Enabled && apiYaml.EndpointConfig.APIEndpointSecurity.Sandbox.Enabled { mgwSwagger.GetSandEndpoints().SecurityConfig = apiYaml.EndpointConfig.APIEndpointSecurity.Sandbox } diff --git a/adapter/internal/oasparser/model/types.go b/adapter/internal/oasparser/model/types.go index ee03dd4331..95727d5030 100644 --- a/adapter/internal/oasparser/model/types.go +++ b/adapter/internal/oasparser/model/types.go @@ -66,6 +66,7 @@ type ProjectAPI struct { APIType string // read from api.yaml and formatted to upper case APILifeCycleStatus string // read from api.yaml and formatted to upper case OrganizationID string // read from api.yaml or config + IsPaidOrg bool //UpstreamCerts cert filename -> cert bytes UpstreamCerts map[string][]byte @@ -156,7 +157,6 @@ type choreoComponentInfo struct { ProjectID string `json:"projectId,omitempty"` ComponentID string `json:"componentId,omitempty"` VersionID string `json:"versionId,omitempty"` - IsChoreoOrgPaid bool `json:"isChoreoOrgPaid,omitempty"` } type backendJWTConfiguration struct { diff --git a/adapter/internal/synchronizer/apis_fetcher.go b/adapter/internal/synchronizer/apis_fetcher.go index 0c6f56a06d..a4a1647ae8 100644 --- a/adapter/internal/synchronizer/apis_fetcher.go +++ b/adapter/internal/synchronizer/apis_fetcher.go @@ -95,8 +95,6 @@ func PushAPIProjects(payload []byte, environments []string, xdsOptions common.Xd return err } - choreoComponentInfo := deployment.ChoreoComponentInfo - vhostToEnvsMap := make(map[string][]*synchronizer.GatewayLabel) for index := range deployment.Environments { env := deployment.Environments[index] @@ -115,7 +113,9 @@ func PushAPIProjects(payload []byte, environments []string, xdsOptions common.Xd // Pass the byte slice for the XDS APIs to push it to the enforcer and router // TODO: (renuka) optimize applying API project, update maps one by one and apply xds once var deployedRevisionList []*notifier.DeployedAPIRevision - deployedRevisionList, err = apiServer.ApplyAPIProjectFromAPIM(apiFileData, vhostToEnvsMap, envProps, xdsOptions, choreoComponentInfo) + + isPaidOrg := deploymentDescriptor.Data.Deployments[0].IsPaidOrg + deployedRevisionList, err = apiServer.ApplyAPIProjectFromAPIM(apiFileData, vhostToEnvsMap, envProps, xdsOptions, isPaidOrg) if err != nil { logger.LoggerSync.Errorf("Error occurred while applying project %v", err) } else if deployedRevisionList != nil { diff --git a/adapter/pkg/synchronizer/types.go b/adapter/pkg/synchronizer/types.go index de946eec6d..9cb0b2acb2 100644 --- a/adapter/pkg/synchronizer/types.go +++ b/adapter/pkg/synchronizer/types.go @@ -54,7 +54,7 @@ type APIDeployment struct { Environments []GatewayLabel `json:"environments"` // These properties are used by global Adapter OrganizationID string `json:"organizationId"` - ChoreoComponentInfo ChoreoComponentInfo `json:"choreoComponentInfo"` + IsPaidOrg bool `json:"isPaidOrg"` APIContext string `json:"apiContext"` Version string `json:"version"` } @@ -74,7 +74,6 @@ type ChoreoComponentInfo struct { ProjectID string `json:"projectId"` ComponentID string `json:"componentId"` VersionID string `json:"versionId"` - IsChoreoOrgPaid bool `json:"isChoreoOrgPaid"` // isPaidOrg } // APIConfigs represents env properties belongs to the API From c4567bcd557837acf21f1550f6d45ee91a07037f Mon Sep 17 00:00:00 2001 From: Thushani Jayasekera Date: Mon, 20 Jan 2025 15:23:32 +0530 Subject: [PATCH 06/11] Remove unwanted lines --- adapter/pkg/synchronizer/types.go | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/adapter/pkg/synchronizer/types.go b/adapter/pkg/synchronizer/types.go index 9cb0b2acb2..dd0664a1fb 100644 --- a/adapter/pkg/synchronizer/types.go +++ b/adapter/pkg/synchronizer/types.go @@ -50,13 +50,13 @@ type DeploymentData struct { // APIDeployment represents an API project that contains zip file name and // gateway environments (labels) that the project to be deployed type APIDeployment struct { - APIFile string `json:"apiFile"` - Environments []GatewayLabel `json:"environments"` + APIFile string `json:"apiFile"` + Environments []GatewayLabel `json:"environments"` // These properties are used by global Adapter - OrganizationID string `json:"organizationId"` - IsPaidOrg bool `json:"isPaidOrg"` - APIContext string `json:"apiContext"` - Version string `json:"version"` + OrganizationID string `json:"organizationId"` + IsPaidOrg bool `json:"isPaidOrg"` + APIContext string `json:"apiContext"` + Version string `json:"version"` } // GatewayLabel represents gateway environment name, vhost and deployedTimeStamp of an API project. @@ -69,13 +69,6 @@ type GatewayLabel struct { DeploymentType string `json:"deploymentType"` } -type ChoreoComponentInfo struct { - OrganizationID string `json:"organizationId"` - ProjectID string `json:"projectId"` - ComponentID string `json:"componentId"` - VersionID string `json:"versionId"` -} - // APIConfigs represents env properties belongs to the API type APIConfigs struct { ProductionEndpoint string `mapstructure:"productionEndpoint,omitempty"` From 12b7646aedccc83b148826d54f3ff235deaa961b Mon Sep 17 00:00:00 2001 From: Thushani Jayasekera Date: Mon, 20 Jan 2025 16:21:48 +0530 Subject: [PATCH 07/11] Add comment --- adapter/internal/oasparser/model/mgw_swagger.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/adapter/internal/oasparser/model/mgw_swagger.go b/adapter/internal/oasparser/model/mgw_swagger.go index 69030b2e17..ea10735cf9 100644 --- a/adapter/internal/oasparser/model/mgw_swagger.go +++ b/adapter/internal/oasparser/model/mgw_swagger.go @@ -180,6 +180,8 @@ const prototypedAPI = "prototyped" // BasicCircuitBreaker is the name for free tier cluster level circuit breaker const BasicCircuitBreaker = "BasicCircuitBreaker" + +// EnhancedCircuitBreaker is the name for the circuit breaker assigned for paid orgs const EnhancedCircuitBreaker = "EnhancedCircuitBreaker" // GetCorsConfig returns the CorsConfiguration Object. From 016722c55d43fc5cb062e41d5fd9cd6e63e84187 Mon Sep 17 00:00:00 2001 From: Thushani Jayasekera Date: Tue, 21 Jan 2025 10:21:35 +0530 Subject: [PATCH 08/11] Remove comment --- adapter/internal/api/apis_impl.go | 1 - 1 file changed, 1 deletion(-) diff --git a/adapter/internal/api/apis_impl.go b/adapter/internal/api/apis_impl.go index 10f26164b0..c9f5682d8e 100644 --- a/adapter/internal/api/apis_impl.go +++ b/adapter/internal/api/apis_impl.go @@ -250,7 +250,6 @@ func validateAndUpdateXds(apiProject mgw.ProjectAPI, override *bool) (err error) } // TODO: (renuka) optimize to update cache only once when all internal memory maps are updated - // Step 1: Updating xds after going through each deployment. for vhost, environments := range vhostToEnvsMap { _, err = xds.UpdateAPI(vhost, apiProject, environments, common.XdsOptions{}, apiProject.IsPaidOrg) if err != nil { From 85b08af705d14e1c435d2c5339a63d967db5da2c Mon Sep 17 00:00:00 2001 From: Thushani Jayasekera Date: Tue, 21 Jan 2025 10:58:51 +0530 Subject: [PATCH 09/11] Remove reading artifacts file from standalone feature --- adapter/internal/api/apis_impl.go | 39 ++++++------------------ adapter/internal/discovery/xds/server.go | 6 ++-- adapter/pkg/synchronizer/types.go | 12 ++++---- 3 files changed, 18 insertions(+), 39 deletions(-) diff --git a/adapter/internal/api/apis_impl.go b/adapter/internal/api/apis_impl.go index c9f5682d8e..b4035aa635 100644 --- a/adapter/internal/api/apis_impl.go +++ b/adapter/internal/api/apis_impl.go @@ -37,7 +37,6 @@ import ( "github.com/wso2/product-microgateway/adapter/internal/oasparser/model" mgw "github.com/wso2/product-microgateway/adapter/internal/oasparser/model" "github.com/wso2/product-microgateway/adapter/pkg/synchronizer" - sync "github.com/wso2/product-microgateway/adapter/pkg/synchronizer" ) // API Controller related constants @@ -65,14 +64,6 @@ const ( apisArtifactDir string = "apis" ) -func init() { - conf, _ := config.ReadConfigs() - sync.InitializeWorkerPool(conf.ControlPlane.RequestWorkerPool.PoolSize, conf.ControlPlane.RequestWorkerPool.QueueSizePerPool, - conf.ControlPlane.RequestWorkerPool.PauseTimeAfterFailure, conf.Adapter.Truststore.Location, - conf.ControlPlane.SkipSSLVerification, conf.ControlPlane.HTTPClient.RequestTimeOut, conf.ControlPlane.RetryInterval, - conf.ControlPlane.ServiceURL, conf.ControlPlane.Username, conf.ControlPlane.Password) -} - // extractAPIProject accepts the API project as a zip file and returns the extracted content. // The apictl project must be in zipped format. // API type is decided by the type field in the api.yaml file. @@ -108,7 +99,6 @@ func extractAPIProject(payload []byte) (apiProject mgw.ProjectAPI, err error) { // ProcessMountedAPIProjects iterates through the api artifacts directory and apply the projects located within the directory. func ProcessMountedAPIProjects() (err error) { conf, _ := config.ReadConfigs() - isPaidOrg := false apisDirName := filepath.FromSlash(conf.Adapter.ArtifactsDirectory + "/" + apisArtifactDir) files, err := ioutil.ReadDir((apisDirName)) if err != nil { @@ -119,23 +109,6 @@ func ProcessMountedAPIProjects() (err error) { } } - payload, err := ioutil.ReadFile(apisDirName) - zipReader, err := zip.NewReader(bytes.NewReader(payload), int64(len(payload))) - if err != nil { - loggers.LoggerSync.Errorf("Error occured while unzipping the apictl project. Error: %v", err.Error()) - return err - } - - deploymentDescriptor, _, err := sync.ReadRootFiles(zipReader) - if err != nil { - loggers.LoggerAPI.Error("Error occured while reading root files ", err) - return err - } - - if len(deploymentDescriptor.Data.Deployments) > 0 { - isPaidOrg = deploymentDescriptor.Data.Deployments[0].IsPaidOrg - } - for _, apiProjectFile := range files { if apiProjectFile.IsDir() { apiProject := mgw.ProjectAPI{ @@ -164,8 +137,10 @@ func ProcessMountedAPIProjects() (err error) { continue } + // setting false as this feature is not in use + apiProject.IsPaidOrg = false + overrideValue := false - apiProject.IsPaidOrg = isPaidOrg err = validateAndUpdateXds(apiProject, &overrideValue) if err != nil { loggers.LoggerAPI.Errorf("Error while processing api artifact - %s during startup : %v", apiProjectFile.Name(), err) @@ -251,7 +226,7 @@ func validateAndUpdateXds(apiProject mgw.ProjectAPI, override *bool) (err error) // TODO: (renuka) optimize to update cache only once when all internal memory maps are updated for vhost, environments := range vhostToEnvsMap { - _, err = xds.UpdateAPI(vhost, apiProject, environments, common.XdsOptions{}, apiProject.IsPaidOrg) + _, err = xds.UpdateAPI(vhost, apiProject, environments, common.XdsOptions{}) if err != nil { return } @@ -313,7 +288,7 @@ func ApplyAPIProjectFromAPIM( loggers.LoggerAPI.Debugf("Update all environments (%v) of API %v %v:%v with UUID \"%v\".", environments, vhost, apiYaml.Name, apiYaml.Version, apiYaml.ID) // first update the API for vhost - deployedRevision, err := xds.UpdateAPI(vhost, apiProject, environments, xdsOptions, apiProject.IsPaidOrg) + deployedRevision, err := xds.UpdateAPI(vhost, apiProject, environments, xdsOptions) if err != nil { return deployedRevisionList, fmt.Errorf("%v:%v with UUID \"%v\"", apiYaml.Name, apiYaml.Version, apiYaml.ID) } @@ -332,6 +307,10 @@ func ApplyAPIProjectInStandaloneMode(payload []byte, override *bool) (err error) if err != nil { return err } + + // setting false as this feature is not in use + apiProject.IsPaidOrg = false + return validateAndUpdateXds(apiProject, override) } diff --git a/adapter/internal/discovery/xds/server.go b/adapter/internal/discovery/xds/server.go index 08b1280dc7..d44db6c493 100644 --- a/adapter/internal/discovery/xds/server.go +++ b/adapter/internal/discovery/xds/server.go @@ -273,7 +273,7 @@ func DeployReadinessAPI(envs []string) { // UpdateAPI updates the Xds Cache when OpenAPI Json content is provided func UpdateAPI(vHost string, apiProject mgw.ProjectAPI, deployedEnvironments []*synchronizer.GatewayLabel, - xdsOptions common.XdsOptions, isPaidOrg bool) (*notifier.DeployedAPIRevision, error) { + xdsOptions common.XdsOptions) (*notifier.DeployedAPIRevision, error) { var mgwSwagger mgw.MgwSwagger var deployedRevision *notifier.DeployedAPIRevision @@ -372,14 +372,14 @@ func UpdateAPI(vHost string, apiProject mgw.ProjectAPI, deployedEnvironments []* apiHashValue := generateHashValue(apiYaml.Name, apiYaml.Version) if mgwSwagger.GetProdEndpoints() != nil { - mgwSwagger.GetProdEndpoints().SetEndpointsConfig(apiYaml.EndpointConfig.ProductionEndpoints, apiYaml.EndpointConfig.EndpointType, apiYaml.OrganizationID, isPaidOrg) + mgwSwagger.GetProdEndpoints().SetEndpointsConfig(apiYaml.EndpointConfig.ProductionEndpoints, apiYaml.EndpointConfig.EndpointType, apiYaml.OrganizationID, apiProject.IsPaidOrg) if !mgwSwagger.GetProdEndpoints().SecurityConfig.Enabled && apiYaml.EndpointConfig.APIEndpointSecurity.Production.Enabled { mgwSwagger.GetProdEndpoints().SecurityConfig = apiYaml.EndpointConfig.APIEndpointSecurity.Production } } if mgwSwagger.GetSandEndpoints() != nil { - mgwSwagger.GetSandEndpoints().SetEndpointsConfig(apiYaml.EndpointConfig.SandBoxEndpoints, apiYaml.EndpointConfig.EndpointType, apiYaml.OrganizationID, isPaidOrg) + mgwSwagger.GetSandEndpoints().SetEndpointsConfig(apiYaml.EndpointConfig.SandBoxEndpoints, apiYaml.EndpointConfig.EndpointType, apiYaml.OrganizationID, apiProject.IsPaidOrg) if !mgwSwagger.GetSandEndpoints().SecurityConfig.Enabled && apiYaml.EndpointConfig.APIEndpointSecurity.Sandbox.Enabled { mgwSwagger.GetSandEndpoints().SecurityConfig = apiYaml.EndpointConfig.APIEndpointSecurity.Sandbox } diff --git a/adapter/pkg/synchronizer/types.go b/adapter/pkg/synchronizer/types.go index dd0664a1fb..de323b5525 100644 --- a/adapter/pkg/synchronizer/types.go +++ b/adapter/pkg/synchronizer/types.go @@ -50,13 +50,13 @@ type DeploymentData struct { // APIDeployment represents an API project that contains zip file name and // gateway environments (labels) that the project to be deployed type APIDeployment struct { - APIFile string `json:"apiFile"` - Environments []GatewayLabel `json:"environments"` + APIFile string `json:"apiFile"` + Environments []GatewayLabel `json:"environments"` // These properties are used by global Adapter - OrganizationID string `json:"organizationId"` - IsPaidOrg bool `json:"isPaidOrg"` - APIContext string `json:"apiContext"` - Version string `json:"version"` + OrganizationID string `json:"organizationId"` + IsPaidOrg bool `json:"isPaidOrg"` + APIContext string `json:"apiContext"` + Version string `json:"version"` } // GatewayLabel represents gateway environment name, vhost and deployedTimeStamp of an API project. From ee0727db285632c1e59f2fa4ffb815a2a5bc40ed Mon Sep 17 00:00:00 2001 From: Thushani Jayasekera Date: Tue, 21 Jan 2025 11:04:33 +0530 Subject: [PATCH 10/11] Refactor code --- adapter/internal/synchronizer/apis_fetcher.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/adapter/internal/synchronizer/apis_fetcher.go b/adapter/internal/synchronizer/apis_fetcher.go index a4a1647ae8..dd7308ea13 100644 --- a/adapter/internal/synchronizer/apis_fetcher.go +++ b/adapter/internal/synchronizer/apis_fetcher.go @@ -114,8 +114,7 @@ func PushAPIProjects(payload []byte, environments []string, xdsOptions common.Xd // TODO: (renuka) optimize applying API project, update maps one by one and apply xds once var deployedRevisionList []*notifier.DeployedAPIRevision - isPaidOrg := deploymentDescriptor.Data.Deployments[0].IsPaidOrg - deployedRevisionList, err = apiServer.ApplyAPIProjectFromAPIM(apiFileData, vhostToEnvsMap, envProps, xdsOptions, isPaidOrg) + deployedRevisionList, err = apiServer.ApplyAPIProjectFromAPIM(apiFileData, vhostToEnvsMap, envProps, xdsOptions, deployment.IsPaidOrg) if err != nil { logger.LoggerSync.Errorf("Error occurred while applying project %v", err) } else if deployedRevisionList != nil { From 33fadc03c1e8bc605680b2e06c03911e62417a11 Mon Sep 17 00:00:00 2001 From: Thushani Jayasekera Date: Wed, 22 Jan 2025 17:47:59 +0530 Subject: [PATCH 11/11] Add feature flag --- .../internal/oasparser/model/mgw_swagger.go | 81 ++++++++++++++----- 1 file changed, 62 insertions(+), 19 deletions(-) diff --git a/adapter/internal/oasparser/model/mgw_swagger.go b/adapter/internal/oasparser/model/mgw_swagger.go index ea10735cf9..5b7456557d 100644 --- a/adapter/internal/oasparser/model/mgw_swagger.go +++ b/adapter/internal/oasparser/model/mgw_swagger.go @@ -21,6 +21,7 @@ import ( "errors" "fmt" "net/url" + "os" "regexp" "strconv" "strings" @@ -37,6 +38,19 @@ import ( "github.com/wso2/product-microgateway/adapter/pkg/synchronizer" ) +var paidOrgsFromSubscriptionServiceEnabled bool + +func init() { + envIsPaidOrgsFromSubscriptionServiceEnabled := os.Getenv("ENABLE_PAID_ORGS_FROM_SUBSCRIPTION_SERVICE") + + // Parse the environment variable to a boolean, defaulting to false if not set or if parsing fails + var err error + paidOrgsFromSubscriptionServiceEnabled, err = strconv.ParseBool(envIsPaidOrgsFromSubscriptionServiceEnabled) + if err != nil || envIsPaidOrgsFromSubscriptionServiceEnabled == "" { + paidOrgsFromSubscriptionServiceEnabled = false + } +} + // MgwSwagger represents the object structure holding the information related to the // openAPI object. The values are populated from the extensions/properties mentioned at // the root level of the openAPI definition. The pathItem level information is represented @@ -687,25 +701,54 @@ func (endpointCluster *EndpointCluster) SetEndpointsConfig(endpointInfos []Endpo conf, _ := config.ReadConfigs() var selectedCircuitBreaker *CircuitBreakers - for _, circuitBreaker := range conf.Envoy.Upstream.CircuitBreakers { - if isChoreoOrgPaid && circuitBreaker.CircuitBreakerName == EnhancedCircuitBreaker { - selectedCircuitBreaker = createCircuitBreaker( - circuitBreaker.MaxConnections, - circuitBreaker.MaxPendingRequests, - circuitBreaker.MaxRequests, - circuitBreaker.MaxRetries, - circuitBreaker.MaxConnectionPools, - ) - break - } else if !isChoreoOrgPaid && circuitBreaker.CircuitBreakerName == BasicCircuitBreaker { - selectedCircuitBreaker = createCircuitBreaker( - circuitBreaker.MaxConnections, - circuitBreaker.MaxPendingRequests, - circuitBreaker.MaxRequests, - circuitBreaker.MaxRetries, - circuitBreaker.MaxConnectionPools, - ) - break + if paidOrgsFromSubscriptionServiceEnabled { + for _, circuitBreaker := range conf.Envoy.Upstream.CircuitBreakers { + if isChoreoOrgPaid && circuitBreaker.CircuitBreakerName == EnhancedCircuitBreaker { + selectedCircuitBreaker = createCircuitBreaker( + circuitBreaker.MaxConnections, + circuitBreaker.MaxPendingRequests, + circuitBreaker.MaxRequests, + circuitBreaker.MaxRetries, + circuitBreaker.MaxConnectionPools, + ) + break + } else if !isChoreoOrgPaid && circuitBreaker.CircuitBreakerName == BasicCircuitBreaker { + selectedCircuitBreaker = createCircuitBreaker( + circuitBreaker.MaxConnections, + circuitBreaker.MaxPendingRequests, + circuitBreaker.MaxRequests, + circuitBreaker.MaxRetries, + circuitBreaker.MaxConnectionPools, + ) + break + } + } + } else { + for _, circuitBreaker := range conf.Envoy.Upstream.CircuitBreakers { + if utills.GetIsOrganizationInList(orgID, circuitBreaker.Organizations) { + selectedCircuitBreaker = createCircuitBreaker( + circuitBreaker.MaxConnections, + circuitBreaker.MaxPendingRequests, + circuitBreaker.MaxRequests, + circuitBreaker.MaxRetries, + circuitBreaker.MaxConnectionPools, + ) + break + } + } + if selectedCircuitBreaker == nil { + for _, circuitBreaker := range conf.Envoy.Upstream.CircuitBreakers { + if circuitBreaker.CircuitBreakerName == BasicCircuitBreaker { + selectedCircuitBreaker = createCircuitBreaker( + circuitBreaker.MaxConnections, + circuitBreaker.MaxPendingRequests, + circuitBreaker.MaxRequests, + circuitBreaker.MaxRetries, + circuitBreaker.MaxConnectionPools, + ) + break + } + } } } endpointCluster.Config.CircuitBreakers = selectedCircuitBreaker