diff --git a/adapter/internal/oasparser/model/adapter_internal_api.go b/adapter/internal/oasparser/model/adapter_internal_api.go index 3cdfe66c9..7bdd62768 100644 --- a/adapter/internal/oasparser/model/adapter_internal_api.go +++ b/adapter/internal/oasparser/model/adapter_internal_api.go @@ -26,7 +26,6 @@ import ( "time" "github.com/google/uuid" - "github.com/sirupsen/logrus" "github.com/wso2/apk/adapter/config" "github.com/wso2/apk/adapter/internal/interceptor" "github.com/wso2/apk/adapter/internal/loggers" @@ -1297,15 +1296,6 @@ func (adapterInternalAPI *AdapterInternalAPI) SetInfoGRPCRouteCR(grpcRoute *gwap Name: string(filter.ExtensionRef.Name), Namespace: grpcRoute.Namespace, }.String()]; found { - logrus.Info("filter.ExtensionRef.Kind == constants.KindAPIPolicy") - logrus.Info(apiPolicy.Name) - logrus.Info(apiPolicy.Name) - if apiPolicy.Spec.Default != nil { - logrus.Info(apiPolicy.Spec.Default.RequestInterceptors) - } - if apiPolicy.Spec.Default != nil { - logrus.Info(apiPolicy.Spec.Default.ResponseInterceptors) - } resourceAPIPolicy = concatAPIPolicies(apiPolicy, &ref) } else { return fmt.Errorf(`apipolicy: %s has not been resolved, spec.targetRef.kind should be diff --git a/adapter/internal/operator/controllers/dp/api_controller.go b/adapter/internal/operator/controllers/dp/api_controller.go index 2cc69d699..44c2b5852 100644 --- a/adapter/internal/operator/controllers/dp/api_controller.go +++ b/adapter/internal/operator/controllers/dp/api_controller.go @@ -1089,36 +1089,6 @@ func (apiReconciler *APIReconciler) getResolvedBackendsMappingForGRPC(ctx contex } } } - - for _, filter := range rule.Filters { - if filter.RequestMirror != nil { - mirrorBackend := filter.RequestMirror.BackendRef - mirrorBackendNamespacedName := types.NamespacedName{ - Name: string(mirrorBackend.Name), - Namespace: utils.GetNamespace(mirrorBackend.Namespace, grpcRoute.Namespace), - } - if string(*mirrorBackend.Kind) == constants.KindBackend { - if _, exists := backendMapping[mirrorBackendNamespacedName.String()]; !exists { - resolvedMirrorBackend := utils.GetResolvedBackend(ctx, apiReconciler.client, mirrorBackendNamespacedName, &api) - if resolvedMirrorBackend != nil { - backendMapping[mirrorBackendNamespacedName.String()] = resolvedMirrorBackend - } else { - return nil, fmt.Errorf("unable to find backend %s", mirrorBackendNamespacedName.String()) - } - } - } else if string(*mirrorBackend.Kind) == constants.KindService { - var err error - service, err := utils.GetService(ctx, apiReconciler.client, utils.GetNamespace(mirrorBackend.Namespace, grpcRoute.Namespace), string(mirrorBackend.Name)) - if err != nil { - return nil, fmt.Errorf("unable to find service %s", mirrorBackendNamespacedName.String()) - } - backendMapping[mirrorBackendNamespacedName.String()], err = utils.GetResolvedBackendFromService(service, int(*mirrorBackend.Port)) - if err != nil { - return nil, fmt.Errorf("error in getting service information %s", service) - } - } - } - } } // Resolve backends in InterceptorServices diff --git a/test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/BaseSteps.java b/test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/BaseSteps.java index e7245f198..50ce6d88d 100644 --- a/test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/BaseSteps.java +++ b/test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/BaseSteps.java @@ -78,6 +78,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import io.cucumber.java.en.And; import io.grpc.Status; import io.grpc.StatusRuntimeException; @@ -248,6 +249,18 @@ public void GetStudent(String arg0, int arg1) throws StatusRuntimeException { } } + @And("the GRPC response should contain header {string}") + public void GetGRPCMetadata(String arg0) throws StatusRuntimeException { + try { + String header = SimpleGRPCStudentClient.getResponseHeader(arg0); + Assert.assertNotNull(header); + Assert.assertEquals(header, "Interceptor-Response-header-value"); + } catch (StatusRuntimeException e) { + sharedContext.setGrpcStatusCode(e.getStatus().getCode().value()); + logger.error(e.getMessage() + " Status code: " + e.getStatus().getCode().value()); + } + } + @Then("I make grpc request GetStudent default version to {string} with port {int}") public void GetStudentDefaultVersion(String arg0, int arg1) throws StatusRuntimeException { try { @@ -329,8 +342,9 @@ public void checkEnforcerLogs(DataTable dataTable) throws IOException, Interrupt } try { String logs = api.readNamespacedPodLog(podName, namespace).container("enforcer").sinceSeconds(60).execute(); - Assert.assertNotNull(logs, String.format("Could not find any logs in the last 60 seconds. PodName: %s, namespace: %s", podName, namespace)); - for(String word : stringsToCheck) { + Assert.assertNotNull(logs, String.format( + "Could not find any logs in the last 60 seconds. PodName: %s, namespace: %s", podName, namespace)); + for (String word : stringsToCheck) { Assert.assertTrue(logs.contains(word), "Expected word '" + word + "' not found in logs"); } } catch (ApiException e) { diff --git a/test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/GenericClientInterceptor.java b/test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/GenericClientInterceptor.java index 0467b66f1..7d435b2c3 100644 --- a/test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/GenericClientInterceptor.java +++ b/test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/GenericClientInterceptor.java @@ -2,6 +2,8 @@ import io.grpc.ClientInterceptor; import io.grpc.ForwardingClientCall; +import io.grpc.ForwardingClientCall.SimpleForwardingClientCall; +import io.grpc.ForwardingClientCallListener.SimpleForwardingClientCallListener; import io.grpc.Metadata; import io.grpc.MethodDescriptor; import io.grpc.CallOptions; @@ -9,16 +11,23 @@ import io.grpc.Channel; import java.util.Map; -import java.util.Map; - public class GenericClientInterceptor implements ClientInterceptor { private Map headers; + private Metadata responseHeaders; public GenericClientInterceptor(Map headers) { this.headers = headers; } + public void setResponseHeaders(Metadata responseHeaders) { + this.responseHeaders = responseHeaders; + } + + public Metadata getResponseHeaders() { + return this.responseHeaders; + } + @Override public ClientCall interceptCall( MethodDescriptor method, CallOptions callOptions, Channel next) { @@ -31,7 +40,18 @@ public void start(Listener responseListener, Metadata headersMetadata) { headers.forEach((key, value) -> headersMetadata.put( Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER), value)); - super.start(responseListener, headersMetadata); + super.start(new SimpleForwardingClientCallListener(responseListener) { + @Override + public void onHeaders(Metadata headers) { + /** + * if you don't need receive header from server, + * you can use {@link io.grpc.stub.MetadataUtils#attachHeaders} + * directly to send header + */ + setResponseHeaders(headers); + super.onHeaders(headers); + } + }, headersMetadata); } }; } diff --git a/test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/clients/SimpleGRPCStudentClient.java b/test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/clients/SimpleGRPCStudentClient.java index 359b9eb86..92c1eba87 100644 --- a/test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/clients/SimpleGRPCStudentClient.java +++ b/test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/clients/SimpleGRPCStudentClient.java @@ -9,6 +9,8 @@ import org.apache.commons.logging.LogFactory; import io.grpc.ManagedChannel; +import io.grpc.Metadata; + import org.wso2.apk.integration.utils.GenericClientInterceptor; import org.wso2.apk.integration.utils.clients.student_service.StudentRequest; import org.wso2.apk.integration.utils.clients.student_service.StudentResponse; @@ -24,6 +26,7 @@ public class SimpleGRPCStudentClient { private static final int EVENTUAL_SUCCESS_RESPONSE_TIMEOUT_IN_SECONDS = 10; private final String host; private final int port; + private static Metadata responseHeaders; public SimpleGRPCStudentClient(String host, int port) { this.host = host; @@ -53,6 +56,7 @@ public StudentResponse GetStudent(Map headers) throws StatusRunt log.error("Failed to get student"); throw new RuntimeException("Failed to get student"); } + setResponseHeaders(interceptor.getResponseHeaders()); return response; } catch (SSLException e) { throw new RuntimeException("Failed to create SSL context", e); @@ -72,6 +76,18 @@ public StudentResponse GetStudent(Map headers) throws StatusRunt } } + public static String getResponseHeader(String headerName) { + Metadata.Key headerValue = Metadata.Key.of(headerName, Metadata.ASCII_STRING_MARSHALLER); + if (responseHeaders == null) { + return ""; + } + return responseHeaders.get(headerValue); + } + + public void setResponseHeaders(Metadata metadata) { + SimpleGRPCStudentClient.responseHeaders = metadata; + } + public StudentResponse GetStudentDefaultVersion(Map headers) throws StatusRuntimeException { ManagedChannel managedChannel = null; try { diff --git a/test/cucumber-tests/src/test/resources/artifacts/apk-confs/grpc/grpc-interceptor.apk-conf b/test/cucumber-tests/src/test/resources/artifacts/apk-confs/grpc/grpc-interceptor.apk-conf new file mode 100644 index 000000000..2b4318225 --- /dev/null +++ b/test/cucumber-tests/src/test/resources/artifacts/apk-confs/grpc/grpc-interceptor.apk-conf @@ -0,0 +1,44 @@ +name: "6a254687f3229c35dd0189aac7f7fc4b6228e97a" +basePath: "/org.apk" +version: "v1" +type: "GRPC" +id: "grpc-interceptor-api" +endpointConfigurations: + production: + endpoint: "http://grpc-backend:6565" +defaultVersion: false +subscriptionValidation: false +operations: + - target: "student_service.StudentService" + verb: "GetStudent" + secured: true + scopes: [] + - target: "student_service.StudentService" + verb: "GetStudentStream" + secured: true + scopes: [] + - target: "student_service.StudentService" + verb: "SendStudentStream" + secured: true + scopes: [] + - target: "student_service.StudentService" + verb: "SendAndGetStudentStream" + secured: true + scopes: [] +apiPolicies: + request: + - policyName: "Interceptor" + policyVersion: v1 + parameters: + backendUrl: "http://interceptor-service.apk-integration-test.svc.cluster.local:8443" + contextEnabled: true + headersEnabled: true + bodyEnabled: true + response: + - policyName: "Interceptor" + policyVersion: v1 + parameters: + backendUrl: "http://interceptor-service.apk-integration-test.svc.cluster.local:8443" + contextEnabled: true + headersEnabled: true + bodyEnabled: true diff --git a/test/cucumber-tests/src/test/resources/tests/api/GRPC.feature b/test/cucumber-tests/src/test/resources/tests/api/GRPC.feature index dfbcc8f57..39dbf6ae3 100644 --- a/test/cucumber-tests/src/test/resources/tests/api/GRPC.feature +++ b/test/cucumber-tests/src/test/resources/tests/api/GRPC.feature @@ -120,4 +120,25 @@ Feature: Generating APK conf for gRPC API Given The system is ready And I have a valid subscription When I undeploy the API whose ID is "grpc-default-version-api" + Then the response status code should be 202 + + Scenario: Deploying gRPC API with interceptor policy + Given The system is ready + And I have a valid subscription + When I use the APK Conf file "artifacts/apk-confs/grpc/grpc-interceptor.apk-conf" + And the definition file "artifacts/definitions/student.proto" + And make the API deployment request + Then the response status code should be 200 + Then I set headers + | Authorization | bearer ${accessToken} | + And I make grpc request GetStudent to "default.gw.wso2.com" with port 9095 + And the gRPC response status code should be 0 + And the student response body should contain name: "Student" age: 10 + And the GRPC response should contain header "interceptor-response-header" + + + Scenario: Undeploy API + Given The system is ready + And I have a valid subscription + When I undeploy the API whose ID is "grpc-interceptor-api" Then the response status code should be 202 \ No newline at end of file