You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by zr...@apache.org on 2020/01/06 09:36:54 UTC

[camel-website] branch capi-gateway-review created (now 9a980e9)

This is an automated email from the ASF dual-hosted git repository.

zregvart pushed a change to branch capi-gateway-review
in repository https://gitbox.apache.org/repos/asf/camel-website.git.


      at 9a980e9  refactor: spelling, grammar, and formatting

This branch includes the following new commits:

     new 9a980e9  refactor: spelling, grammar, and formatting

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[camel-website] 01/01: refactor: spelling, grammar, and formatting

Posted by zr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

zregvart pushed a commit to branch capi-gateway-review
in repository https://gitbox.apache.org/repos/asf/camel-website.git

commit 9a980e9a3221668ebe9bea26ddc65099f57afe88
Author: Zoran Regvart <zr...@apache.org>
AuthorDate: Mon Jan 6 10:36:49 2020 +0100

    refactor: spelling, grammar, and formatting
---
 content/blog/capi-gateway/index.md | 280 +++++++++++++++++++------------------
 1 file changed, 141 insertions(+), 139 deletions(-)

diff --git a/content/blog/capi-gateway/index.md b/content/blog/capi-gateway/index.md
index b90030f..f4fdf9a 100644
--- a/content/blog/capi-gateway/index.md
+++ b/content/blog/capi-gateway/index.md
@@ -6,22 +6,22 @@ categories: ["Usecases"]
 preview: CAPI Gateway
 ---
 
-I've been working at the European Commission for the last 4 years as a Software Architect, working for a unit responsible for developing reusable components, and advocating open source software. In this context, we organized already a couple of Hackathons and Bug bounties open to all the open source community.
+I've been working at the European Commission for the last 4 years as a Software Architect, working for a unit responsible for developing reusable components, and advocating open source software. In this context, we organized already a couple of Hackathons and Bug bounties open to all the open source communities.
 
-In the team we worked already a couple of times with Apache Camel, and i personally like the elegance and performance compared with other integration frameworks.
+In the team, we worked already a couple of times with Apache Camel, and I like the elegance and performance compared with other integration frameworks.
 
-Recently i was challenged to find alternatives to the existing API Gateway infrastructure, and immediately started to search for products implemented on top of Apache Camel.
+Recently I was challenged to find alternatives to the existing API Gateway infrastructure and immediately started to search for products implemented on top of Apache Camel.
 
-Not being able to find any solution with all we need to offer, i decided to work on a small POC with the following features:
+Not being able to find any solution with all we need to offer, I decided to work on a small POC with the following features:
 
 * Easy to customize API Gateway (since we have several customers, with a wide scope of needs and technologies, we need to be able to easily build custom components on top of an API Gateway core.) Ex.: Customize processors, Integrate with externals IdP, Implement custom API Manager Interface.)
 * Light and easy to install.
-* Decoupled components, Observality, Metrics, Database, API Manager Interface, Authorization and Gateway.
+* Decoupled components, Observability, Metrics, Database, API Manager Interface, Authorization, and Gateway.
 * Traffic management (Applied per API or API Path)
 * Automated traceability. (When a user deploys an API, we create Zipkin traces)
 * Automated Metrics (When a user deploys an API, we create Prometheus metrics)
 * Automated Dashboards (When a user deploys an API, we create Grafana dashboards)
-* Block API's after failed attempts.
+* Block APIs after failed attempts.
 * REST endpoints to manage your API's, Clients, Subscriptions, Certificates.
 * Authorization integration with Keycloak.
 
@@ -29,20 +29,20 @@ SO, WHY APACHE CAMEL?
 
 * Open Source.
 * Big and active community.
-* Fast and relyable.
+* Fast and reliable.
 * Deep integration with Spring Boot.
 * DSL Language.
 * Know-how in the team.
 * It supports all the integration patterns that you can remember.
 
-As part of the POC, i've decided already to combine other technologies:
+As part of the POC, I've decided already to combine other technologies:
 
 * Spring Boot
 * Hazelcast distributed cache
 * Prometheus
 * Grafana
 * Zipkin
-* Mongodb
+* MongoDB
 * Keycloak
 
 The POC is available, and currently being tested, already working with Apache Camel 3.0.0.
@@ -55,49 +55,51 @@ Let's then go for some technical details...
 ## Basic Route Definition
 
 ```
-          routeDefinition
-            .streamCaching()
-            .setHeader(...) //core headers
-            .process(authenticationProcessor)
-            .choice()
-                .when(...) //check execution of the authentication processor
-                .process(pathProcessor) //evaluates the path
-                .toF(toEndpoint) //proxy to the deployed backend
-                .removeHeader(...) //remove some core headers
-                .process(metricsProcessor) //process metrics
-
-            //api was not authenticated (ex.: expired token)
-            .otherwise()
-                .setHeader(...) //core error headers
-                .toF(apiGatewayErrorEndpoint) //proxy to default error endpoint
-                .removeHeader(...) //remove some core headers
-                .process(metricsProcessor) //process metrics
-                .end()
-                .setId(routeID);
+routeDefinition
+  .streamCaching()
+  .setHeader(...) //core headers
+  .process(authenticationProcessor)
+  .choice()
+      .when(...) //check execution of the authentication processor
+      .process(pathProcessor) //evaluates the path
+      .toF(toEndpoint) //proxy to the deployed backend
+      .removeHeader(...) //remove some core headers
+      .process(metricsProcessor) //process metrics
+
+  //api was not authenticated (ex.: expired token)
+  .otherwise()
+      .setHeader(...) //core error headers
+      .toF(apiGatewayErrorEndpoint) //proxy to default error endpoint
+      .removeHeader(...) //remove some core headers
+      .process(metricsProcessor) //process metrics
+      .end()
+      .setId(routeID);
 ```
 
 The *toEndpoint* contains the default configuration:
 
-     throwExceptionOnFailure=false //we will catch the exceptions
-     connectTimeout=...
-     bridgeEndpoint=true
-     copyHeaders=true
-     connectionClose=true
+```
+throwExceptionOnFailure=false //we will catch the exceptions
+connectTimeout=...
+bridgeEndpoint=true
+copyHeaders=true
+connectionClose=true
+```
 
 Since we want to be able to catch Network, IO exceptions we also do this on the route definition:
 
 ```
-          routeDefinition
-            .onException(exceptionClass)
-            .continued(continued)
-            .setHeader(...) //exception headers
-            .toF(apiGatewayErrorEndpoint) //proxy to default error endpoint
-            .removeHeader(...) //remove some core headers
-            .end();
+routeDefinition
+  .onException(exceptionClass)
+  .continued(continued)
+  .setHeader(...) //exception headers
+  .toF(apiGatewayErrorEndpoint) //proxy to default error endpoint
+  .removeHeader(...) //remove some core headers
+  .end();
 ```
 
-All information about a running API can be found in the shared cache. This allows the component that manages API's to know if an API must be suspended, or temporarily blocked (due to failed attempts and/or number of calls exceeding the defined threshold.)
-Information about a running API, includes:
+All information about a running API can be found in the shared cache. This allows the component that manages APIs to know if an API must be suspended or temporarily blocked (due to failed attempts and/or many calls exceeding the defined threshold.)
+Information about a running API includes:
 
 * Route ID
 * Secured
@@ -107,7 +109,7 @@ Information about a running API, includes:
 * Verb
 * Failed calls
 * Max allowed failed calls
-* Disabled (temporarily disabled, candidate to be removed)
+* Disabled (temporarily disabled, a candidate to be removed)
 * Removed (removed Route)
 * Suspended info (type [ERROR, THROTTLING] and reason)
 
@@ -119,110 +121,88 @@ Main components Managing enabled Routes:
 ## Example of an API definition
 
 ```
-    {
-        "_id" : "XXX-XXX-XXX-XXX",
-        "endpoint" : "remote.domain.com:8080",
-        "endpointType" : "HTTPS",
-        "name" : "Friendly API Name",
-        "secured" : true,
-        "context" : "context-name",
-        "swagger" : true,
-        "swaggerEndpoint" : "https://remote.domain.com:8080/v2/api-docs",
-        "blockIfInError" : true,
-        "maxAllowedFailedCalls" : 10, //after 10 failed calls, the route will be removed
-        "unblockAfter" : true,
-        "unblockAfterMinutes" : 2, //after 2 minutes of being removed, the route is added
-        //100 calls per minute, above this, the route is suspended.
-        "throttlingPolicy" : {
-            "maxCallsAllowed" : "100",
-            "periodForMaxCalls" : "60000",
-            "applyPerPath" : true
-        }
+{
+    "_id" : "XXX-XXX-XXX-XXX",
+    "endpoint" : "remote.domain.com:8080",
+    "endpointType" : "HTTPS",
+    "name" : "Friendly API Name",
+    "secured" : true,
+    "context" : "context-name",
+    "swagger" : true,
+    "swaggerEndpoint" : "https://remote.domain.com:8080/v2/api-docs",
+    "blockIfInError" : true,
+    "maxAllowedFailedCalls" : 10, //after 10 failed calls, the route will be removed
+    "unblockAfter" : true,
+    "unblockAfterMinutes" : 2, //after 2 minutes of being removed, the route is added
+    //100 calls per minute, above this, the route is suspended.
+    "throttlingPolicy" : {
+        "maxCallsAllowed" : "100",
+        "periodForMaxCalls" : "60000",
+        "applyPerPath" : true
     }
+}
 ```
 
 With the following configuration your service will be available at:
 
 ```
-    https://localhost:8380/gateway/context-name/
+https://localhost:8380/gateway/context-name/
 ```
 
 The following configuration will be applied:
 * secured: true - Meaning, that the CAPI Gateway expects a Bearer token sign by the authorization server (currently integrating with Keycloak) provided by the CAPI Rest Server.
 * blockIfInError: true - Means that for instance if you send more than 10 times (maxAllowedFailedCalls) the wrong token your API will be suspended for 2 minutes (unblockAfterMinutes).
 * throttlingPolicy.maxCallsAllowed: 100 / throttlingPolicy.periodForMaxCalls - You can only call your API/Path 100 times per minute.
-* throttlingPolicy.applyPerPath: true - If true the policy will be applied by path and NOT the total amount for the API.
+* throttlingPolicy.applyPerPath: true - If true the policy will be applied by the path and NOT the total amount for the API.
 
 ## Optional Configuration
-You can define your own paths, in case you dont have a Swagger Endpoint (Swagger 2/Open API), so if swagger: false, then CAPI will look for a list of PATH like the below example:
+You can define custom paths, in case you don't have a Swagger Endpoint (Swagger 2/Open API), so if swagger: false, then CAPI will look for a list of PATH like the below example:
 
 ```
-    {
-        "_id" : "XXX-XXX-XXX-XXX",
-        "endpoint" : "remote.domain.com:8080",
-        "endpointType" : "HTTPS",
-        "name" : "Friendly API Name",
-        //this time, the API will be available for everyone
-        "secured" : false,
-        "context" : "context-name",
-        "blockIfInError" : false,
-        //no swagger definition present, you need to define the available paths.
-        "swagger" : false,
-        "paths" : [
-            {
-            "verb" : "GET",
-            "path" : "/services/path"
-            },
-            {
-            "verb" : "POST",
-            "path" : "/services/path"
-            }
-        ]
-    }
+ {
+     "_id" : "XXX-XXX-XXX-XXX",
+     "endpoint" : "remote.domain.com:8080",
+     "endpointType" : "HTTPS",
+     "name" : "Friendly API Name",
+     //this time, the API will be available for everyone
+     "secured" : false,
+     "context" : "context-name",
+     "blockIfInError" : false,
+     //no swagger definition present, you need to define the available paths.
+     "swagger" : false,
+     "paths" : [
+         {
+         "verb" : "GET",
+         "path" : "/services/path"
+         },
+         {
+         "verb" : "POST",
+         "path" : "/services/path"
+         }
+     ]
+ }
 ```
 
 ## Client (consumer) object
 This will change after the integration with Keycloak.
-Example of  client (with the password: web-client-secret)
-
-```
-    {
-        "_id" : "XXX-XXX-XXX-XXX",
-        "clientId" : "web-publisher",
-        "resourceIds" : [],
-        "secretRequired" : true,
-        "clientSecret" : "$2a$10$oQBqS4ZOEiIGVNiZnB0nMuFw/n/Od57IG/uy4nFuOJxLtHE/Z5jDC",
-        "scoped" : false,
-        "scope" : [
-            "read-foo"
-        ],
-        "authorizedGrantTypes" : [
-            "refresh_token",
-            "client_credentials",
-        ],
-        "registeredRedirectUri" : [],
-        "authorities" : [
-            {
-                "role" : "ROLE_USER",
-                "_class" : "org.springframework.security.core.authority.SimpleGrantedAuthority"
-            },
-            {
-                "role" : "ROLE_PUBLISHER",
-                "_class" : "org.springframework.security.core.authority.SimpleGrantedAuthority"
-            }
-            // All the API's you subscribe will be an authority
-        ],
-        "accessTokenValiditySeconds" : 60,
-        "refreshTokenValiditySeconds" : 14400,
-        "autoApprove" : false
-    }
-```
-
-## Consuming your API
-If you wish to enable security for your API (api.secured = true), then you will need to subscribe your API with a *client*.
-Your API ID will be added as an authority in the authorities list of your client.
+Example of a client (with the password: web-client-secret)
 
 ```
+{
+    "_id" : "XXX-XXX-XXX-XXX",
+    "clientId" : "web-publisher",
+    "resourceIds" : [],
+    "secretRequired" : true,
+    "clientSecret" : "$2a$10$oQBqS4ZOEiIGVNiZnB0nMuFw/n/Od57IG/uy4nFuOJxLtHE/Z5jDC",
+    "scoped" : false,
+    "scope" : [
+        "read-foo"
+    ],
+    "authorizedGrantTypes" : [
+        "refresh_token",
+        "client_credentials",
+    ],
+    "registeredRedirectUri" : [],
     "authorities" : [
         {
             "role" : "ROLE_USER",
@@ -231,12 +211,34 @@ Your API ID will be added as an authority in the authorities list of your client
         {
             "role" : "ROLE_PUBLISHER",
             "_class" : "org.springframework.security.core.authority.SimpleGrantedAuthority"
-        },
-        {
-            "role" : "YOUR API ID",
-            "_class" : "org.springframework.security.core.authority.SimpleGrantedAuthority"
         }
-    ]
+        // All the API's you subscribe will be an authority
+    ],
+    "accessTokenValiditySeconds" : 60,
+    "refreshTokenValiditySeconds" : 14400,
+    "autoApprove" : false
+}
+```
+
+## Consuming your API
+If you wish to enable security for your API (api.secured = true), then you will need to define a *client*.
+Your API ID will be added as an authority in the authorities list of your client.
+
+```
+"authorities" : [
+    {
+        "role" : "ROLE_USER",
+        "_class" : "org.springframework.security.core.authority.SimpleGrantedAuthority"
+    },
+    {
+        "role" : "ROLE_PUBLISHER",
+        "_class" : "org.springframework.security.core.authority.SimpleGrantedAuthority"
+    },
+    {
+        "role" : "YOUR API ID",
+        "_class" : "org.springframework.security.core.authority.SimpleGrantedAuthority"
+    }
+]
 ```
 
 ## Play with CAPI Gateway
@@ -244,26 +246,27 @@ Your API ID will be added as an authority in the authorities list of your client
 * Execute
 
 ```
-        $ sudo docker-compose up -d
+$ sudo docker-compose up -d
 ```
 
-* If you are starting a fresh Mongo instance, a default CAPI Client will be created for you.
+* If you are starting a new MongoDB instance, a default CAPI Client will be created for you.
 * Request your first access token:
 
 ```
-      curl -X POST https://localhost:8080/oauth/token -H 'Authorization: Basic d2ViLXB1Ymxpc2hlcjp3ZWItY2xpZW50LXNlY3JldA==' -H 'Content-Type: multipart/form-data;' -F grant_type=client_credentials -F 'response_type=access_token'
+$ curl -X POST https://localhost:8080/oauth/token -H 'Authorization: Basic d2ViLXB1Ymxpc2hlcjp3ZWItY2xpZW50LXNlY3JldA==' -H 'Content-Type: multipart/form-data;' -F grant_type=client_credentials -F 'response_type=access_token'
 ```
 
-* Go to: http://localhost:8080/swagger-ui.html
+* Go to http://localhost:8080/swagger-ui.html
 * Authenticate with the token you obtained from the previous step. (Don't forget to specify: Bearer _the token_)
 * Publish your first API:
+
 ```
-         curl -X POST "http://localhost:8080/route/simple-rest" -H "accept: application/json" -H "Content-Type: application/json" -d "<your-api>" (see Example of an API definition)
+$ curl -X POST "http://localhost:8080/route/simple-rest" -H "accept: application/json" -H "Content-Type: application/json" -d "<your-api>" (see Example of an API definition)
 ```
 
 * Imagine that your context was: test and one of your GET path was /user you can then test: http://localhost:8380/gateway/test/user
 
-Docker compose will create instances of Grafana, Prometheus and Zipkin, but if you wish to use already existing instances you just need to change this environment variables:
+Docker Compose will create instances of Grafana, Prometheus and Zipkin, but if you wish to use already existing instances you just need to change this environment variables:
 
 * api.gateway.prometheus.endpoint=http://prometheus:9090
 * api.gateway.zipkin.endpoint=http://zipkin:9411/api/v2/spans
@@ -300,6 +303,5 @@ Docker compose will create instances of Grafana, Prometheus and Zipkin, but if y
     Waiting:        3  796 883.3    681   13862
     Total:         58 3229 1683.6   3091   18639
 
-It would be amazing to have feedback from the Apache Camel Community. If you have any question, feel free to contact me.
-The repo is located at: https://github.com/rodrigoserracoelho/capi-gateway
-
+It would be amazing to have feedback from the Apache Camel Community. If you have any questions, feel free to contact me.
+The repo is located at https://github.com/rodrigoserracoelho/capi-gateway