Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Building a Microgateway in Ballerina_KubeCon 2108

89 views

Published on

API gateways play a critical role in modern enterprise architecture. As microservices strengthen their hold on modern-day application architectures, cloud native API gateways are high in demand. Ballerina, being a programming language designed to address and simplify the complexities of heavily distributed systems primarily built on microservice architectures, provides a rich set of language features and a smart compiler that makes it a good choice of technology to build a cloud native API gateway.

Published in: Software
  • Be the first to comment

  • Be the first to like this

Building a Microgateway in Ballerina_KubeCon 2108

  1. 1. Building a Microgateway in Ballerina Nuwan Dias Director - API Architecture, WSO2 @nuwandias
  2. 2. API Gateway
  3. 3. API Gateway CLIENT DEVICES API GATEWAY MICROSERVICE
  4. 4. API Gateway - What does it do? ○ Request forwarding ○ URL rewrite ○ Load-balancing ○ Failover ○ Circuit breaking ○ Inbound and outbound security ○ Authentication and authorization ○ OAuth2, OIDC, API Keys, Basic auth, Digital signatures, MTLS, etc. ○ Rate limiting ○ Analytics
  5. 5. Ballerina Service
  6. 6. Ballerina Service @http:ServiceConfig { basePath:"/pizzashack/1.0.0" } service passthrough on new http:Listener (9090) { @http:ResourceConfig { methods:["GET"], path:"/menu" } resource function getMenu (http:Caller caller, http:Request req) { //contains request forwarding logic to target. } }
  7. 7. OAS (Swagger) document becomes the source of the service definition OAS DOCUMENT
  8. 8. Generating the Ballerina service OAS DOCUMENT Auto generate the Ballerina source code from OAS.
  9. 9. Connecting to the target endpoint Target endpoint
  10. 10. Forwarding request to the target http:Client targetEndpoint = new ("https://api.pizzastore.com/pizzashack/v1"); @http:ServiceConfig { basePath: "/pizzashack/1.0.0" } service passthrough on new http:Listener (9090) { @http:ResourceConfig { methods:["GET"], path:"/menu" } resource function getMenu (http:Caller caller, http:Request req) { . . . . . . . } }
  11. 11. Forwarding request to the target resource function getMenu (http:Caller caller, http:Request req) { //Forward the client request to the /menu resource of the Target Endpoint. var clientResponse = targetEndpoint -> forward(“/menu”, req); //Check if the response from the target Endpoint was a success or not. if clientResponse is http:Response{ var result = caller->respond(res); if result is error { log:printError("Error sending response"); } } else { http:Response res = new; res.statusCode = 500; res.setPayload(err.message); var result = caller->respond(res); if result is error { log:printError("Error sending response"); } }
  12. 12. Request Filters
  13. 13. Ballerina filter chain FILTER1 FILTER2 FILTERn
  14. 14. Listeners and Filters service passthrough on new http:Listener (9090) { import wso2/gateway; AuthnFilter authnFilter; OAuthzFilter authzFilter; RateLimitFilter rateLimitFilter; AnalyticsFilter analyticsFilter; ExtensionFilter extensionFilter; listener gateway:APIGatewayListener apiListener = new (9095, { filters:[authnFilter, authzFilter, rateLimitFilter, analyticsFilter, extensionFilter] }); service passthrough on apiListener { A listener is what a service binds itself to. A listener may have one or more filters to filter requests being received on the port of the listener.
  15. 15. Security
  16. 16. Authentication listener gateway:APIGatewayListener apiListener = new (9095, { filters:[authnFilter, authzFilter]}, { authProviders:[jwtAuthProvider, basic] }); http:AuthProvider jwtAuthProvider = { scheme:"jwt", issuer:"ballerina", audience: "ballerina.io", certificateAlias: "ballerina", trustStore: { path: "${ballerina.home}/bre/security/ballerinaTr uststore.p12", password: "ballerina" } }; The microgateway supports different authentication mechanisms such as OAuth2, basic authentication, etc. Which mechanisms to apply against a request is decided by the declared authentication providers in the listener.
  17. 17. Enabling/Disabling security by service //This service is accessible at // /pizzashack/1.0.0 on port 9095 @http:ServiceConfig { basePath: "/pizzashack/1.0.0", authConfig: { authentication: { enabled: true } } } service passthrough on apiListener { . . . . . . . . . . } Each service bound to the listener can chose to enable or disable security by itself.
  18. 18. Authorization Authorization is enabled per each operation of the service using ‘scopes’. Scopes are used as a means of abstracting the authorization mechanism. @http:ResourceConfig { methods:["PUT"], path:"/menu", authConfig: { scopes: ["edit_menu"] } } resource function editMenu (http:Caller caller, http:Request req)
  19. 19. Microgateway in-bound security architecture. CLIENT DEVICES MICROGATEWAY MICROSERVICE SECURITY TOKEN SERVICE 1 OBTAIN TOKEN FROM STS 2 SEND TOKEN TO MICROGATEWAY WITH REQUEST 3 OPTIONAL VALIDATION REQUEST FROM MICROGATEWAY TO STS 4 FORWARD REQUEST TO TARGET
  20. 20. Rate Limiting
  21. 21. Ballerina Streams The RateLimitFilter on the listener adds metadata of every successful request into a data-stream. public stream<RequestStreamDTO> requestStream; public function publishNonThrottleEvent(RequestStreamDTO request) { requestStream.publish(request); }
  22. 22. Rate limiting Policies Rate limiting policies on the microgateway are modelled as stream processors where it executes logic on the data received via the stream. forever { from gateway:requestStream select messageID, (tier == "Silver") as isEligible, subscriptionKey as throttleKey => (gateway:EligibilityStreamDTO[] counts) { eligibilityStream.publish(counts); } from eligibilityStream throttler:timeBatch(60000, 0) where isEligible == true select throttleKey, count(messageID) >= 2000 as isThrottled, expiryTimeStamp group by throttleKey => (gateway:GlobalThrottleStreamDTO[] counts) { resultStream.publish(counts); }
  23. 23. Analytics
  24. 24. Microgateway analytics architecture. CLIENT DEVICES MICROGATEWAY ANALYTICS ENGINE 1 SEND REQUEST TO MICROGATEWAY 2 WRITE REQUEST META-DATA TO FILE SYSTEM 3 PERIODICALLY READ DATA FROM FILE SYSTEM 4 UPLOAD DATA TO ANALYTICS ENGINE FOR PROCESSING BALLERINA BASED PERIODIC TASK
  25. 25. Using Ballerina Streams to avoid write-lock contentions on the file system public function filterRequest(http:Request request, http:FilterContext context) returns http:FilterResult { http:FilterResult requestFilterResult; AnalyticsRequestStream requestStream = generateRequestEvent(request, context); EventDTO eventDto = generateEventFromRequest(requestStream); eventStream.publish(eventDto); requestFilterResult = { canProceed: true, statusCode: 200, message: "Analytics filter processed." }; return requestFilterResult; } SERVICE 1 SERVICE 2 SERVICE 3 EVENT STREAM FILE SYSTEM
  26. 26. Ballerina Character I/O API for writing data to file io:ByteChannel channel = io:openFile("api-usage-data.dat", io:APPEND); io:CharacterChannel charChannel = new(channel, "UTF-8"); try { match charChannel.write(getEventData(eventDTO),0) { . . . . . . . . } } finally { match charChannel.close() { . . . . . . . . } }
  27. 27. Docker and Kubernetes
  28. 28. Ballerina @docker annotations The @docker annotations help us build docker images of the microgateway @docker:Expose{} listener gateway:APIGatewayListener apiListener = new (9095, { filters:[authnFilter, authzFilter, rateLimitFilter, analyticsFilter, extensionFilter] }); @docker:Config { registry:"private.docker.gateway.com", name:"passthrough", tag:"v1.0" } service passthrough on apiListener { . . . . . . }
  29. 29. Microgateway build process to build docker images OAS PROJECT Generate Ballerina source code from OAS document Compile Ballerina project to build docker image of microgateway
  30. 30. Ballerina @kubernetes annotations The @kubernetes annotations help easily deploy the microgateway to kubernetes. @kubernetes:Service { sessionAffinity: "ClientIP" } listener gateway:APIGatewayListener apiListener = new (9095, { filters:[authnFilter, authzFilter, rateLimitFilter, analyticsFilter, extensionFilter] }); @kubernetes:Deployment { name: "passthrough", replicas: 3, labels: { "location": "WA", "city": "SEA" }, enableLiveness: true, livenessPort: 9099, singleYAML: false } service passthrough on apiListener { . . . . . .
  31. 31. Microgateway build process to build kubernetes deployment artifacts OAS PROJECT Generate Ballerina source code from OAS document Compile Ballerina project to build k8s deployment artifacts of microgateway
  32. 32. More information https://www.infoq.com/articles/ballerina-api-gateway
  33. 33. Q & A
  34. 34. THANK YOU

×