Hi all, - In the previous mail, it was mentioned that, when providing the etcd keys, the config value used will be Worldbank_1.0.0_prod encoded to base64 format and then adding the etcdKey suffix to this encoded value. - But most of the time, when a value is encoded to base64 format, the encoded value will contain a "=" character. For example, when Worldbank_1.0.0_prod is encoded, the encoded value will be "V29ybGRCYW5rXzEuMC4wX3Byb2Q=". - So when the suffix etcdKey is added, the final value will be "V29ybGRCYW5rXzEuMC4wX3Byb2Q=_etcdKey". - This value will be provided when the microgateway is started using the bash gateway command as a CLI parameter with the -e flag. ( bash gateway -e V29ybGRCYW5rXzEuMC4wX3Byb2Q=_etcdKey=worldbankprod...... )
- But since the config value contains a "=" character, ballerina splits the config value and the parameter value using the first "=" character. config value = V29ybGRCYW5rXzEuMC4wX3Byb2Q parameter value = _etcdKey=worldbankprod - Because of this problem, it was decided to use the API ID as the prefix of the config value, append it with "prod" or "sand" and then add the etcdKey suffix to the resultant value. For production endpoint etcd key : <API_ID>_prod_etcdKey For sandbox endpoint etcd key : <API_ID>_sand_etcdKey - Since the microgateway can be created using 2 approaches, there are 2 scenarios when using the API ID. *Approach 1: Creating the microgateway by specifying the API name or label* - In this approach, the API details are fetched from the API manager. This detail contains the API ID for the relevant API. *Approach 2: Creating the microgateway using an open-api definition file* - In this approach, a random UUID will be generated as the API ID. - When a microgateway is created using the setup command, the API ID will be displayed in the console as well as it will be written to the generated API source file. [image: mgw-with-api-id.png] *Conclusion* - Assume that the API ID for the Worldbank API is "90b1d415-bc9c-4f15-884b-73ece9725746" - The bash gateway command would look as shown below. bash gateway -e 90b1d415-bc9c-4f15-884b-73ece9725746_prod_etcdKey=worldbankprod -e 90b1d415-bc9c-4f15-884b-73ece9725746_sand_etcdKey=worldbanksand -e etcdurl= http://127.0.0.1:2379 -e etcdusername=etcd -e etcdpassword=etcd -e etcdtimer=10000 Thanks! On Fri, Jan 18, 2019 at 5:25 PM Hisan Hunais <[email protected]> wrote: > Hi all, > > - In the previous mail, it was mentioned that the bash gateway command > would look as shown below. > > bash gateway -e WorldBank.1.0.0.prod.etcd.key=worldbankprod -e > WorldBank.1.0.0.sand.etcd.key=worldbanksand -e etcdurl= > http://127.0.0.1:2379 -e etcdusername=etcd -e etcdpassword=etcd -e > etcdtimer=10000 > > WorldBank.1.0.0.prod.etcd.key=worldbankprod (CLI parameter) > WorldBank.1.0.0.prod.etcd.key (Parameter config value) > worldbankprod (Parameter value) > > - Two problems were encountered when using this approach. > > > *Problem 1: Cannot use "." character in environment variables. So unable > to provide these parameters when the microgateway runs in docker* > > - When running the microgateway in docker, the above parameters have > to be provided as environment variables. But the "." character is not > allowed in environment variables. So we cannot provide the > "WorldBank.1.0.0.prod.etcd.key" parameter config value to docker. > - Because of this, it was decided to replace the "." character with > the "_" character. > > > *Problem 2: Problem if the API name consists of characters from other > languages such as Chinese* > > - In the parameter config value "WorldBank.1.0.0.prod.etcd.key", > WorldBank is the API name, 1.0.0 is the API version, prod is to indicate > whether its production or sandbox and etcd.key is a suffix to identify that > the parameter is related to the etcd key. > - So if the API name consists of characters from other languages such > as Chinese, it will be difficult to provide this parameter. As a solution, > it was decided to encode the prefix of the parameter config value to base64 > format and then add the relevant suffix. > > > *Steps that are used to get the final parameter value* > > - The "." character will be replaced with the "_" character. Then > parameter config value prefix would look like below. > > WorldBank_1.0.0_prod > > - This value will be encoded to base64 format. > > V29ybGRCYW5rXzEuMC4wX3Byb2Q= > > - Then the suffix of etcdKey will be added to this base64 formatted > value > > V29ybGRCYW5rXzEuMC4wX3Byb2Q=_etcdKey > > - So the final parameter would look like below > > V29ybGRCYW5rXzEuMC4wX3Byb2Q=_etcdKey=worldbankprod > > > *Conclusion* > > - The bash gateway command would look as shown below > > bash gateway -e V29ybGRCYW5rXzEuMC4wX3Byb2Q=_etcdKey=worldbankprod -e > V29ybGRCYW5rXzEuMC4wX3NhbmQ=_etcdKey=worldbanksand -e etcdurl= > http://127.0.0.1:2379 -e etcdusername=etcd -e etcdpassword=etcd -e > etcdtimer=10000 > > Thank you! > > On Tue, Jan 8, 2019 at 11:25 AM Hisan Hunais <[email protected]> wrote: > >> Hi all, >> >> This is to mention some of the changes and additions that have been made >> to the initial design, which was described in the previous email. >> >> In the previous mail, it was mentioned that only the etcd URL and etcd >> keys are taken during the bash gateway command. In addition to those, the >> following arguments also need to be provided. >> >> - etcd username >> - etcd password >> - etcd timer - the time period for the periodic timer task >> >> The bash gateway command would look like this. >> bash gateway -e WorldBank.1.0.0.prod.etcd.key=worldbankprod -e >> WorldBank.1.0.0.sand.etcd.key=worldbanksand -e etcdurl= >> http://127.0.0.1:2379 -e etcdusername=etcd -e etcdpassword=etcd -e >> etcdtimer=10000 >> >> - WorldBank.1.0.0.prod.etcd.key and WorldBank.1.0.0.sand.etcd.key are >> the config values to retrieve the etcd keys relevant for the >> production and sandbox endpoint of the world bank API. >> >> Since there are several arguments to be provided, there may be situations >> where some arguments which are provided are invalid or not provided at all. >> In such situations, the fallbacks have been shown in the diagram attached >> below. >> >> As mentioned in the previous mail, etcd can be enabled using the -etcd >> flag during the micorgateway setup command. If etcd is enabled, the >> generated ballerina file(WorldBank_1_0_0.bal) in the src folder will >> contain the following code segment >> >> endpoint http:Client WorldBank_1_0_0_prod { >> url: gateway:etcdSetup("WorldBank.1.0.0.prod.endpoint.0", " >> http://api.worldbank.org", "WorldBank.1.0.0.prod.etcd.key"), >> cache: { enabled: false } >> }; >> >> In the etcdSetup function, first, a connection is established with etcd. >> In order to establish a connection, the provided etcd URL, username and >> password should be valid. >> Once the connection is established, the periodic timer task will be >> started. >> >> A periodic task is implemented to query etcd using the etcd keys >> provided, and the results are maintained in a map variable(etcdUrls) where >> the key of the map will be the etcd key and the value will be the URL >> queried from the etcd node. Also, another map variable(urlChanged) is >> used with the same etcd keys but the values are boolean. This map is >> used to indicate whether the endpoint for the relevant etcd key should >> be reinitialized or not. >> >> When an API request comes, first the urlChanged map is read for the >> particular key, and if the value is false, the API request will be >> forwarded to the current endpoint URL. But if the value is true, the >> endpoint should be reinitialized. This is done by reading the etcdUrls map >> for the particular key, and using the URL obtained to reinitialize the >> endpoint. There may be situations where the URL defined at the etcd node >> is invalid. In such a situation, when the endpoint is reinitialized, it >> throws an exception. In such a situation, an error message is generated and >> sent to the user. >> >> The following code segment will perform the reinitialization task. >> >> etcdKey = >> gateway:retrieveConfig("{{api.name}}.{{api.version}}.prod.etcd.key", >> ""); >> if(etcdKey != "" && gateway:etcdConnectionEstablished){ >> hasUrlChanged = <boolean>gateway:urlChanged[etcdKey]; >> match hasUrlChanged{ >> boolean matchUrlChanged => reinitRequired = matchUrlChanged; >> error err => log:printError("Error in checking for >> Re-initialization", err = err); >> } >> if(reinitRequired){ >> newConfig = {url:<string>gateway:etcdUrls[etcdKey]}; >> destination_attribute = <string>gateway:etcdUrls[etcdKey]; >> try{ >> WorldBank_1_0_0_prod.init(newConfig); >> gateway:urlChanged[etcdKey] = false; >> }catch(error err){ >> reinitFailed = true; >> gateway:urlChanged[etcdKey] = true; >> >> http:Response res = new; >> res.statusCode = 500; >> json payload = { >> "fault": { >> "code": "101505", >> "message": "Runtime Error", >> "description": "URL defined at etcd for key " + >> etcdKey + " is invalid" >> } >> }; >> runtime:getInvocationContext().attributes["error_code"] = >> "101505"; >> res.setPayload(payload); >> clientResponse = res; >> log:printError("URL defined at etcd for key " + etcdKey + " >> is invalid"); >> } >> } >> } >> >> Your feedback is much appreciated. >> >> Thank you! >> >> On Mon, Oct 15, 2018 at 12:27 PM Hisan Hunais <[email protected]> wrote: >> >>> Hi all, >>> >>> The project I’m currently working on is "*Integration of API >>> microgateway with etcd for service discovery*". This project is about >>> making the API microgateway capable of communicating with etcd for service >>> discovery. >>> >>> *Problem Definition* >>> >>> - When an API microgateway is created, it is capable of routing >>> traffic to the URL of the API, provided at the time of API Creation. >>> - In practical scenarios, micro services will have dynamic URLs. >>> Since the microgateway is immutable, these dynamic URL changes will not >>> be >>> reflected at the microgateway. So the microgateway has to be stopped and >>> restarted providing the new URL. >>> >>> *Proposed Solution* >>> >>> - Integrating the API microgateway with etcd for discovering the >>> target endpoints for routing API traffic. >>> - etcd is a distributed key value store that provides a reliable way >>> to store data across a cluster of machines. Using etcd, we can store a >>> static key, and have the corresponding dynamic value which represents the >>> URL of the target endpoint. If the URL of the endpoint changes due to >>> some >>> situation, etcd should be updated providing the new URL for the relevant >>> key. So the API microgateway should know the etcd key and can obtain the >>> correct URL using an etcd lookup and route the traffic to the returned >>> URL. >>> - Basically an entry in etcd will be a key-value pair as shown below. >>> >>> worldbank-key - >>> key >>> http://api.worldbank.org - >>> value >>> >>> phoneverify-key - >>> key >>> http://ws.cdyne.com/phoneverify/phoneverify.asmx - value >>> >>> *Proposed design* >>> >>> - During microgateway setup command, if the microgateway needs etcd >>> enabled, use the flag -etcd. >>> >>> micro-gw setup project_name -a WorldBank -v 1.0.0 -etcd >>> >>> - When the microgateway is run using bash gateway command, need to >>> provide the etcd URL and relevant keys of APIs as CLI Parameters. (These >>> keys are used to query etcd to fetch the API URL) >>> >>> bash gateway -e etcdurl=http://127.0.0.1:2379 -e >>> WorldBank.1.0.0.prod.etcd.key=worldbank-key >>> >>> >>> - I'm currently researching on a way to query etcd with a key, >>> obtain the URL and reinitialize the API endpoint if the URL has changed. >>> Proposed idea is to run a periodic task to query etcd and maintain a list >>> of variables with the values. These variables will hold the actual URL to >>> route to and the variables will be updated time to time through a >>> periodic >>> check to etcd. >>> >>> >>> - The etcdLookup() function used to query etcd by providing the >>> relevant key as shown below. >>> >>> //key and value fields are defined as byte arrays and therefore must be >>> base64 encoded in JSON. >>> function etcdLookup(string key10) returns string >>> { >>> http:Request req; >>> string key64; >>> string value64; >>> var key = key10.base64Encode(charset = "utf-8"); >>> >>> match key { >>> string key1 => key64 = key1; >>> error err => io:println("error: " + err.message); >>> } >>> req.setPayload({"key": untaint key64}); >>> var response = etcdEndpoint->post("/v3alpha/kv/range",req); // call >>> to etcd node >>> match response { >>> http:Response resp => { >>> var msg = resp.getJsonPayload(); //fetch response >>> match msg { >>> json jsonPayload => { >>> var val64 = <string>jsonPayload.kvs[0].value; >>> //obtaining value corresponding to the key in base64 format >>> match val64 { >>> string value => value64 = value; >>> error err => io:println("error: " + err.message); >>> } >>> } >>> error err => { >>> log:printError(err.message, err = err); >>> } >>> } >>> } >>> error err => { log:printError(err.message, err = err); } >>> } >>> >>> var value10 = value64.base64Decode(charset = "utf-8"); //decoding >>> the base64 value to base10 format >>> match value10 { >>> string b => prodURL = untaint b; >>> error err => io:println("error: " + err.message); >>> } >>> return backendURL; >>> } >>> >>> Your feedback is much appreciated. >>> >>> Thank you! >>> -- >>> Hisan Hunais | Software Engineer Intern | WSO2 Inc. >>> (m) +94768526186 | (e) [email protected] >>> >>> <https://wso2.com/signature> >>> >>> >> >> -- >> Hisan Hunais | Software Engineer Intern | WSO2 Inc. >> (m) +94768526186 | (e) [email protected] >> >> <https://wso2.com/signature> >> >> > > -- > Hisan Hunais | Software Engineer Intern | WSO2 Inc. > (m) +94768526186 | (e) [email protected] > > <https://wso2.com/signature> > > -- Hisan Hunais | Software Engineer Intern | WSO2 Inc. (m) +94768526186 | (e) [email protected] <https://wso2.com/signature>
_______________________________________________ Architecture mailing list [email protected] https://mail.wso2.org/cgi-bin/mailman/listinfo/architecture
