Repository: wso2/product-microgateway
Issue: Unlimited API Tier does not apply after resource level tier is set once

### Description:

$subject

### Steps to reproduce:
1. Create an API and assign resource level Tier and save.
2. Deploy the API and see if the resource level tier is applied.
3. Then change it to API Level and assign unlimited tier. 
4. Deploy the API and see if the resource level tier is applied. (in this case, it would apply.)

### Affected Product Version:
<!-- Members can use Affected/*** labels -->

### Environment details (with versions):
- OS:
- Client:
- Env (Docker/K8s):

---
### Optional Fields
#### Related Issues:
<!-- Any related issues from this/other repositories-->

#### Suggested Labels:
<!--Only to be used by non-members-->

#### Suggested Assignees:
<!--Only to be used by non-members-->


Changed files:
enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/throttle/ThrottleFilter.java
enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/InternalAPIKeyAuthenticator.java
enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/util/FilterUtils.java
enforcer-parent/commons/src/main/java/org/wso2/choreo/connect/enforcer/commons/model/APIConfig.java
enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/websocket/WebSocketMetaDataFilter.java

diff --git a/enforcer-parent/commons/src/main/java/org/wso2/choreo/connect/enforcer/commons/model/APIConfig.java b/enforcer-parent/commons/src/main/java/org/wso2/choreo/connect/enforcer/commons/model/APIConfig.java
index 32fe1df81..331d53b84 100644
--- a/enforcer-parent/commons/src/main/java/org/wso2/choreo/connect/enforcer/commons/model/APIConfig.java
+++ b/enforcer-parent/commons/src/main/java/org/wso2/choreo/connect/enforcer/commons/model/APIConfig.java
@@ -40,7 +40,7 @@ public class APIConfig {
     private String uuid;
 
     private Map<String, List<String>> apiSecurity = new HashMap<>();
-    private String tier = "Unlimited";
+    private String tier;
     private boolean disableSecurity = false;
     private List<ResourceConfig> resources = new ArrayList<>();
 
@@ -203,7 +203,7 @@ public class APIConfig {
         private String uuid;
         private Map<String, SecuritySchemaConfig> securitySchemeDefinitions;
         private Map<String, List<String>> apiSecurity = new HashMap<>();
-        private String tier = "Unlimited";
+        private String tier;
         private boolean disableSecurity = false;
         private List<ResourceConfig> resources = new ArrayList<>();
 
diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/InternalAPIKeyAuthenticator.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/InternalAPIKeyAuthenticator.java
index dde3ff0bf..2df3c35ef 100644
--- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/InternalAPIKeyAuthenticator.java
+++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/InternalAPIKeyAuthenticator.java
@@ -228,7 +228,6 @@ public class InternalAPIKeyAuthenticator extends APIKeyHandler {
                     }
 
                     return FilterUtils.generateAuthenticationContext(tokenIdentifier, payload, api,
-                            requestContext.getMatchedAPI().getTier(),
                             requestContext.getMatchedAPI().getUuid(), internalKey);
                 } else {
                     log.error("Internal Key authentication failed. " + FilterUtils.getMaskedToken(splitToken[0]));
diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/throttle/ThrottleFilter.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/throttle/ThrottleFilter.java
index 19f1a7abf..a006c434e 100644
--- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/throttle/ThrottleFilter.java
+++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/throttle/ThrottleFilter.java
@@ -135,7 +135,7 @@ public class ThrottleFilter implements Filter {
                 String authorizedUser = FilterUtils.buildUsernameWithTenant(authContext.getUsername(), appTenant);
                 boolean isApiLevelTriggered = false;
 
-                if (!StringUtils.isEmpty(apiTier) && !ThrottleConstants.UNLIMITED_TIER.equalsIgnoreCase(apiTier)) {
+                if (!StringUtils.isEmpty(api.getTier())) {
                     resourceThrottleKey = apiThrottleKey;
                     resourceTier = apiTier;
                     isApiLevelTriggered = true;
@@ -298,7 +298,9 @@ public class ThrottleFilter implements Filter {
             tenantDomain = APIConstants.SUPER_TENANT_DOMAIN_NAME;
         }
 
-        if (!StringUtils.isEmpty(apiTier) && !ThrottleConstants.UNLIMITED_TIER.equals(apiTier)) {
+        // apiConfig instance will have the tier assigned only if openapi definition contains the
+        // extension
+        if (!StringUtils.isEmpty(api.getTier())) {
             resourceTier = apiTier;
             resourceKey = apiContext;
         } else {
@@ -362,7 +364,7 @@ public class ThrottleFilter implements Filter {
     }
 
     private String getApiTier(APIConfig apiConfig) {
-        if (!apiConfig.getTier().isBlank()) {
+        if (!StringUtils.isEmpty(apiConfig.getTier())) {
             return apiConfig.getTier();
         }
         return ThrottleConstants.UNLIMITED_TIER;
diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/util/FilterUtils.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/util/FilterUtils.java
index b5a97aae3..b03c3567e 100644
--- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/util/FilterUtils.java
+++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/util/FilterUtils.java
@@ -300,13 +300,12 @@ public class FilterUtils {
      * @param tokenIdentifier
      * @param payload
      * @param api
-     * @param apiLevelPolicy
      * @param rawToken Raw token used to authenticate the request
      * @return
      * @throws java.text.ParseException
      */
     public static AuthenticationContext generateAuthenticationContext(String tokenIdentifier, JWTClaimsSet payload,
-                                                                      JSONObject api, String apiLevelPolicy,
+                                                                      JSONObject api,
                                                                       String apiUUID, String rawToken)
             throws java.text.ParseException {
 
diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/websocket/WebSocketMetaDataFilter.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/websocket/WebSocketMetaDataFilter.java
index a4a292f1c..b0344c52c 100644
--- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/websocket/WebSocketMetaDataFilter.java
+++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/websocket/WebSocketMetaDataFilter.java
@@ -27,6 +27,7 @@ import org.wso2.choreo.connect.enforcer.commons.model.APIConfig;
 import org.wso2.choreo.connect.enforcer.commons.model.AuthenticationContext;
 import org.wso2.choreo.connect.enforcer.commons.model.RequestContext;
 import org.wso2.choreo.connect.enforcer.constants.APIConstants;
+import org.wso2.choreo.connect.enforcer.throttle.ThrottleConstants;
 import org.wso2.choreo.connect.enforcer.tracing.TracingConstants;
 import org.wso2.choreo.connect.enforcer.tracing.TracingSpan;
 import org.wso2.choreo.connect.enforcer.tracing.TracingTracer;
@@ -63,6 +64,8 @@ public class WebSocketMetaDataFilter implements Filter {
                         ThreadContext.get(APIConstants.LOG_TRACE_ID));
 
             }
+            String apiTier = !requestContext.getMatchedAPI().getTier().isBlank()
+                    ? requestContext.getMatchedAPI().getTier() : ThrottleConstants.UNLIMITED_TIER;
             AuthenticationContext authenticationContext = requestContext.getAuthenticationContext();
             requestContext.addMetadataToMap(MetadataConstants.GRPC_STREAM_ID, UUID.randomUUID().toString());
             requestContext.addMetadataToMap(MetadataConstants.REQUEST_ID,
@@ -74,7 +77,7 @@ public class WebSocketMetaDataFilter implements Filter {
             requestContext.addMetadataToMap(MetadataConstants.TIER,
                     getNullableStringValue(authenticationContext.getTier()));
             requestContext.addMetadataToMap(MetadataConstants.API_TIER,
-                    getNullableStringValue(requestContext.getMatchedAPI().getTier()));
+                    getNullableStringValue(apiTier));
             requestContext.addMetadataToMap(MetadataConstants.CONTENT_AWARE_TIER_PRESENT,
                     getNullableStringValue(String.valueOf(authenticationContext.isContentAwareTierPresent())));
             requestContext.addMetadataToMap(MetadataConstants.API_KEY,