From 8f66d25de4f7a5cabc19b25bdfd52efab49b1cef Mon Sep 17 00:00:00 2001 From: Aditya Mayukh Som Date: Sun, 3 Mar 2024 02:42:58 +0530 Subject: [PATCH 1/6] ADD: javaAsyncHttpClient as Codegen Language enum --- lib/consts.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/consts.dart b/lib/consts.dart index d157b7fa..7f090a65 100644 --- a/lib/consts.dart +++ b/lib/consts.dart @@ -271,7 +271,8 @@ enum CodegenLanguage { nodejsFetch("node.js (fetch)", "javascript", "js"), kotlinOkHttp("Kotlin (okhttp3)", "java", "kt"), pythonHttpClient("Python (http.client)", "python", "py"), - pythonRequests("Python (requests)", "python", "py"); + pythonRequests("Python (requests)", "python", "py"), + javaAsyncHttpClient("Java (async-http-client)", "java", "java"); const CodegenLanguage(this.label, this.codeHighlightLang, this.ext); final String label; From 220d58e6389e6af84b0b593123c4e23a671123a3 Mon Sep 17 00:00:00 2001 From: Aditya Mayukh Som Date: Sun, 3 Mar 2024 02:43:23 +0530 Subject: [PATCH 2/6] ADD: switch case for generating javaAsyncHttpClient code generation --- lib/codegen/codegen.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/codegen/codegen.dart b/lib/codegen/codegen.dart index 1aec7144..76aed61b 100644 --- a/lib/codegen/codegen.dart +++ b/lib/codegen/codegen.dart @@ -5,6 +5,7 @@ import 'dart/dio.dart'; import 'kotlin/okhttp.dart'; import 'python/http_client.dart'; import 'python/requests.dart'; +import 'java/async_http_client.dart'; import 'js/axios.dart'; import 'js/fetch.dart'; import 'others/har.dart'; @@ -42,6 +43,8 @@ class Codegen { .getCode(requestModel, defaultUriScheme); case CodegenLanguage.pythonRequests: return PythonRequestsCodeGen().getCode(requestModel, defaultUriScheme); + case CodegenLanguage.javaAsyncHttpClient: + return JavaAsyncHttpClientGen().getCode(requestModel, defaultUriScheme); } } } From c9f90a5d56e98fa2b0728ec53e1dd8e71c168789 Mon Sep 17 00:00:00 2001 From: Aditya Mayukh Som Date: Sun, 3 Mar 2024 02:46:10 +0530 Subject: [PATCH 3/6] ADD: JavaAsyncHttpClientGen class --- lib/codegen/java/async_http_client.dart | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 lib/codegen/java/async_http_client.dart diff --git a/lib/codegen/java/async_http_client.dart b/lib/codegen/java/async_http_client.dart new file mode 100644 index 00000000..daaa2103 --- /dev/null +++ b/lib/codegen/java/async_http_client.dart @@ -0,0 +1,9 @@ +import 'dart:convert'; +import 'package:apidash/utils/har_utils.dart'; +import 'package:apidash/utils/http_utils.dart'; +import 'package:jinja/jinja.dart' as jj; +import 'package:apidash/models/models.dart' show RequestModel; +import 'package:apidash/consts.dart'; + +class JavaAsyncHttpClientGen { +} From c13c788ea9876acb889709b347bab8c9d6b13b5f Mon Sep 17 00:00:00 2001 From: Aditya Mayukh Som Date: Sun, 3 Mar 2024 02:54:07 +0530 Subject: [PATCH 4/6] ADD: templates for code generation --- lib/codegen/java/async_http_client.dart | 68 +++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/lib/codegen/java/async_http_client.dart b/lib/codegen/java/async_http_client.dart index daaa2103..c6aa368d 100644 --- a/lib/codegen/java/async_http_client.dart +++ b/lib/codegen/java/async_http_client.dart @@ -6,4 +6,72 @@ import 'package:apidash/models/models.dart' show RequestModel; import 'package:apidash/consts.dart'; class JavaAsyncHttpClientGen { + final String kTemplateStart = ''' +import org.asynchttpclient.*; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.stream.Collectors; + +public class Main { + public static void main(String[] args) { + try (AsyncHttpClient asyncHttpClient = Dsl.asyncHttpClient()) { +'''; + + final String kTemplateUrl = ''' + String url = "{{url}}";\n +'''; + + final String kTemplateRequestCreation = ''' + Request request = asyncHttpClient + .prepare("{{method}}", url)\n +'''; + + final String kTemplateUrlQueryParam = ''' + .addQueryParam("{{name}}", "{{value}}")\n +'''; + + final String kTemplateRequestHeader = ''' + .addHeader("{{name}}", "{{value}}")\n +'''; + final String kTemplateRequestFormData = ''' + .addFormParam("{{name}}", "{{value}}")\n +'''; + + String kTemplateRequestBodyContent = ''' + String bodyContent = "{{body}}";\n +'''; + String kTemplateRequestBodySetup = ''' + .setBody(bodyContent)\n +'''; + + final String kTemplateRequestEnd = """ + .build(); + ListenableFuture listenableFuture = asyncHttpClient.executeRequest(request); + listenableFuture.addListener(() -> { + try { + Response response = listenableFuture.get(); + InputStream is = response.getResponseBodyAsStream(); + BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8)); + String respBody = br.lines().collect(Collectors.joining("\\n")); + System.out.println(response.getStatusCode()); + System.out.println(respBody); + } catch (InterruptedException | ExecutionException e) { + e.printStackTrace(); + } + }, Executors.newCachedThreadPool()); + listenableFuture.get(); + } catch (InterruptedException | ExecutionException | IOException ignored) { + + } + } +} +\n +"""; + } From b9750ef8b16f061fe0d1357adb72c4c1ae508885 Mon Sep 17 00:00:00 2001 From: Aditya Mayukh Som Date: Sun, 3 Mar 2024 02:58:14 +0530 Subject: [PATCH 5/6] ADD: getCode function to return the generted code string --- lib/codegen/java/async_http_client.dart | 126 ++++++++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/lib/codegen/java/async_http_client.dart b/lib/codegen/java/async_http_client.dart index c6aa368d..f0f688c6 100644 --- a/lib/codegen/java/async_http_client.dart +++ b/lib/codegen/java/async_http_client.dart @@ -74,4 +74,130 @@ public class Main { \n """; + String? getCode( + RequestModel requestModel, + String defaultUriScheme, + ) { + try { + String result = ""; + bool hasBody = false; + bool hasJsonBody = false; + + String url = requestModel.url; + if (!url.contains("://") && url.isNotEmpty) { + url = "$defaultUriScheme://$url"; + } + + var rec = getValidRequestUri( + url, + requestModel.enabledRequestParams, + ); + Uri? uri = rec.$1; + + if (uri == null) { + return ""; + } + + url = stripUriParams(uri); + + // contains the HTTP method associated with the request + var method = requestModel.method; + + // contains the entire request body as a string if body is present + var requestBody = requestModel.requestBody; + + // generating the URL to which the request has to be submitted + var templateUrl = jj.Template(kTemplateUrl); + result += templateUrl.render({"url": url}); + + // creating request body if available + var rM = requestModel.copyWith(url: url); + var harJson = requestModelToHARJsonRequest(rM, useEnabled: true); + + // if request type is not form data, the request method can include + // a body, and the body of the request is not null, in that case + // we need to parse the body as it is, and write it to the body + if (!requestModel.isFormDataRequest && + kMethodsWithBody.contains(method) && + requestBody != null) { + var contentLength = utf8.encode(requestBody).length; + if (contentLength > 0) { + var templateBodyContent = jj.Template(kTemplateRequestBodyContent); + hasBody = true; + + // every JSON should be enclosed within a pair of curly braces + // very simple check for JSON, for stronger check, we may validate + // the JSON in the JSON editor itself + hasJsonBody = + requestBody.startsWith("{") && requestBody.endsWith("}"); + + if (harJson["postData"]?["text"] != null) { + result += templateBodyContent.render({ + "body": kEncoder.convert(harJson["postData"]["text"]).substring( + 1, kEncoder.convert(harJson["postData"]["text"]).length - 1) + }); + } + } + } + + var templateRequestCreation = jj.Template(kTemplateRequestCreation); + result += + templateRequestCreation.render({"method": method.name.toUpperCase()}); + + // setting up query parameters + if (uri.hasQuery) { + var params = uri.queryParameters; + var templateUrlQueryParam = jj.Template(kTemplateUrlQueryParam); + params.forEach((name, value) { + result += + templateUrlQueryParam.render({"name": name, "value": value}); + }); + } + + result = kTemplateStart + result; + + var contentType = requestModel.requestBodyContentType.header; + var templateRequestHeader = jj.Template(kTemplateRequestHeader); + + // especially sets up Content-Type header if the request has a body + // and Content-Type is not explicitely set by the developer + if (hasBody && + !requestModel.enabledHeadersMap.containsKey('Content-Type')) { + result += templateRequestHeader + .render({"name": 'Content-Type', "value": contentType}); + } + + // setting up rest of the request headers + var headers = requestModel.enabledHeadersMap; + headers.forEach((name, value) { + result += templateRequestHeader.render({"name": name, "value": value}); + }); + + // handling form data + if (requestModel.isFormDataRequest && + requestModel.formDataMapList.isNotEmpty && + kMethodsWithBody.contains(method)) { + // including form data into the request + var formDataList = requestModel.formDataMapList; + var templateRequestFormData = jj.Template(kTemplateRequestFormData); + for (var formDataMap in formDataList) { + result += templateRequestFormData.render( + {"name": formDataMap['name'], "value": formDataMap['value']}); + } + hasBody = true; + } + + var templateRequestBodySetup = jj.Template(kTemplateRequestBodySetup); + if (kMethodsWithBody.contains(method) && hasBody) { + result += templateRequestBodySetup.render(); + } + + var templateRequestBodyEnd = jj.Template(kTemplateRequestEnd); + result += templateRequestBodyEnd.render(); + + return result; + } catch (e) { + return null; + } + } } From 15c38c61275bb8a47cf13d59dba556be665fd54c Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Fri, 15 Mar 2024 08:12:56 +0530 Subject: [PATCH 6/6] removed errors --- lib/codegen/java/async_http_client.dart | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/lib/codegen/java/async_http_client.dart b/lib/codegen/java/async_http_client.dart index f0f688c6..ec804cc1 100644 --- a/lib/codegen/java/async_http_client.dart +++ b/lib/codegen/java/async_http_client.dart @@ -76,20 +76,13 @@ public class Main { String? getCode( RequestModel requestModel, - String defaultUriScheme, ) { try { String result = ""; bool hasBody = false; - bool hasJsonBody = false; - - String url = requestModel.url; - if (!url.contains("://") && url.isNotEmpty) { - url = "$defaultUriScheme://$url"; - } var rec = getValidRequestUri( - url, + requestModel.url, requestModel.enabledRequestParams, ); Uri? uri = rec.$1; @@ -98,7 +91,7 @@ public class Main { return ""; } - url = stripUriParams(uri); + var url = stripUriParams(uri); // contains the HTTP method associated with the request var method = requestModel.method; @@ -117,20 +110,13 @@ public class Main { // if request type is not form data, the request method can include // a body, and the body of the request is not null, in that case // we need to parse the body as it is, and write it to the body - if (!requestModel.isFormDataRequest && + if (!requestModel.hasFormData && kMethodsWithBody.contains(method) && requestBody != null) { var contentLength = utf8.encode(requestBody).length; if (contentLength > 0) { var templateBodyContent = jj.Template(kTemplateRequestBodyContent); hasBody = true; - - // every JSON should be enclosed within a pair of curly braces - // very simple check for JSON, for stronger check, we may validate - // the JSON in the JSON editor itself - hasJsonBody = - requestBody.startsWith("{") && requestBody.endsWith("}"); - if (harJson["postData"]?["text"] != null) { result += templateBodyContent.render({ "body": kEncoder.convert(harJson["postData"]["text"]).substring( @@ -174,7 +160,7 @@ public class Main { }); // handling form data - if (requestModel.isFormDataRequest && + if (requestModel.hasFormData && requestModel.formDataMapList.isNotEmpty && kMethodsWithBody.contains(method)) { // including form data into the request