diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/CommandUtil.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/CommandUtil.java index 98749dc1021e..66d89e8789ab 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/CommandUtil.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/CommandUtil.java @@ -457,7 +457,9 @@ private static void pullPackageFromRemote(String orgName, String packageName, St CentralAPIClient client = new CentralAPIClient(RepoUtils.getRemoteRepoURL(), initializeProxy(settings.getProxy()), settings.getProxy().username(), settings.getProxy().password(), - getAccessTokenOfCLI(settings)); + getAccessTokenOfCLI(settings), settings.getCentral().getConnectTimeout(), + settings.getCentral().getReadTimeout(), settings.getCentral().getWriteTimeout(), + settings.getCentral().getCallTimeout()); try { client.pullPackage(orgName, packageName, version, destination, supportedPlatform, RepoUtils.getBallerinaVersion(), false); diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/DeprecateCommand.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/DeprecateCommand.java index f23c3f13cc1a..4218007a2574 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/DeprecateCommand.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/DeprecateCommand.java @@ -171,7 +171,9 @@ private void deprecateInCentral(String packageInfo) { CentralAPIClient client = new CentralAPIClient(RepoUtils.getRemoteRepoURL(), initializeProxy(settings.getProxy()), settings.getProxy().username(), settings.getProxy().password(), - getAccessTokenOfCLI(settings)); + getAccessTokenOfCLI(settings), settings.getCentral().getConnectTimeout(), + settings.getCentral().getReadTimeout(), settings.getCentral().getWriteTimeout(), + settings.getCentral().getCallTimeout()); client.deprecatePackage(packageValue, deprecationMsg, JvmTarget.JAVA_17.code(), RepoUtils.getBallerinaVersion(), this.undoFlag); diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PullCommand.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PullCommand.java index 0461d2c2842b..a62050085578 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PullCommand.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PullCommand.java @@ -270,7 +270,10 @@ public void execute() { try { CentralAPIClient client = new CentralAPIClient(RepoUtils.getRemoteRepoURL(), initializeProxy(settings.getProxy()), settings.getProxy().username(), - settings.getProxy().password(), getAccessTokenOfCLI(settings)); + settings.getProxy().password(), getAccessTokenOfCLI(settings), + settings.getCentral().getConnectTimeout(), + settings.getCentral().getReadTimeout(), settings.getCentral().getWriteTimeout(), + settings.getCentral().getCallTimeout()); client.pullPackage(orgName, packageName, version, packagePathInBalaCache, supportedPlatform, RepoUtils.getBallerinaVersion(), false); if (version.equals(Names.EMPTY.getValue())) { diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java index f4c20699ac27..ff3ee3e9cc70 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java @@ -219,7 +219,10 @@ public void execute() { } CentralAPIClient client = new CentralAPIClient(RepoUtils.getRemoteRepoURL(), initializeProxy(settings.getProxy()), settings.getProxy().username(), - settings.getProxy().password(), getAccessTokenOfCLI(settings)); + settings.getProxy().password(), getAccessTokenOfCLI(settings), + settings.getCentral().getConnectTimeout(), + settings.getCentral().getReadTimeout(), settings.getCentral().getWriteTimeout(), + settings.getCentral().getCallTimeout()); if (balaPath == null) { pushPackage(project, client); } else { diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/SearchCommand.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/SearchCommand.java index 075a6e60d1c8..f4474f6bd66d 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/SearchCommand.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/SearchCommand.java @@ -144,7 +144,11 @@ private void searchInCentral(String query) { initializeProxy(settings.getProxy()), settings.getProxy().username(), settings.getProxy().password(), - getAccessTokenOfCLI(settings)); + getAccessTokenOfCLI(settings), + settings.getCentral().getConnectTimeout(), + settings.getCentral().getReadTimeout(), + settings.getCentral().getWriteTimeout(), + settings.getCentral().getCallTimeout()); boolean foundSearch = false; String supportedPlatform = Arrays.stream(JvmTarget.values()) .map(target -> target.code()) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/ToolCommand.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/ToolCommand.java index 6d9503cf0aaf..509c966daf05 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/ToolCommand.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/ToolCommand.java @@ -442,7 +442,10 @@ private void pullToolFromCentral(String supportedPlatform, Path balaCacheDirPath System.setProperty(CentralClientConstants.ENABLE_OUTPUT_STREAM, "true"); CentralAPIClient client = new CentralAPIClient(RepoUtils.getRemoteRepoURL(), initializeProxy(settings.getProxy()), settings.getProxy().username(), - settings.getProxy().password(), getAccessTokenOfCLI(settings)); + settings.getProxy().password(), getAccessTokenOfCLI(settings), + settings.getCentral().getConnectTimeout(), + settings.getCentral().getReadTimeout(), settings.getCentral().getWriteTimeout(), + settings.getCentral().getCallTimeout()); String[] toolInfo = client.pullTool(toolId, version, balaCacheDirPath, supportedPlatform, RepoUtils.getBallerinaVersion(), false); boolean isPulled = Boolean.parseBoolean(toolInfo[0]); @@ -574,7 +577,10 @@ private void searchToolsInCentral(String keyword) { } CentralAPIClient client = new CentralAPIClient(RepoUtils.getRemoteRepoURL(), initializeProxy(settings.getProxy()), settings.getProxy().username(), - settings.getProxy().password(), getAccessTokenOfCLI(settings)); + settings.getProxy().password(), getAccessTokenOfCLI(settings), + settings.getCentral().getConnectTimeout(), + settings.getCentral().getReadTimeout(), settings.getCentral().getWriteTimeout(), + settings.getCentral().getCallTimeout()); boolean foundTools = false; String supportedPlatform = Arrays.stream(JvmTarget.values()) .map(JvmTarget::code) @@ -726,7 +732,10 @@ private String getLatestVersionForUpdateCommand(String supportedPlatforms, BalTo System.setProperty(CentralClientConstants.ENABLE_OUTPUT_STREAM, "true"); CentralAPIClient client = new CentralAPIClient(RepoUtils.getRemoteRepoURL(), initializeProxy(settings.getProxy()), settings.getProxy().username(), - settings.getProxy().password(), getAccessTokenOfCLI(settings)); + settings.getProxy().password(), getAccessTokenOfCLI(settings), + settings.getCentral().getConnectTimeout(), + settings.getCentral().getReadTimeout(), settings.getCentral().getWriteTimeout(), + settings.getCentral().getCallTimeout()); List versions = client.getPackageVersions(tool.org(), tool.name(), supportedPlatforms, RepoUtils.getBallerinaVersion()); return getLatestVersion(versions, tool.version()); diff --git a/cli/central-client/src/main/java/org/ballerinalang/central/client/CentralAPIClient.java b/cli/central-client/src/main/java/org/ballerinalang/central/client/CentralAPIClient.java index 39450e0521b0..c2307c06caf8 100644 --- a/cli/central-client/src/main/java/org/ballerinalang/central/client/CentralAPIClient.java +++ b/cli/central-client/src/main/java/org/ballerinalang/central/client/CentralAPIClient.java @@ -129,6 +129,10 @@ public class CentralAPIClient { private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); // System property name for enabling central verbose public static final String SYS_PROP_CENTRAL_VERBOSE_ENABLED = "CENTRAL_VERBOSE_ENABLED"; + private static final int DEFAULT_CONNECT_TIMEOUT = 60; + private static final int DEFAULT_READ_TIMEOUT = 60; + private static final int DEFAULT_WRITE_TIMEOUT = 60; + private static final int DEFAULT_CALL_TIMEOUT = 0; private final String baseUrl; private final Proxy proxy; @@ -137,6 +141,10 @@ public class CentralAPIClient { private final boolean verboseEnabled; private final String proxyUsername; private final String proxyPassword; + private final int connectTimeout; + private final int readTimeout; + private final int writeTimeout; + private final int callTimeout; public CentralAPIClient(String baseUrl, Proxy proxy, String accessToken) { this.outStream = System.out; @@ -146,10 +154,15 @@ public CentralAPIClient(String baseUrl, Proxy proxy, String accessToken) { this.verboseEnabled = Boolean.parseBoolean(System.getenv(SYS_PROP_CENTRAL_VERBOSE_ENABLED)); this.proxyUsername = ""; this.proxyPassword = ""; + this.connectTimeout = DEFAULT_CONNECT_TIMEOUT; + this.readTimeout = DEFAULT_READ_TIMEOUT; + this.writeTimeout = DEFAULT_WRITE_TIMEOUT; + this.callTimeout = DEFAULT_CALL_TIMEOUT; } public CentralAPIClient(String baseUrl, Proxy proxy, String proxyUsername, String proxyPassword, - String accessToken) { + String accessToken, int connectionTimeout, int readTimeout, int writeTimeout, + int callTimeout) { this.outStream = System.out; this.baseUrl = baseUrl; this.proxy = proxy; @@ -157,6 +170,10 @@ public CentralAPIClient(String baseUrl, Proxy proxy, String proxyUsername, Strin this.verboseEnabled = Boolean.parseBoolean(System.getenv(SYS_PROP_CENTRAL_VERBOSE_ENABLED)); this.proxyUsername = proxyUsername; this.proxyPassword = proxyPassword; + this.connectTimeout = connectionTimeout; + this.readTimeout = readTimeout; + this.writeTimeout = writeTimeout; + this.callTimeout = callTimeout; } /** @@ -776,17 +793,24 @@ public PackageNameResolutionResponse resolvePackageNames(PackageNameResolutionRe .addHeader(ACCEPT_ENCODING, IDENTITY) .addHeader(ACCEPT, APPLICATION_JSON) .build(); + logRequestInitVerbose(resolutionReq); Call resolutionReqCall = client.newCall(resolutionReq); Response packageResolutionResponse = resolutionReqCall.execute(); + logRequestConnectVerbose(resolutionReq, "/" + PACKAGES + "/" + RESOLVE_MODULES); body = Optional.ofNullable(packageResolutionResponse.body()); + String resolvePackageNamesBody = null; + if (body.isPresent()) { + resolvePackageNamesBody = body.get().string(); + } + logResponseVerbose(packageResolutionResponse, resolvePackageNamesBody); if (body.isPresent()) { Optional contentType = Optional.ofNullable(body.get().contentType()); if (contentType.isPresent() && isApplicationJsonContentType(contentType.get().toString())) { // If searching was successful if (packageResolutionResponse.code() == HTTP_OK) { - return new Gson().fromJson(body.get().string(), PackageNameResolutionResponse.class); + return new Gson().fromJson(resolvePackageNamesBody, PackageNameResolutionResponse.class); } // Unauthorized access token @@ -796,7 +820,7 @@ public PackageNameResolutionResponse resolvePackageNames(PackageNameResolutionRe // If search request was sent wrongly if (packageResolutionResponse.code() == HTTP_BAD_REQUEST) { - Error error = new Gson().fromJson(body.get().string(), Error.class); + Error error = new Gson().fromJson(resolvePackageNamesBody, Error.class); if (error.getMessage() != null && !"".equals(error.getMessage())) { throw new ConnectionErrorException(error.getMessage()); } @@ -805,7 +829,7 @@ public PackageNameResolutionResponse resolvePackageNames(PackageNameResolutionRe // If error occurred at remote repository if (packageResolutionResponse.code() == HTTP_INTERNAL_ERROR || packageResolutionResponse.code() == HTTP_UNAVAILABLE) { - Error error = new Gson().fromJson(body.get().string(), Error.class); + Error error = new Gson().fromJson(resolvePackageNamesBody, Error.class); if (error.getMessage() != null && !"".equals(error.getMessage())) { throw new ConnectionErrorException(ERR_PACKAGE_RESOLUTION + " reason:" + error.getMessage()); @@ -847,17 +871,23 @@ public PackageResolutionResponse resolveDependencies(PackageResolutionRequest re .addHeader(ACCEPT_ENCODING, IDENTITY) .addHeader(ACCEPT, APPLICATION_JSON) .build(); - + logRequestInitVerbose(packageResolutionReq); Call packageResolutionReqCall = client.newCall(packageResolutionReq); Response packageResolutionResponse = packageResolutionReqCall.execute(); + logRequestConnectVerbose(packageResolutionReq, "/" + PACKAGES + "/" + RESOLVE_DEPENDENCIES); body = Optional.ofNullable(packageResolutionResponse.body()); + String packageResolutionResponseBody = null; + if (body.isPresent()) { + packageResolutionResponseBody = body.get().string(); + } + logResponseVerbose(packageResolutionResponse, packageResolutionResponseBody); if (body.isPresent()) { Optional contentType = Optional.ofNullable(body.get().contentType()); if (contentType.isPresent() && isApplicationJsonContentType(contentType.get().toString())) { // If searching was successful if (packageResolutionResponse.code() == HTTP_OK) { - return new Gson().fromJson(body.get().string(), PackageResolutionResponse.class); + return new Gson().fromJson(packageResolutionResponseBody, PackageResolutionResponse.class); } // Unauthorized access token @@ -867,7 +897,7 @@ public PackageResolutionResponse resolveDependencies(PackageResolutionRequest re // If search request was sent wrongly if (packageResolutionResponse.code() == HTTP_BAD_REQUEST) { - Error error = new Gson().fromJson(body.get().string(), Error.class); + Error error = new Gson().fromJson(packageResolutionResponseBody, Error.class); if (error.getMessage() != null && !"".equals(error.getMessage())) { throw new ConnectionErrorException(error.getMessage()); } @@ -876,7 +906,7 @@ public PackageResolutionResponse resolveDependencies(PackageResolutionRequest re // If error occurred at remote repository if (packageResolutionResponse.code() == HTTP_INTERNAL_ERROR || packageResolutionResponse.code() == HTTP_UNAVAILABLE) { - Error error = new Gson().fromJson(body.get().string(), Error.class); + Error error = new Gson().fromJson(packageResolutionResponseBody, Error.class); if (error.getMessage() != null && !"".equals(error.getMessage())) { throw new ConnectionErrorException(ERR_PACKAGE_RESOLUTION + " reason:" + error.getMessage()); @@ -909,17 +939,23 @@ public PackageSearchResult searchPackage(String query, String supportedPlatform, .get() .url(this.baseUrl + "/" + PACKAGES + "/?q=" + query) .build(); - + logRequestInitVerbose(searchReq); Call httpRequestCall = client.newCall(searchReq); Response searchResponse = httpRequestCall.execute(); + logRequestConnectVerbose(searchReq, "/" + PACKAGES + "/?q=" + query); body = Optional.ofNullable(searchResponse.body()); + String searchResponseBody = null; + if (body.isPresent()) { + searchResponseBody = body.get().string(); + } + logResponseVerbose(searchResponse, searchResponseBody); if (body.isPresent()) { Optional contentType = Optional.ofNullable(body.get().contentType()); if (contentType.isPresent() && isApplicationJsonContentType(contentType.get().toString())) { // If searching was successful if (searchResponse.code() == HTTP_OK) { - return new Gson().fromJson(body.get().string(), PackageSearchResult.class); + return new Gson().fromJson(searchResponseBody, PackageSearchResult.class); } // Unauthorized access token @@ -929,7 +965,7 @@ public PackageSearchResult searchPackage(String query, String supportedPlatform, // If search request was sent wrongly if (searchResponse.code() == HTTP_BAD_REQUEST) { - Error error = new Gson().fromJson(body.get().string(), Error.class); + Error error = new Gson().fromJson(searchResponseBody, Error.class); if (error.getMessage() != null && !"".equals(error.getMessage())) { throw new CentralClientException(error.getMessage()); } @@ -938,7 +974,7 @@ public PackageSearchResult searchPackage(String query, String supportedPlatform, // If error occurred at remote repository if (searchResponse.code() == HTTP_INTERNAL_ERROR || searchResponse.code() == HTTP_UNAVAILABLE) { - Error error = new Gson().fromJson(body.get().string(), Error.class); + Error error = new Gson().fromJson(searchResponseBody, Error.class); if (error.getMessage() != null && !"".equals(error.getMessage())) { throw new CentralClientException(ERR_CANNOT_SEARCH + "'" + query + "' reason:" + error.getMessage()); @@ -973,16 +1009,23 @@ public ToolSearchResult searchTool(String keyword, String supportedPlatform, Str .url(this.baseUrl + "/" + TOOLS + SEARCH_QUERY + keyword) .build(); + logRequestInitVerbose(searchReq); Call httpRequestCall = client.newCall(searchReq); Response searchResponse = httpRequestCall.execute(); + logRequestConnectVerbose(searchReq, "/" + TOOLS + "/" + SEARCH_QUERY + "/" + keyword); body = Optional.ofNullable(searchResponse.body()); + String searchResponseBody = null; + if (body.isPresent()) { + searchResponseBody = body.get().string(); + } + logResponseVerbose(searchResponse, searchResponseBody); if (body.isPresent()) { Optional contentType = Optional.ofNullable(body.get().contentType()); if (contentType.isPresent() && isApplicationJsonContentType(contentType.get().toString())) { // If searching was successful if (searchResponse.code() == HTTP_OK) { - return new Gson().fromJson(body.get().string(), ToolSearchResult.class); + return new Gson().fromJson(searchResponseBody, ToolSearchResult.class); } // Unauthorized access token @@ -992,7 +1035,7 @@ public ToolSearchResult searchTool(String keyword, String supportedPlatform, Str // If search request was sent wrongly if (searchResponse.code() == HTTP_BAD_REQUEST) { - Error error = new Gson().fromJson(body.get().string(), Error.class); + Error error = new Gson().fromJson(searchResponseBody, Error.class); if (error.getMessage() != null && !"".equals(error.getMessage())) { throw new CentralClientException(error.getMessage()); } @@ -1001,7 +1044,7 @@ public ToolSearchResult searchTool(String keyword, String supportedPlatform, Str // If error occurred at remote repository if (searchResponse.code() == HTTP_INTERNAL_ERROR || searchResponse.code() == HTTP_UNAVAILABLE) { - Error error = new Gson().fromJson(body.get().string(), Error.class); + Error error = new Gson().fromJson(searchResponseBody, Error.class); if (error.getMessage() != null && !"".equals(error.getMessage())) { throw new CentralClientException(ERR_CANNOT_SEARCH + "'" + keyword + "' reason:" + error.getMessage()); @@ -1061,17 +1104,24 @@ public void deprecatePackage(String packageInfo, String deprecationMsg, String s .addHeader(ACCEPT_ENCODING, IDENTITY) .addHeader(ACCEPT, APPLICATION_JSON) .build(); + logRequestInitVerbose(deprecationReq); Call httpRequestCall = client.newCall(deprecationReq); Response deprecationResponse = httpRequestCall.execute(); + logRequestConnectVerbose(deprecationReq, requestURL.replace(this.baseUrl, "")); body = Optional.ofNullable(deprecationResponse.body()); + String deprecationResponseBody = null; + if (body.isPresent()) { + deprecationResponseBody = body.get().string(); + } + logResponseVerbose(deprecationResponse, deprecationResponseBody); if (body.isPresent()) { Optional contentType = Optional.ofNullable(body.get().contentType()); if (contentType.isPresent() && isApplicationJsonContentType(contentType.get().toString())) { // If deprecation was successful if (deprecationResponse.code() == HTTP_OK) { - Package packageResponse = new Gson().fromJson(body.get().string(), Package.class); + Package packageResponse = new Gson().fromJson(deprecationResponseBody, Package.class); if (packageResponse.getDeprecated()) { if (existingPackage.getDeprecated()) { this.outStream.println("deprecation message is successfully updated for the package " @@ -1093,7 +1143,7 @@ public void deprecatePackage(String packageInfo, String deprecationMsg, String s // If deprecation request was sent wrongly if (deprecationResponse.code() == HTTP_BAD_REQUEST) { - Error error = new Gson().fromJson(body.get().string(), Error.class); + Error error = new Gson().fromJson(deprecationResponseBody, Error.class); if (error.getMessage() != null && !"".equals(error.getMessage())) { throw new CentralClientException(error.getMessage()); } @@ -1101,7 +1151,7 @@ public void deprecatePackage(String packageInfo, String deprecationMsg, String s // If deprecation request was sent wrongly if (deprecationResponse.code() == HTTP_NOT_FOUND) { - Error error = new Gson().fromJson(body.get().string(), Error.class); + Error error = new Gson().fromJson(deprecationResponseBody, Error.class); if (error.getMessage() != null && !"".equals(error.getMessage())) { throw new CentralClientException(error.getMessage()); } @@ -1110,7 +1160,7 @@ public void deprecatePackage(String packageInfo, String deprecationMsg, String s // If error occurred at remote repository if (deprecationResponse.code() == HTTP_INTERNAL_ERROR || deprecationResponse.code() == HTTP_UNAVAILABLE) { - Error error = new Gson().fromJson(body.get().string(), Error.class); + Error error = new Gson().fromJson(deprecationResponseBody, Error.class); if (error.getMessage() != null && !"".equals(error.getMessage())) { String errorMsg = isUndo ? ERR_PACKAGE_UN_DEPRECATE : ERR_PACKAGE_DEPRECATE; throw new CentralClientException(errorMsg + "'" + packageValue + @@ -1146,8 +1196,10 @@ public JsonElement getPackages(Map params, String supportedPlatf Optional body = Optional.empty(); OkHttpClient client = new OkHttpClient.Builder() .followRedirects(false) - .connectTimeout(20, TimeUnit.SECONDS) - .readTimeout(20, TimeUnit.SECONDS) + .connectTimeout(connectTimeout, TimeUnit.SECONDS) + .readTimeout(readTimeout, TimeUnit.SECONDS) + .writeTimeout(writeTimeout, TimeUnit.SECONDS) + .callTimeout(callTimeout, TimeUnit.SECONDS) .proxy(this.proxy) .build(); @@ -1204,8 +1256,10 @@ public JsonElement getConnectors(Map params, String supportedPla // TODO: update this client initiation with default timeouts after fixing central/connectors API. OkHttpClient client = new OkHttpClient.Builder() .followRedirects(false) - .connectTimeout(20, TimeUnit.SECONDS) - .readTimeout(20, TimeUnit.SECONDS) + .connectTimeout(connectTimeout, TimeUnit.SECONDS) + .readTimeout(readTimeout, TimeUnit.SECONDS) + .writeTimeout(writeTimeout, TimeUnit.SECONDS) + .callTimeout(callTimeout, TimeUnit.SECONDS) .proxy(this.proxy) .build(); @@ -1219,16 +1273,23 @@ public JsonElement getConnectors(Map params, String supportedPla .get() .url(httpBuilder.build()) .build(); + logRequestInitVerbose(searchReq); Call httpRequestCall = client.newCall(searchReq); Response searchResponse = httpRequestCall.execute(); + logRequestConnectVerbose(searchReq, "/" + CONNECTORS); body = Optional.ofNullable(searchResponse.body()); + String searchResponseBody = null; + if (body.isPresent()) { + searchResponseBody = body.get().string(); + } + logResponseVerbose(searchResponse, searchResponseBody); if (body.isPresent()) { Optional contentType = Optional.ofNullable(body.get().contentType()); if (contentType.isPresent() && isApplicationJsonContentType(contentType.get().toString()) && searchResponse.code() == HttpsURLConnection.HTTP_OK) { - return new Gson().toJsonTree(body.get().string()); + return new Gson().toJsonTree(searchResponseBody); } } handleResponseErrors(searchResponse, ERR_CANNOT_GET_CONNECTOR); @@ -1263,13 +1324,20 @@ public JsonObject getConnector(String id, String supportedPlatform, String balle .get() .url(this.baseUrl + "/" + CONNECTORS + "/" + id) .build(); + logRequestInitVerbose(searchReq); Call httpRequestCall = client.newCall(searchReq); Response searchResponse = httpRequestCall.execute(); + logRequestConnectVerbose(searchReq, "/" + CONNECTORS + "/" + id); body = Optional.ofNullable(searchResponse.body()); + String searchResponseBody = null; + if (body.isPresent()) { + searchResponseBody = body.get().string(); + } + logResponseVerbose(searchResponse, searchResponseBody); if (body.isPresent()) { - String responseStr = body.get().string(); + String responseStr = searchResponseBody; Optional contentType = Optional.ofNullable(body.get().contentType()); if (contentType.isPresent() && isApplicationJsonContentType(contentType.get().toString()) && searchResponse.code() == HttpsURLConnection.HTTP_OK) { @@ -1310,13 +1378,22 @@ public JsonObject getConnector(ConnectorInfo connector, String supportedPlatform "/" + connector.getPackageName() + "/" + connector.getVersion() + "/" + connector.getModuleName() + "/" + connector.getName()) .build(); + logRequestInitVerbose(searchReq); Call httpRequestCall = client.newCall(searchReq); Response searchResponse = httpRequestCall.execute(); + logRequestConnectVerbose(searchReq, "/" + CONNECTORS + "/" + connector.getOrgName() + + "/" + connector.getPackageName() + "/" + connector.getVersion() + + "/" + connector.getModuleName() + "/" + connector.getName()); body = Optional.ofNullable(searchResponse.body()); + String searchResponseBody = null; + if (body.isPresent()) { + searchResponseBody = body.get().string(); + } + logResponseVerbose(searchResponse, searchResponseBody); if (body.isPresent()) { - String responseStr = body.get().string(); + String responseStr = searchResponseBody; Optional contentType = Optional.ofNullable(body.get().contentType()); if (contentType.isPresent() && isApplicationJsonContentType(contentType.get().toString()) && searchResponse.code() == HttpsURLConnection.HTTP_OK) { @@ -1345,8 +1422,10 @@ public JsonObject getConnector(ConnectorInfo connector, String supportedPlatform */ protected OkHttpClient getClient() { OkHttpClient okHttpClient = new OkHttpClient.Builder() - .connectTimeout(30, TimeUnit.SECONDS) - .readTimeout(60, TimeUnit.SECONDS) + .connectTimeout(connectTimeout, TimeUnit.SECONDS) + .readTimeout(readTimeout, TimeUnit.SECONDS) + .writeTimeout(writeTimeout, TimeUnit.SECONDS) + .callTimeout(callTimeout, TimeUnit.SECONDS) .followRedirects(false) .retryOnConnectionFailure(true) .proxy(this.proxy) @@ -1464,8 +1543,10 @@ public JsonElement getTriggers(Map params, String supportedPlatf // TODO: update this client initiation with default timeouts after fixing central/triggers API. OkHttpClient client = new OkHttpClient.Builder() .followRedirects(false) - .connectTimeout(20, TimeUnit.SECONDS) - .readTimeout(20, TimeUnit.SECONDS) + .connectTimeout(connectTimeout, TimeUnit.SECONDS) + .readTimeout(readTimeout, TimeUnit.SECONDS) + .writeTimeout(writeTimeout, TimeUnit.SECONDS) + .callTimeout(callTimeout, TimeUnit.SECONDS) .proxy(this.proxy) .build(); @@ -1479,16 +1560,23 @@ public JsonElement getTriggers(Map params, String supportedPlatf .get() .url(httpBuilder.build()) .build(); + logRequestInitVerbose(searchReq); Call httpRequestCall = client.newCall(searchReq); Response searchResponse = httpRequestCall.execute(); + logRequestConnectVerbose(searchReq, "/" + TRIGGERS); body = Optional.ofNullable(searchResponse.body()); + String searchResponseBody = null; + if (body.isPresent()) { + searchResponseBody = body.get().string(); + } + logResponseVerbose(searchResponse, searchResponseBody); if (body.isPresent()) { Optional contentType = Optional.ofNullable(body.get().contentType()); if (contentType.isPresent() && isApplicationJsonContentType(contentType.get().toString()) && searchResponse.code() == HttpsURLConnection.HTTP_OK) { - return new Gson().toJsonTree(body.get().string()); + return new Gson().toJsonTree(searchResponseBody); } } handleResponseErrors(searchResponse, ERR_CANNOT_GET_TRIGGERS); @@ -1523,15 +1611,23 @@ public JsonObject getTrigger(String id, String supportedPlatform, String balleri .get() .url(this.baseUrl + "/" + TRIGGERS + "/" + id) .build(); + logRequestInitVerbose(searchReq); Call httpRequestCall = client.newCall(searchReq); Response searchResponse = httpRequestCall.execute(); + logRequestConnectVerbose(searchReq, "/" + TRIGGERS + "/" + id); + body = Optional.ofNullable(searchResponse.body()); + String searchResponseBody = null; + if (body.isPresent()) { + searchResponseBody = body.get().string(); + } + logResponseVerbose(searchResponse, searchResponseBody); if (body.isPresent()) { Optional contentType = Optional.ofNullable(body.get().contentType()); if (contentType.isPresent() && isApplicationJsonContentType(contentType.get().toString()) && searchResponse.code() == HttpsURLConnection.HTTP_OK) { - String responseStr = body.get().string(); + String responseStr = searchResponseBody; return new Gson().fromJson(responseStr, JsonObject.class); } } diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/SettingsBuilder.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/SettingsBuilder.java index 852a9be081bb..b399be860c95 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/SettingsBuilder.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/SettingsBuilder.java @@ -51,6 +51,10 @@ public class SettingsBuilder { public static final String NAME = "name"; public static final String MAVEN = "maven"; + private static final String CONNECT_TIMEOUT = "connectTimeout"; + private static final String READ_TIMEOUT = "readTimeout"; + private static final String WRITE_TIMEOUT = "writeTimeout"; + private static final String CALL_TIMEOUT = "callTimeout"; private TomlDocument settingsToml; private Settings settings; private DiagnosticResult diagnostics; @@ -66,6 +70,10 @@ public class SettingsBuilder { private static final String REPOSITORY = "repository"; private static final String ID = "id"; private static final String URL = "url"; + private static final int DEFAULT_CONNECT_TIMEOUT = 60; + private static final int DEFAULT_READ_TIMEOUT = 60; + private static final int DEFAULT_WRITE_TIMEOUT = 60; + private static final int DEFAULT_CALL_TIMEOUT = 0; private SettingsBuilder(TomlDocument settingsToml) { this.diagnosticList = new ArrayList<>(); @@ -111,6 +119,10 @@ private Settings parseAsSettings() { String proxyUsername = ""; String proxyPassword = ""; String accessToken = ""; + int connectTimeout = DEFAULT_CONNECT_TIMEOUT; + int readTimeout = DEFAULT_READ_TIMEOUT; + int writeTimeout = DEFAULT_WRITE_TIMEOUT; + int callTimeout = DEFAULT_CALL_TIMEOUT; String url = ""; String id = ""; String repoName = ""; @@ -130,6 +142,10 @@ private Settings parseAsSettings() { TomlTableNode centralNode = (TomlTableNode) tomlAstNode.entries().get(CENTRAL); if (centralNode != null && centralNode.kind() != TomlType.NONE && centralNode.kind() == TomlType.TABLE) { accessToken = getStringOrDefaultFromTomlTableNode(centralNode, ACCESS_TOKEN, ""); + connectTimeout = getIntValueFromProxyNode(centralNode, CONNECT_TIMEOUT, DEFAULT_CONNECT_TIMEOUT); + readTimeout = getIntValueFromProxyNode(centralNode, READ_TIMEOUT, DEFAULT_READ_TIMEOUT); + writeTimeout = getIntValueFromProxyNode(centralNode, WRITE_TIMEOUT, DEFAULT_WRITE_TIMEOUT); + callTimeout = getIntValueFromProxyNode(centralNode, CALL_TIMEOUT, DEFAULT_CALL_TIMEOUT); } TomlTableNode repository = (TomlTableNode) tomlAstNode.entries().get(REPOSITORY); @@ -153,8 +169,9 @@ private Settings parseAsSettings() { } } - return Settings.from(Proxy.from(host, port, proxyUsername, proxyPassword), Central.from(accessToken), - diagnostics(), repositories.toArray(new Repository[0])); + return Settings.from(Proxy.from(host, port, proxyUsername, proxyPassword), Central.from(accessToken, + connectTimeout, readTimeout, writeTimeout, callTimeout), diagnostics(), + repositories.toArray(new Repository[0])); } private String getStringOrDefaultFromTomlTableNode(TomlTableNode pkgNode, String key, String defaultValue) { diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/model/Central.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/model/Central.java index a1d5b7434124..7eac25e6b263 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/model/Central.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/model/Central.java @@ -24,17 +24,28 @@ */ public class Central { private String accesstoken = ""; + private int connectTimeout = 60; + private int readTimeout = 60; + private int writeTimeout = 60; + private int callTimeout = 60; - private Central(String accesstoken) { + + private Central(String accesstoken, int connectTimeout, int readTimeout, int writeTimeout, + int callTimeout) { this.accesstoken = accesstoken; + this.connectTimeout = connectTimeout; + this.readTimeout = readTimeout; + this.writeTimeout = writeTimeout; + this.callTimeout = callTimeout; } - public static Central from(String accesstoken) { - return new Central(accesstoken); + public static Central from(String accesstoken, int connectTimeout, int readTimeout, int writeTimeout, + int callTimeout) { + return new Central(accesstoken, connectTimeout, readTimeout, writeTimeout, callTimeout); } public static Central from() { - return new Central(""); + return new Central("", 60, 60, 60, 0); } /** @@ -46,6 +57,42 @@ public String getAccessToken() { return accesstoken; } + /** + * Get the connection timeout. + * + * @return connection timeout + */ + public int getConnectTimeout() { + return connectTimeout; + } + + /** + * Get the read timeout. + * + * @return read timeout + */ + public int getReadTimeout() { + return readTimeout; + } + + /** + * Get the write timeout. + * + * @return write timeout + */ + public int getWriteTimeout() { + return writeTimeout; + } + + /** + * Get the call timeout. + * + * @return call timeout + */ + public int getCallTimeout() { + return callTimeout; + } + /** * Sets the value of the access token. * diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/repositories/RemotePackageRepository.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/repositories/RemotePackageRepository.java index e450f2d48a71..8990fafc81b3 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/repositories/RemotePackageRepository.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/repositories/RemotePackageRepository.java @@ -75,8 +75,10 @@ public static RemotePackageRepository from(Environment environment, Path cacheDi environment, cacheDirectory, ballerinaShortVersion); Proxy proxy = initializeProxy(settings.getProxy()); CentralAPIClient client = new CentralAPIClient(repoUrl, proxy, settings.getProxy().username(), - settings.getProxy().password(), getAccessTokenOfCLI(settings)); - + settings.getProxy().password(), getAccessTokenOfCLI(settings), + settings.getCentral().getConnectTimeout(), + settings.getCentral().getReadTimeout(), settings.getCentral().getWriteTimeout(), + settings.getCentral().getCallTimeout()); return new RemotePackageRepository(fileSystemRepository, client); } diff --git a/compiler/ballerina-lang/src/main/resources/settings-toml-schema.json b/compiler/ballerina-lang/src/main/resources/settings-toml-schema.json index b23b9e050fd6..cdf4462bd681 100644 --- a/compiler/ballerina-lang/src/main/resources/settings-toml-schema.json +++ b/compiler/ballerina-lang/src/main/resources/settings-toml-schema.json @@ -29,6 +29,18 @@ "properties": { "accesstoken": { "type": "string" + }, + "connectTimeout": { + "type": "integer" + }, + "readTimeout": { + "type": "integer" + }, + "writeTimeout": { + "type": "integer" + }, + "callTimeout": { + "type": "integer" } } }, diff --git a/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/extensions/ballerina/connector/BallerinaConnectorService.java b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/extensions/ballerina/connector/BallerinaConnectorService.java index 29a8ad457919..182801505583 100644 --- a/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/extensions/ballerina/connector/BallerinaConnectorService.java +++ b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/extensions/ballerina/connector/BallerinaConnectorService.java @@ -109,7 +109,10 @@ public CompletableFuture connectors(BallerinaCon Settings settings = RepoUtils.readSettings(); CentralAPIClient client = new CentralAPIClient(RepoUtils.getRemoteRepoURL(), initializeProxy(settings.getProxy()), settings.getProxy().username(), - settings.getProxy().password(), getAccessTokenOfCLI(settings)); + settings.getProxy().password(), getAccessTokenOfCLI(settings), + settings.getCentral().getConnectTimeout(), + settings.getCentral().getReadTimeout(), settings.getCentral().getWriteTimeout(), + settings.getCentral().getCallTimeout()); JsonElement connectorSearchResult = client.getConnectors(request.getQueryMap(), "any", RepoUtils.getBallerinaVersion()); @@ -194,7 +197,10 @@ private Optional getConnectorFromCentral(BallerinaConnectorRequest r CentralAPIClient client = new CentralAPIClient(RepoUtils.getRemoteRepoURL(), initializeProxy(settings.getProxy()), settings.getProxy().username(), settings.getProxy().password(), - getAccessTokenOfCLI(settings)); + getAccessTokenOfCLI(settings), + settings.getCentral().getConnectTimeout(), + settings.getCentral().getReadTimeout(), settings.getCentral().getWriteTimeout(), + settings.getCentral().getCallTimeout()); if (request.getConnectorId() != null) { // Fetch connector by connector Id. connector = client.getConnector(request.getConnectorId(), "any", RepoUtils.getBallerinaVersion()); diff --git a/misc/ls-extensions/modules/trigger-service/src/main/java/io/ballerina/trigger/BallerinaTriggerService.java b/misc/ls-extensions/modules/trigger-service/src/main/java/io/ballerina/trigger/BallerinaTriggerService.java index 6606b924a07e..76afe925576f 100644 --- a/misc/ls-extensions/modules/trigger-service/src/main/java/io/ballerina/trigger/BallerinaTriggerService.java +++ b/misc/ls-extensions/modules/trigger-service/src/main/java/io/ballerina/trigger/BallerinaTriggerService.java @@ -75,7 +75,10 @@ public CompletableFuture triggers(BallerinaTrigger Settings settings = RepoUtils.readSettings(); CentralAPIClient client = new CentralAPIClient(RepoUtils.getRemoteRepoURL(), initializeProxy(settings.getProxy()), settings.getProxy().username(), - settings.getProxy().password(), getAccessTokenOfCLI(settings)); + settings.getProxy().password(), getAccessTokenOfCLI(settings), + settings.getCentral().getConnectTimeout(), + settings.getCentral().getReadTimeout(), settings.getCentral().getWriteTimeout(), + settings.getCentral().getCallTimeout()); JsonElement triggerSearchResult = client.getTriggers(request.getQueryMap(), "any", RepoUtils.getBallerinaVersion()); CentralTriggerListResult centralTriggerListResult = new Gson().fromJson( @@ -105,7 +108,10 @@ private Optional getTriggerFromCentral(BallerinaTriggerRequest reque CentralAPIClient client = new CentralAPIClient(RepoUtils.getRemoteRepoURL(), initializeProxy(settings.getProxy()), settings.getProxy().username(), settings.getProxy().password(), - getAccessTokenOfCLI(settings)); + getAccessTokenOfCLI(settings), + settings.getCentral().getConnectTimeout(), + settings.getCentral().getReadTimeout(), settings.getCentral().getWriteTimeout(), + settings.getCentral().getCallTimeout()); if (request.getTriggerId() != null) { trigger = client.getTrigger(request.getTriggerId(), "any", RepoUtils.getBallerinaVersion()); return Optional.of(trigger); diff --git a/misc/semver-checker/modules/semver-checker-core/src/main/java/io/ballerina/semver/checker/BallerinaPackageResolver.java b/misc/semver-checker/modules/semver-checker-core/src/main/java/io/ballerina/semver/checker/BallerinaPackageResolver.java index 7fc62c3e3510..e26e49a13243 100644 --- a/misc/semver-checker/modules/semver-checker-core/src/main/java/io/ballerina/semver/checker/BallerinaPackageResolver.java +++ b/misc/semver-checker/modules/semver-checker-core/src/main/java/io/ballerina/semver/checker/BallerinaPackageResolver.java @@ -184,7 +184,10 @@ private void initializeCentralClient() { } this.centralClient = new CentralAPIClient(RepoUtils.getRemoteRepoURL(), initializeProxy(settings.getProxy()), settings.getProxy().username(), - settings.getProxy().password(), getAccessTokenOfCLI(settings)); + settings.getProxy().password(), getAccessTokenOfCLI(settings), + settings.getCentral().getConnectTimeout(), + settings.getCentral().getReadTimeout(), settings.getCentral().getWriteTimeout(), + settings.getCentral().getCallTimeout()); } private Path resolveBalaPath(String org, String pkgName, String version) throws SemverToolException {