From 0d188dd7508d55c89d101c7469f9f5007e1251e6 Mon Sep 17 00:00:00 2001 From: Subhashinie Koshalya Date: Tue, 2 Nov 2021 12:00:23 +0530 Subject: [PATCH 1/3] Fix sandbox endpoint invocation failure with apim --- .../choreo/connect/enforcer/api/RestAPI.java | 2 +- .../security/jwt/JWTAuthenticator.java | 2 +- .../connect/tests/apim/utils/StoreUtils.java | 26 ++++++++--- .../withapim/ExistingApiTestCase.java | 43 ++++++++++++++++--- .../test/resources/apimApisAppsSubs/apis.json | 12 ++++++ .../apimApisAppsSubs/applications.json | 4 ++ .../apimApisAppsSubs/subscriptions.json | 5 +++ .../test/resources/testng-cc-with-apim.xml | 1 + 8 files changed, 80 insertions(+), 15 deletions(-) diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/api/RestAPI.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/api/RestAPI.java index 73b18bb29e..e4790499ef 100644 --- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/api/RestAPI.java +++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/api/RestAPI.java @@ -123,7 +123,7 @@ public String init(Api api) { api.getEndpointSecurity().getProductionSecurityInfo())); } if (api.getEndpointSecurity().hasSandBoxSecurityInfo()) { - endpointSecurity.setProductionSecurityInfo( + endpointSecurity.setSandBoxSecurityInfo( APIProcessUtils.convertProtoEndpointSecurity( api.getEndpointSecurity().getSandBoxSecurityInfo())); } diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java index 6415bdff54..e58a8f6687 100644 --- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java +++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java @@ -229,7 +229,7 @@ public AuthenticationContext authenticate(RequestContext requestContext) throws securityInfo = requestContext.getMatchedAPI().getEndpointSecurity(). getSandBoxSecurityInfo(); } - if (securityInfo.isEnabled() && + if (securityInfo != null && securityInfo.isEnabled() && APIConstants.AUTHORIZATION_HEADER_BASIC. equalsIgnoreCase(securityInfo.getSecurityType())) { requestContext.getRemoveHeaders().remove(APIConstants.AUTHORIZATION_HEADER_DEFAULT diff --git a/integration/test-integration/src/test/java/org/wso2/choreo/connect/tests/apim/utils/StoreUtils.java b/integration/test-integration/src/test/java/org/wso2/choreo/connect/tests/apim/utils/StoreUtils.java index 79e186e379..e8fd38bf31 100644 --- a/integration/test-integration/src/test/java/org/wso2/choreo/connect/tests/apim/utils/StoreUtils.java +++ b/integration/test-integration/src/test/java/org/wso2/choreo/connect/tests/apim/utils/StoreUtils.java @@ -64,7 +64,8 @@ public static APIKeyDTO generateAPIKey(String applicationId, String keyType, Res public static String generateUserAccessToken(String apimServiceURLHttps, String applicationId, User user, RestAPIStoreImpl storeRestClient) throws CCTestException { - ApplicationKeyDTO applicationKeyDTO = StoreUtils.generateKeysForApp(applicationId, storeRestClient); + ApplicationKeyDTO applicationKeyDTO = StoreUtils.generateKeysForApp(applicationId, + ApplicationKeyGenerateRequestDTO.KeyTypeEnum.PRODUCTION, storeRestClient); Utils.delay(TestConstant.DEPLOYMENT_WAIT_TIME, "Interrupted while waiting for the " + "Applications Registration event to be received by the CC"); return StoreUtils.generateUserAccessToken(apimServiceURLHttps, @@ -72,6 +73,17 @@ public static String generateUserAccessToken(String apimServiceURLHttps, String new String[]{"PRODUCTION"}, user, storeRestClient); } + public static String generateUserAccessTokenSandbox(String apimServiceURLHttps, String applicationId, User user, + RestAPIStoreImpl storeRestClient) throws CCTestException { + ApplicationKeyDTO applicationKeyDTO = StoreUtils.generateKeysForApp(applicationId, + ApplicationKeyGenerateRequestDTO.KeyTypeEnum.SANDBOX, storeRestClient); + Utils.delay(TestConstant.DEPLOYMENT_WAIT_TIME, "Interrupted while waiting for the " + + "Applications Registration event to be received by the CC"); + return StoreUtils.generateUserAccessToken(apimServiceURLHttps, + applicationKeyDTO.getConsumerKey(), applicationKeyDTO.getConsumerSecret(), + new String[]{"SANDBOX"}, user, storeRestClient); + } + /** * Generate the user access token for the grant type password. * @@ -140,7 +152,8 @@ public static String subscribeToAPI(String apiId, String applicationId, String t public static AppWithConsumerKey createApplicationWithKeys(Application app, RestAPIStoreImpl storeRestClient) throws CCTestException { String applicationId = createApplication(app, storeRestClient); - ApplicationKeyDTO applicationKeyDTO = generateKeysForApp(applicationId, storeRestClient); + ApplicationKeyDTO applicationKeyDTO = generateKeysForApp(applicationId, + ApplicationKeyGenerateRequestDTO.KeyTypeEnum.PRODUCTION, storeRestClient); return new AppWithConsumerKey(applicationId, applicationKeyDTO.getConsumerKey(), applicationKeyDTO.getConsumerSecret()); } @@ -171,22 +184,23 @@ public static String createApplication(Application app, RestAPIStoreImpl storeRe * @return an ApplicationKeyDTO object containing Consumer key and Secret * @throws CCTestException if an error occurs while generating keys */ - public static ApplicationKeyDTO generateKeysForApp(String appId, RestAPIStoreImpl storeRestClient) throws CCTestException { + public static ApplicationKeyDTO generateKeysForApp(String appId, + ApplicationKeyGenerateRequestDTO.KeyTypeEnum keyType, + RestAPIStoreImpl storeRestClient) throws CCTestException { ArrayList grantTypes = new ArrayList<>(); grantTypes.add(APIMIntegrationConstants.GRANT_TYPE.PASSWORD); grantTypes.add(APIMIntegrationConstants.GRANT_TYPE.CLIENT_CREDENTIAL); ApplicationKeyDTO applicationKeyDTO; try { applicationKeyDTO = storeRestClient.generateKeys(appId, - TestConstant.DEFAULT_TOKEN_VALIDITY_TIME, "", - ApplicationKeyGenerateRequestDTO.KeyTypeEnum.PRODUCTION, - null, grantTypes); + TestConstant.DEFAULT_TOKEN_VALIDITY_TIME, "", keyType, null, grantTypes); } catch (ApiException e) { throw new CCTestException("Error while generating consumer keys from APIM Store", e); } return applicationKeyDTO; } + public static String getSubscriptionInfoString(String apiId, String applicationId, String tier) { return "API_Id:" + apiId + " Application_Id:" + applicationId + " Tier:" + tier; } diff --git a/integration/test-integration/src/test/java/org/wso2/choreo/connect/tests/testcases/withapim/ExistingApiTestCase.java b/integration/test-integration/src/test/java/org/wso2/choreo/connect/tests/testcases/withapim/ExistingApiTestCase.java index cd8884a038..0d189234b6 100644 --- a/integration/test-integration/src/test/java/org/wso2/choreo/connect/tests/testcases/withapim/ExistingApiTestCase.java +++ b/integration/test-integration/src/test/java/org/wso2/choreo/connect/tests/testcases/withapim/ExistingApiTestCase.java @@ -19,6 +19,7 @@ import com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.HttpStatus; import io.netty.handler.codec.http.HttpHeaderNames; +import org.testng.Assert; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import org.wso2.choreo.connect.mockbackend.ResponseConstants; @@ -26,13 +27,19 @@ import org.wso2.choreo.connect.tests.apim.ApimResourceProcessor; import org.wso2.choreo.connect.tests.apim.utils.StoreUtils; import org.wso2.choreo.connect.tests.context.CCTestException; +import org.wso2.choreo.connect.tests.util.HttpResponse; +import org.wso2.choreo.connect.tests.util.HttpsClientRequest; import org.wso2.choreo.connect.tests.util.TestConstant; +import org.wso2.choreo.connect.tests.util.Utils; import java.util.HashMap; import java.util.Map; public class ExistingApiTestCase extends ApimBaseTest { - private static final String VHOST_API_ENDPOINT = "vhostApi1/1.0.0/pet/findByStatus"; + private static final String API_NAME = "ExistingApi"; + private static final String API_CONTEXT = "existing_api"; + private static final String API_VERSION = "1.0.0"; + private static final String APP_NAME = "ExistingApiApp"; @BeforeClass(alwaysRun = true, description = "initialize setup") void setup() throws Exception { @@ -40,14 +47,36 @@ void setup() throws Exception { } @Test - public void testExistingApiWithSubscriptions() throws CCTestException { - String applicationId = ApimResourceProcessor.applicationNameToId.get(VhostApimTestCase.APPLICATION_NAME); + public void testExistingApiWithProdKey() throws Exception { + String applicationId = ApimResourceProcessor.applicationNameToId.get(APP_NAME); String accessToken = StoreUtils.generateUserAccessToken(apimServiceURLHttps, applicationId, user, storeRestClient); - Map requestHeaders = new HashMap<>(); - requestHeaders.put(TestConstant.AUTHORIZATION_HEADER, "Bearer " + accessToken); - requestHeaders.put(HttpHeaderNames.HOST.toString(), "localhost"); - VhostApimTestCase.testInvokeAPI(VHOST_API_ENDPOINT, requestHeaders, HttpStatus.SC_SUCCESS, ResponseConstants.RESPONSE_BODY); + Map headers = new HashMap<>(); + headers.put(TestConstant.AUTHORIZATION_HEADER, "Bearer " + accessToken); + headers.put(HttpHeaderNames.HOST.toString(), "localhost"); + + String endpoint = Utils.getServiceURLHttps(API_CONTEXT + "/1.0.0/pet/findByStatus"); + HttpResponse response = HttpsClientRequest.retryGetRequestUntilDeployed(endpoint, headers); + Assert.assertNotNull(response, "Error occurred while invoking the endpoint " + endpoint + " HttpResponse "); + Assert.assertEquals(response.getResponseCode(), HttpStatus.SC_SUCCESS, + "Status code mismatched. Endpoint:" + endpoint + " HttpResponse "); + } + + @Test + public void testExistingApiWithSandboxKey() throws Exception { + String applicationId = ApimResourceProcessor.applicationNameToId.get(APP_NAME); + String accessToken = StoreUtils.generateUserAccessTokenSandbox(apimServiceURLHttps, applicationId, + user, storeRestClient); + + Map headers = new HashMap<>(); + headers.put(TestConstant.AUTHORIZATION_HEADER, "Bearer " + accessToken); + headers.put(HttpHeaderNames.HOST.toString(), "localhost"); + + String endpoint = Utils.getServiceURLHttps(API_CONTEXT + "/1.0.0/pet/findByStatus"); + HttpResponse response = HttpsClientRequest.retryGetRequestUntilDeployed(endpoint, headers); + Assert.assertNotNull(response, "Error occurred while invoking the endpoint " + endpoint + " HttpResponse "); + Assert.assertEquals(response.getResponseCode(), HttpStatus.SC_SUCCESS, + "Status code mismatched. Endpoint:" + endpoint + " HttpResponse "); } } diff --git a/integration/test-integration/src/test/resources/apimApisAppsSubs/apis.json b/integration/test-integration/src/test/resources/apimApisAppsSubs/apis.json index 497689771d..fef91327e0 100644 --- a/integration/test-integration/src/test/resources/apimApisAppsSubs/apis.json +++ b/integration/test-integration/src/test/resources/apimApisAppsSubs/apis.json @@ -35,6 +35,18 @@ } ] }, + { + "name": "ExistingApi", + "version": "1.0.0", + "context": "existing_api", + "operationsDTOS": [ + { + "verb": "GET", + "target": "/pet/findByStatus", + "throttlingPolicy": "Unlimited" + } + ] + }, { "name": "SubscriptionValidationApi", "version": "1.0.0", diff --git a/integration/test-integration/src/test/resources/apimApisAppsSubs/applications.json b/integration/test-integration/src/test/resources/apimApisAppsSubs/applications.json index 33b175e7d1..75af22c8d7 100644 --- a/integration/test-integration/src/test/resources/apimApisAppsSubs/applications.json +++ b/integration/test-integration/src/test/resources/apimApisAppsSubs/applications.json @@ -11,6 +11,10 @@ "appName": "BlockedApiApp", "throttleTier": "Unlimited" }, + { + "appName": "ExistingApiApp", + "throttleTier": "Unlimited" + }, { "appName": "VHostApp", "throttleTier": "Unlimited" diff --git a/integration/test-integration/src/test/resources/apimApisAppsSubs/subscriptions.json b/integration/test-integration/src/test/resources/apimApisAppsSubs/subscriptions.json index a3efd8af0c..39ffcf19e9 100644 --- a/integration/test-integration/src/test/resources/apimApisAppsSubs/subscriptions.json +++ b/integration/test-integration/src/test/resources/apimApisAppsSubs/subscriptions.json @@ -9,6 +9,11 @@ "appName": "BlockedApiApp", "tier": "Unlimited" }, + { + "apiName": "ExistingApi", + "appName": "ExistingApiApp", + "tier": "Unlimited" + }, { "apiName": "VHostAPI1", "appName": "VHostApp", diff --git a/integration/test-integration/src/test/resources/testng-cc-with-apim.xml b/integration/test-integration/src/test/resources/testng-cc-with-apim.xml index 285ea3f39a..3e48cd9784 100644 --- a/integration/test-integration/src/test/resources/testng-cc-with-apim.xml +++ b/integration/test-integration/src/test/resources/testng-cc-with-apim.xml @@ -56,6 +56,7 @@ + From 45f7cb19ba022326011c322107d253a7e8381330 Mon Sep 17 00:00:00 2001 From: Subhashinie Koshalya Date: Tue, 2 Nov 2021 16:19:37 +0530 Subject: [PATCH 2/3] When exporterType is empty, set to Jaeger - @praminda --- .../wso2/choreo/connect/enforcer/tracing/TracerFactory.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/tracing/TracerFactory.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/tracing/TracerFactory.java index 6a86f25d03..fa141f2673 100644 --- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/tracing/TracerFactory.java +++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/tracing/TracerFactory.java @@ -65,8 +65,8 @@ public void initTracer() throws TracingException { // Future tracer implementations can be initialized from here if (StringUtils.isEmpty(exporterType)) { - logger.warn("Tracer exporter type not defined, defaulting to Azure Trace Exporter"); - exporterType = TracingConstants.AZURE_TRACE_EXPORTER; + logger.warn("Tracer exporter type not defined, defaulting to Jaeger Trace Exporter"); + exporterType = TracingConstants.JAEGER_TRACE_EXPORTER; } if (exporterType.equalsIgnoreCase(TracingConstants.AZURE_TRACE_EXPORTER)) { this.tracer = AzureExporter.getInstance().initTracer(properties); From 6315582ee5db9da54d0fde507211e3a60c9d36e5 Mon Sep 17 00:00:00 2001 From: Subhashinie Koshalya Date: Tue, 2 Nov 2021 18:01:54 +0530 Subject: [PATCH 3/3] Update keymapping key to consumerKey:keymanager in adapter - @VirajSalaka --- adapter/internal/eventhub/subscription.go | 3 ++- .../messaging/notification_listener.go | 22 ++++++++++--------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/adapter/internal/eventhub/subscription.go b/adapter/internal/eventhub/subscription.go index 086f47d227..e8909f3570 100644 --- a/adapter/internal/eventhub/subscription.go +++ b/adapter/internal/eventhub/subscription.go @@ -365,7 +365,8 @@ func retrieveSubscriptionDataFromChannel(response response) { appKeyMappingList = newResponse.(*types.ApplicationKeyMappingList) ResourceMap := make(map[string]*types.ApplicationKeyMapping) for index, keyMapping := range appKeyMappingList.List { - ResourceMap[keyMapping.ApplicationUUID] = &appKeyMappingList.List[index] + applicationKeyMappingReference := keyMapping.ConsumerKey + ":" + keyMapping.KeyManager + ResourceMap[applicationKeyMappingReference] = &appKeyMappingList.List[index] } ApplicationKeyMappingMap = ResourceMap xds.UpdateEnforcerApplicationKeyMappings(xds.MarshalKeyMappingMap(ApplicationKeyMappingMap)) diff --git a/adapter/internal/messaging/notification_listener.go b/adapter/internal/messaging/notification_listener.go index 7b7fc285fd..38967603c1 100644 --- a/adapter/internal/messaging/notification_listener.go +++ b/adapter/internal/messaging/notification_listener.go @@ -102,14 +102,14 @@ func handleAzureNotification() { } } -func processNotificationEvent (conf *config.Config, notification *msg.EventNotification) error { +func processNotificationEvent(conf *config.Config, notification *msg.EventNotification) error { var eventType string var decodedByte, err = base64.StdEncoding.DecodeString(notification.Event.PayloadData.Event) if err != nil { if _, ok := err.(base64.CorruptInputError); ok { logger.LoggerInternalMsg.Error("\nbase64 input is corrupt, check the provided key") } - logger.LoggerInternalMsg.Errorf("Error occurred while decoding the notification event %v. " + + logger.LoggerInternalMsg.Errorf("Error occurred while decoding the notification event %v. "+ "Hence dropping the event", err) return err } @@ -274,19 +274,21 @@ func handleApplicationEvents(data []byte, eventType string) { KeyManager: applicationRegistrationEvent.KeyManager, TenantID: -1, TenantDomain: applicationRegistrationEvent.TenantDomain, TimeStamp: applicationRegistrationEvent.TimeStamp, ApplicationUUID: applicationRegistrationEvent.ApplicationUUID} - if isLaterEvent(applicationKeyMappingTimeStampMap, fmt.Sprint(applicationRegistrationEvent.ApplicationID), + applicationKeyMappingReference := applicationKeyMapping.ConsumerKey + ":" + applicationKeyMapping.KeyManager + + if isLaterEvent(applicationKeyMappingTimeStampMap, fmt.Sprint(applicationKeyMappingReference), applicationRegistrationEvent.TimeStamp) { return } if strings.EqualFold(removeApplicationKeyMapping, eventType) { - delete(eh.ApplicationKeyMappingMap, applicationKeyMapping.ApplicationUUID) - logger.LoggerInternalMsg.Infof("Application Key Mapping for the applicationID %s is removed.", - applicationKeyMapping.ApplicationUUID) + delete(eh.ApplicationKeyMappingMap, applicationKeyMappingReference) + logger.LoggerInternalMsg.Infof("Application Key Mapping for the applicationKeyMappingReference %s is removed.", + applicationKeyMappingReference) } else { - eh.ApplicationKeyMappingMap[applicationKeyMapping.ApplicationUUID] = &applicationKeyMapping - logger.LoggerInternalMsg.Infof("Application Key Mapping for the applicationID %s is added.", - applicationKeyMapping.ApplicationUUID) + eh.ApplicationKeyMappingMap[applicationKeyMappingReference] = &applicationKeyMapping + logger.LoggerInternalMsg.Infof("Application Key Mapping for the applicationKeyMappingReference %s is added.", + applicationKeyMappingReference) } xds.UpdateEnforcerApplicationKeyMappings(xds.MarshalKeyMappingMap(eh.ApplicationKeyMappingMap)) @@ -445,7 +447,7 @@ func belongsToTenant(tenantDomain string) bool { func parseNotificationJSONEvent(data []byte, notification *msg.EventNotification) error { unmarshalErr := json.Unmarshal(data, ¬ification) if unmarshalErr != nil { - logger.LoggerInternalMsg.Errorf("Error occurred while unmarshalling " + + logger.LoggerInternalMsg.Errorf("Error occurred while unmarshalling "+ "notification event data %v. Hence dropping the event", unmarshalErr) } return unmarshalErr