@@ -45,6 +45,7 @@ import (
45
45
"github.com/wso2/product-microgateway/adapter/internal/oasparser/model"
46
46
mgw "github.com/wso2/product-microgateway/adapter/internal/oasparser/model"
47
47
"github.com/wso2/product-microgateway/adapter/internal/svcdiscovery"
48
+ "github.com/wso2/product-microgateway/adapter/pkg/discovery/api/wso2/discovery/api"
48
49
subscription "github.com/wso2/product-microgateway/adapter/pkg/discovery/api/wso2/discovery/subscription"
49
50
throttle "github.com/wso2/product-microgateway/adapter/pkg/discovery/api/wso2/discovery/throttle"
50
51
wso2_cache "github.com/wso2/product-microgateway/adapter/pkg/discovery/protocol/cache/v3"
83
84
orgIDOpenAPIRoutesMap map [string ]map [string ][]* routev3.Route // organizationID -> Vhost:API_UUID -> Envoy Routes map
84
85
orgIDOpenAPIClustersMap map [string ]map [string ][]* clusterv3.Cluster // organizationID -> Vhost:API_UUID -> Envoy Clusters map
85
86
orgIDOpenAPIEndpointsMap map [string ]map [string ][]* corev3.Address // organizationID -> Vhost:API_UUID -> Envoy Endpoints map
86
- orgIDOpenAPIEnforcerApisMap map [string ]map [string ]types. Resource // organizationID -> Vhost:API_UUID -> API Resource map
87
+ orgIDOpenAPIEnforcerApisMap map [string ]map [string ]* api. Api // organizationID -> Vhost:API_UUID -> API Resource map
87
88
orgIDvHostBasepathMap map [string ]map [string ]string // organizationID -> Vhost:basepath -> Vhost:API_UUID
88
89
89
90
reverseAPINameVersionMap map [string ]string
@@ -119,6 +120,8 @@ const (
119
120
maxRandomInt int = 999999999
120
121
prototypedAPI string = "PROTOTYPED"
121
122
apiKeyFieldSeparator string = ":"
123
+ blockedStatus string = "BLOCKED"
124
+ nonBlockedStatus string = "CREATED/PUBLISHED"
122
125
)
123
126
124
127
// IDHash uses ID field as the node hash.
@@ -161,7 +164,7 @@ func init() {
161
164
orgIDOpenAPIRoutesMap = make (map [string ]map [string ][]* routev3.Route ) // organizationID -> Vhost:API_UUID -> Envoy Routes map
162
165
orgIDOpenAPIClustersMap = make (map [string ]map [string ][]* clusterv3.Cluster ) // organizationID -> Vhost:API_UUID -> Envoy Clusters map
163
166
orgIDOpenAPIEndpointsMap = make (map [string ]map [string ][]* corev3.Address ) // organizationID -> Vhost:API_UUID -> Envoy Endpoints map
164
- orgIDOpenAPIEnforcerApisMap = make (map [string ]map [string ]types. Resource ) // organizationID -> Vhost:API_UUID -> API Resource map
167
+ orgIDOpenAPIEnforcerApisMap = make (map [string ]map [string ]* api. Api ) // organizationID -> Vhost:API_UUID -> API Resource map
165
168
orgIDvHostBasepathMap = make (map [string ]map [string ]string )
166
169
167
170
reverseAPINameVersionMap = make (map [string ]string )
@@ -334,6 +337,8 @@ func UpdateAPI(vHost string, apiProject mgw.ProjectAPI, environments []string) (
334
337
apiYaml .Name , apiYaml .Version , organizationID )
335
338
return nil , validationErr
336
339
}
340
+ // Update the LifecycleStatus of the API.
341
+ updateLCStateOfMgwSwagger (& mgwSwagger )
337
342
338
343
// -------- Finished updating mgwSwagger struct
339
344
@@ -434,28 +439,60 @@ func UpdateAPI(vHost string, apiProject mgw.ProjectAPI, environments []string) (
434
439
}
435
440
436
441
if _ , ok := orgIDOpenAPIEnforcerApisMap [organizationID ]; ok {
437
- orgIDOpenAPIEnforcerApisMap [organizationID ][apiIdentifier ] = oasParser .GetEnforcerAPI (mgwSwagger ,
438
- apiProject .APILifeCycleStatus , vHost )
442
+ orgIDOpenAPIEnforcerApisMap [organizationID ][apiIdentifier ] = oasParser .GetEnforcerAPI (mgwSwagger , vHost )
439
443
} else {
440
- enforcerAPIMap := make (map [string ]types.Resource )
441
- enforcerAPIMap [apiIdentifier ] = oasParser .GetEnforcerAPI (mgwSwagger , apiProject .APILifeCycleStatus ,
442
- vHost )
444
+ enforcerAPIMap := make (map [string ]* api.Api )
445
+ enforcerAPIMap [apiIdentifier ] = oasParser .GetEnforcerAPI (mgwSwagger , vHost )
443
446
orgIDOpenAPIEnforcerApisMap [organizationID ] = enforcerAPIMap
444
447
}
445
448
446
449
// TODO: (VirajSalaka) Fault tolerance mechanism implementation
447
450
revisionStatus := updateXdsCacheOnAPIAdd (oldLabels , newLabels )
448
451
if revisionStatus {
449
452
// send updated revision to control plane
450
- deployedRevision = notifier .UpdateDeployedRevisions (apiYaml .ID , apiYaml .RevisionID , environments ,
451
- vHost )
453
+ deployedRevision = notifier .UpdateDeployedRevisions (apiYaml .ID , apiYaml .RevisionID , environments , vHost )
452
454
}
453
455
if svcdiscovery .IsServiceDiscoveryEnabled {
454
456
startConsulServiceDiscovery (organizationID ) //consul service discovery starting point
455
457
}
456
458
return deployedRevision , nil
457
459
}
458
460
461
+ // UpdateAPIInEnforcerForBlockedAPIUpdate updates the state of APIMetadataMap under apiID with the lifecycle state and then
462
+ // XDS cache for enforcerAPIs is updated.
463
+ func UpdateAPIInEnforcerForBlockedAPIUpdate (apiID , organizationID , state string ) {
464
+ mutexForInternalMapUpdate .Lock ()
465
+ defer mutexForInternalMapUpdate .Unlock ()
466
+ // First needs to update the API Metadata Map
467
+ UpdateAPIMetataMapWithAPILCEvent (apiID , state )
468
+ var apiReferenceArray []string
469
+ // Iterate through the enforcerAPIsMap and update the lifecycle status for the map. This is the map representing
470
+ // runtime-artifact for each API
471
+ if openAPIEnforcerAPIsMap , orgFound := orgIDOpenAPIEnforcerApisMap [organizationID ]; orgFound {
472
+ // The reference is vhost:apiUUID. Hence it is required to iterate through all API entries as there could be multiple deployments of the same API
473
+ // under different vhosts.
474
+ for apiReference , enforcerAPI := range openAPIEnforcerAPIsMap {
475
+ if strings .HasSuffix (apiReference , ":" + apiID ) && (state == blockedStatus || enforcerAPI .ApiLifeCycleState == blockedStatus ) {
476
+ logger .LoggerXds .Infof ("API Lifecycle status is updated for the API %s to %s state" , apiReference , state )
477
+ enforcerAPI .ApiLifeCycleState = state
478
+ apiReferenceArray = append (apiReferenceArray , apiReference )
479
+ }
480
+ }
481
+ } else {
482
+ logger .LoggerXds .Infof ("API Life Cycle event is not applied due to irrelevant tenant domain : %s." , organizationID )
483
+ return
484
+ }
485
+
486
+ // For all the gateway labels containing the API, the enforcer XDS cache needs to be updated.
487
+ if openAPIEnvoyLabelMap , ok := orgIDOpenAPIEnvoyMap [organizationID ]; ok {
488
+ for _ , apiReference := range apiReferenceArray {
489
+ if labels , labelsFound := openAPIEnvoyLabelMap [apiReference ]; labelsFound {
490
+ updateXdsCacheForEnforcerAPIsOnly (labels )
491
+ }
492
+ }
493
+ }
494
+ }
495
+
459
496
// GetAllEnvironments returns all the environments merging new environments with already deployed environments
460
497
// of the given vhost of the API
461
498
func GetAllEnvironments (apiUUID , vhost string , newEnvironments []string ) []string {
@@ -782,6 +819,12 @@ func updateXdsCacheOnAPIAdd(oldLabels []string, newLabels []string) bool {
782
819
return revisionStatus
783
820
}
784
821
822
+ func updateXdsCacheForEnforcerAPIsOnly (labels []string ) {
823
+ for _ , label := range labels {
824
+ UpdateEnforcerApis (label , generateEnforcerAPIsForLabel (label ), "" )
825
+ }
826
+ }
827
+
785
828
// GenerateEnvoyResoucesForLabel generates envoy resources for a given label
786
829
// This method will list out all APIs mapped to the label. and generate envoy resources for all of these APIs.
787
830
func GenerateEnvoyResoucesForLabel (label string ) ([]types.Resource , []types.Resource , []types.Resource ,
@@ -850,6 +893,24 @@ func GenerateEnvoyResoucesForLabel(label string) ([]types.Resource, []types.Reso
850
893
return endpoints , clusters , listeners , routeConfigs , apis
851
894
}
852
895
896
+ // generateEnforcerAPIsForLabel generates ebforcerAPIs resource array for a given label.
897
+ // This is used when the envoy resources are not required to have changes but the enforcer APIs are required to (Blocked State APIs)
898
+ func generateEnforcerAPIsForLabel (label string ) []types.Resource {
899
+ var apis []types.Resource
900
+
901
+ for organizationID , entityMap := range orgIDOpenAPIEnvoyMap {
902
+ for apiKey , labels := range entityMap {
903
+ if arrayContains (labels , label ) {
904
+ enforcerAPI , ok := orgIDOpenAPIEnforcerApisMap [organizationID ][apiKey ]
905
+ if ok {
906
+ apis = append (apis , enforcerAPI )
907
+ }
908
+ }
909
+ }
910
+ }
911
+ return apis
912
+ }
913
+
853
914
// GenerateGlobalClusters generates the globally available clusters and endpoints.
854
915
func GenerateGlobalClusters (label string ) {
855
916
clusters , endpoints := oasParser .GetGlobalClusters ()
@@ -1239,3 +1300,13 @@ func UpdateEnforcerThrottleData(throttleData *throttle.ThrottleData) {
1239
1300
enforcerThrottleData = t
1240
1301
logger .LoggerXds .Infof ("New Throttle Data cache update for the label: " + label + " version: " + fmt .Sprint (version ))
1241
1302
}
1303
+
1304
+ func updateLCStateOfMgwSwagger (mgwSwagger * model.MgwSwagger ) {
1305
+ // If there are any metadata stored under the APIMetadataMap and Life Cycle state is blocked, update the mgwSwagger
1306
+ apiEntry , apiFound := APIMetadataMap [mgwSwagger .GetID ()]
1307
+ if apiFound && apiEntry .LcState == blockedStatus {
1308
+ mgwSwagger .LifeCycleState = blockedStatus
1309
+ return
1310
+ }
1311
+ mgwSwagger .LifeCycleState = nonBlockedStatus
1312
+ }
0 commit comments