Skip to content

Commit 266e153

Browse files
Merge pull request #3626 from Thushani-Jayasekera/ws-paidorg
Set circuitbreaker if org is paid
2 parents 450d7a1 + 33fadc0 commit 266e153

File tree

8 files changed

+91
-40
lines changed

8 files changed

+91
-40
lines changed

adapter/config/default_config.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -143,18 +143,18 @@ var defaultConfig = &Config{
143143
{
144144
Organizations: "*",
145145
CircuitBreakerName: "BasicCircuitBreaker",
146-
MaxConnections: 3,
147-
MaxRequests: 3,
146+
MaxConnections: 1,
147+
MaxRequests: 1,
148148
MaxPendingRequests: 1,
149-
MaxRetries: 3,
149+
MaxConnectionPools: 1,
150150
},
151151
{
152152
Organizations: "*",
153153
CircuitBreakerName: "EnhancedCircuitBreaker",
154-
MaxConnections: 50,
155-
MaxRequests: 50,
154+
MaxConnections: 25,
155+
MaxRequests: 25,
156156
MaxPendingRequests: 1,
157-
MaxRetries: 50,
157+
MaxConnectionPools: 2,
158158
},
159159
},
160160
},

adapter/internal/api/apis_impl.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ func ProcessMountedAPIProjects() (err error) {
137137
continue
138138
}
139139

140+
// setting false as this feature is not in use
141+
apiProject.IsPaidOrg = false
142+
140143
overrideValue := false
141144
err = validateAndUpdateXds(apiProject, &overrideValue)
142145
if err != nil {
@@ -238,6 +241,7 @@ func ApplyAPIProjectFromAPIM(
238241
vhostToEnvsMap map[string][]*synchronizer.GatewayLabel,
239242
apiEnvs map[string]map[string]synchronizer.APIEnvProps,
240243
xdsOptions common.XdsOptions,
244+
isPaidOrg bool,
241245
) (deployedRevisionList []*notifier.DeployedAPIRevision, err error) {
242246
apiProject, err := extractAPIProject(payload)
243247
if err != nil {
@@ -260,7 +264,8 @@ func ApplyAPIProjectFromAPIM(
260264
if apiProject.OrganizationID == "" {
261265
apiProject.OrganizationID = config.GetControlPlaneConnectedTenantDomain()
262266
}
263-
loggers.LoggerAPI.Infof("Deploying api %s:%s in Organization %s", apiYaml.Name, apiYaml.Version, apiProject.OrganizationID)
267+
apiProject.IsPaidOrg = isPaidOrg
268+
loggers.LoggerAPI.Infof("Deploying api %s:%s in Organization %s ( isPaid: %v )", apiYaml.Name, apiYaml.Version, apiProject.OrganizationID, isPaidOrg)
264269

265270
conf, _ := config.ReadConfigs()
266271
currentEnv := conf.ControlPlane.EnvironmentLabels[0] // assumption - adapter has only one environment
@@ -302,6 +307,10 @@ func ApplyAPIProjectInStandaloneMode(payload []byte, override *bool) (err error)
302307
if err != nil {
303308
return err
304309
}
310+
311+
// setting false as this feature is not in use
312+
apiProject.IsPaidOrg = false
313+
305314
return validateAndUpdateXds(apiProject, override)
306315
}
307316

adapter/internal/discovery/xds/server.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -372,14 +372,14 @@ func UpdateAPI(vHost string, apiProject mgw.ProjectAPI, deployedEnvironments []*
372372
apiHashValue := generateHashValue(apiYaml.Name, apiYaml.Version)
373373

374374
if mgwSwagger.GetProdEndpoints() != nil {
375-
mgwSwagger.GetProdEndpoints().SetEndpointsConfig(apiYaml.EndpointConfig.ProductionEndpoints, apiYaml.EndpointConfig.EndpointType, apiYaml.OrganizationID)
375+
mgwSwagger.GetProdEndpoints().SetEndpointsConfig(apiYaml.EndpointConfig.ProductionEndpoints, apiYaml.EndpointConfig.EndpointType, apiYaml.OrganizationID, apiProject.IsPaidOrg)
376376
if !mgwSwagger.GetProdEndpoints().SecurityConfig.Enabled && apiYaml.EndpointConfig.APIEndpointSecurity.Production.Enabled {
377377
mgwSwagger.GetProdEndpoints().SecurityConfig = apiYaml.EndpointConfig.APIEndpointSecurity.Production
378378
}
379379
}
380380

381381
if mgwSwagger.GetSandEndpoints() != nil {
382-
mgwSwagger.GetSandEndpoints().SetEndpointsConfig(apiYaml.EndpointConfig.SandBoxEndpoints, apiYaml.EndpointConfig.EndpointType, apiYaml.OrganizationID)
382+
mgwSwagger.GetSandEndpoints().SetEndpointsConfig(apiYaml.EndpointConfig.SandBoxEndpoints, apiYaml.EndpointConfig.EndpointType, apiYaml.OrganizationID, apiProject.IsPaidOrg)
383383
if !mgwSwagger.GetSandEndpoints().SecurityConfig.Enabled && apiYaml.EndpointConfig.APIEndpointSecurity.Sandbox.Enabled {
384384
mgwSwagger.GetSandEndpoints().SecurityConfig = apiYaml.EndpointConfig.APIEndpointSecurity.Sandbox
385385
}

adapter/internal/oasparser/model/mgw_swagger.go

Lines changed: 55 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"errors"
2222
"fmt"
2323
"net/url"
24+
"os"
2425
"regexp"
2526
"strconv"
2627
"strings"
@@ -37,6 +38,19 @@ import (
3738
"github.com/wso2/product-microgateway/adapter/pkg/synchronizer"
3839
)
3940

41+
var paidOrgsFromSubscriptionServiceEnabled bool
42+
43+
func init() {
44+
envIsPaidOrgsFromSubscriptionServiceEnabled := os.Getenv("ENABLE_PAID_ORGS_FROM_SUBSCRIPTION_SERVICE")
45+
46+
// Parse the environment variable to a boolean, defaulting to false if not set or if parsing fails
47+
var err error
48+
paidOrgsFromSubscriptionServiceEnabled, err = strconv.ParseBool(envIsPaidOrgsFromSubscriptionServiceEnabled)
49+
if err != nil || envIsPaidOrgsFromSubscriptionServiceEnabled == "" {
50+
paidOrgsFromSubscriptionServiceEnabled = false
51+
}
52+
}
53+
4054
// MgwSwagger represents the object structure holding the information related to the
4155
// openAPI object. The values are populated from the extensions/properties mentioned at
4256
// the root level of the openAPI definition. The pathItem level information is represented
@@ -181,6 +195,9 @@ const prototypedAPI = "prototyped"
181195
// BasicCircuitBreaker is the name for free tier cluster level circuit breaker
182196
const BasicCircuitBreaker = "BasicCircuitBreaker"
183197

198+
// EnhancedCircuitBreaker is the name for the circuit breaker assigned for paid orgs
199+
const EnhancedCircuitBreaker = "EnhancedCircuitBreaker"
200+
184201
// GetCorsConfig returns the CorsConfiguration Object.
185202
func (swagger *MgwSwagger) GetCorsConfig() *CorsConfig {
186203
return swagger.xWso2Cors
@@ -643,7 +660,7 @@ func (swagger *MgwSwagger) setXWso2Endpoints() error {
643660
}
644661

645662
// SetEndpointsConfig set configs for Endpoints sent by api.yaml
646-
func (endpointCluster *EndpointCluster) SetEndpointsConfig(endpointInfos []EndpointInfo, apiType string, orgID string) error {
663+
func (endpointCluster *EndpointCluster) SetEndpointsConfig(endpointInfos []EndpointInfo, apiType string, orgID string, isChoreoOrgPaid bool) error {
647664
if endpointInfos == nil || len(endpointInfos) == 0 {
648665
return nil
649666
}
@@ -684,22 +701,31 @@ func (endpointCluster *EndpointCluster) SetEndpointsConfig(endpointInfos []Endpo
684701
conf, _ := config.ReadConfigs()
685702
var selectedCircuitBreaker *CircuitBreakers
686703

687-
for _, circuitBreaker := range conf.Envoy.Upstream.CircuitBreakers {
688-
if utills.GetIsOrganizationInList(orgID, circuitBreaker.Organizations) {
689-
selectedCircuitBreaker = createCircuitBreaker(
690-
circuitBreaker.MaxConnections,
691-
circuitBreaker.MaxPendingRequests,
692-
circuitBreaker.MaxRequests,
693-
circuitBreaker.MaxRetries,
694-
circuitBreaker.MaxConnectionPools,
695-
)
696-
break
704+
if paidOrgsFromSubscriptionServiceEnabled {
705+
for _, circuitBreaker := range conf.Envoy.Upstream.CircuitBreakers {
706+
if isChoreoOrgPaid && circuitBreaker.CircuitBreakerName == EnhancedCircuitBreaker {
707+
selectedCircuitBreaker = createCircuitBreaker(
708+
circuitBreaker.MaxConnections,
709+
circuitBreaker.MaxPendingRequests,
710+
circuitBreaker.MaxRequests,
711+
circuitBreaker.MaxRetries,
712+
circuitBreaker.MaxConnectionPools,
713+
)
714+
break
715+
} else if !isChoreoOrgPaid && circuitBreaker.CircuitBreakerName == BasicCircuitBreaker {
716+
selectedCircuitBreaker = createCircuitBreaker(
717+
circuitBreaker.MaxConnections,
718+
circuitBreaker.MaxPendingRequests,
719+
circuitBreaker.MaxRequests,
720+
circuitBreaker.MaxRetries,
721+
circuitBreaker.MaxConnectionPools,
722+
)
723+
break
724+
}
697725
}
698-
}
699-
if selectedCircuitBreaker == nil {
726+
} else {
700727
for _, circuitBreaker := range conf.Envoy.Upstream.CircuitBreakers {
701-
// breaks from the first iteration
702-
if circuitBreaker.CircuitBreakerName == BasicCircuitBreaker {
728+
if utills.GetIsOrganizationInList(orgID, circuitBreaker.Organizations) {
703729
selectedCircuitBreaker = createCircuitBreaker(
704730
circuitBreaker.MaxConnections,
705731
circuitBreaker.MaxPendingRequests,
@@ -709,7 +735,20 @@ func (endpointCluster *EndpointCluster) SetEndpointsConfig(endpointInfos []Endpo
709735
)
710736
break
711737
}
712-
738+
}
739+
if selectedCircuitBreaker == nil {
740+
for _, circuitBreaker := range conf.Envoy.Upstream.CircuitBreakers {
741+
if circuitBreaker.CircuitBreakerName == BasicCircuitBreaker {
742+
selectedCircuitBreaker = createCircuitBreaker(
743+
circuitBreaker.MaxConnections,
744+
circuitBreaker.MaxPendingRequests,
745+
circuitBreaker.MaxRequests,
746+
circuitBreaker.MaxRetries,
747+
circuitBreaker.MaxConnectionPools,
748+
)
749+
break
750+
}
751+
}
713752
}
714753
}
715754
endpointCluster.Config.CircuitBreakers = selectedCircuitBreaker

adapter/internal/oasparser/model/types.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ type ProjectAPI struct {
6666
APIType string // read from api.yaml and formatted to upper case
6767
APILifeCycleStatus string // read from api.yaml and formatted to upper case
6868
OrganizationID string // read from api.yaml or config
69+
IsPaidOrg bool
6970

7071
//UpstreamCerts cert filename -> cert bytes
7172
UpstreamCerts map[string][]byte
@@ -152,10 +153,10 @@ type apiData struct {
152153
}
153154

154155
type choreoComponentInfo struct {
155-
OrganizationID string `json:"organizationId,omitempty"`
156-
ProjectID string `json:"projectId,omitempty"`
157-
ComponentID string `json:"componentId,omitempty"`
158-
VersionID string `json:"versionId,omitempty"`
156+
OrganizationID string `json:"organizationId,omitempty"`
157+
ProjectID string `json:"projectId,omitempty"`
158+
ComponentID string `json:"componentId,omitempty"`
159+
VersionID string `json:"versionId,omitempty"`
159160
}
160161

161162
type backendJWTConfiguration struct {

adapter/internal/synchronizer/apis_fetcher.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,8 @@ func PushAPIProjects(payload []byte, environments []string, xdsOptions common.Xd
113113
// Pass the byte slice for the XDS APIs to push it to the enforcer and router
114114
// TODO: (renuka) optimize applying API project, update maps one by one and apply xds once
115115
var deployedRevisionList []*notifier.DeployedAPIRevision
116-
deployedRevisionList, err = apiServer.ApplyAPIProjectFromAPIM(apiFileData, vhostToEnvsMap, envProps, xdsOptions)
116+
117+
deployedRevisionList, err = apiServer.ApplyAPIProjectFromAPIM(apiFileData, vhostToEnvsMap, envProps, xdsOptions, deployment.IsPaidOrg)
117118
if err != nil {
118119
logger.LoggerSync.Errorf("Error occurred while applying project %v", err)
119120
} else if deployedRevisionList != nil {
@@ -123,7 +124,7 @@ func PushAPIProjects(payload []byte, environments []string, xdsOptions common.Xd
123124

124125
// TODO: (renuka) notify the revision deployment to the control plane once all chunks are deployed.
125126
// 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.
126-
// This path is only happening when Adapter is restarting and at that time the deployed time is already updated in the control plane.
127+
// This path is only happening when Adapter is restarting and at that time the deployed time is already updated in the control plane.
127128
notifier.SendRevisionUpdate(deploymentList)
128129
logger.LoggerSync.Infof("Successfully deployed %d API/s", len(deploymentList))
129130
// Error nil for successful execution

adapter/pkg/synchronizer/types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ type APIDeployment struct {
5454
Environments []GatewayLabel `json:"environments"`
5555
// These properties are used by global Adapter
5656
OrganizationID string `json:"organizationId"`
57+
IsPaidOrg bool `json:"isPaidOrg"`
5758
APIContext string `json:"apiContext"`
5859
Version string `json:"version"`
5960
}

resources/conf/config.toml.template

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -206,18 +206,18 @@ retainKeys = ["self_validate_jwt", "issuer", "claim_mappings", "consumer_key_cla
206206
[[router.upstream.circuitBreakers]]
207207
organizations = "*"
208208
circuitBreakerName = "BasicCircuitBreaker"
209-
maxConnections = 3
210-
maxRequests = 3
211-
maxPendingRequests = 0
212-
maxConnectionPools = 3
209+
maxConnections = 1
210+
maxRequests = 1
211+
maxPendingRequests = 1
212+
maxConnectionPools = 1
213213

214214
[[router.upstream.circuitBreakers]]
215-
organizations = "e0682456-2ba6-4c5f-8f36-3c5b6dc46913,4b9afefb-4bcc-4e63-85d3-ddd593841012,d3a7dfea-fb10-4371-b21d-85d1bc28667b"
215+
organizations = "e0682456-2ba6-4c5f-8f36-3c5b6dc46913,4b9afefb-4bcc-4e63-85d3-ddd593841012"
216216
circuitBreakerName = "EnhancedCircuitBreaker"
217-
maxConnections = 50
218-
maxRequests = 50
219-
maxPendingRequests = 0
220-
maxConnectionPools = 50
217+
maxConnections = 25
218+
maxRequests = 25
219+
maxPendingRequests = 1
220+
maxConnectionPools = 2
221221

222222
# Configs relevant to the envoy rate-limit service
223223
[router.ratelimit]

0 commit comments

Comments
 (0)