Skip to content

PR Problems Summary #37

@aicodeguard

Description

@aicodeguard

PR Problems Summary

This PR introduces a new JiraService that contains a critical performance and stability issue. The HTTP client implementation creates a new, deprecated DefaultHttpClient instance for every request. This pattern bypasses connection pooling and fails to apply the configured timeouts, which can lead to resource exhaustion (port/thread starvation) and application hangs in production environments.


1. Inefficient and Unsafe HTTP Client Usage

File: src/main/java/com/aliyun/api/gateway/demo/service/JiraService.java
Lines: 207-228

Description:
The executeGet, executePost, executePut, and executeDelete methods each instantiate a new DefaultHttpClient. This class is deprecated, heavy to instantiate, and does not share connections. Furthermore, the timeout configured in JiraConfig is completely ignored, leaving the client with default (potentially infinite) timeouts.

Snippet:

private String executeGet(String url) throws Exception {
    HttpClient httpClient = new DefaultHttpClient(); // Deprecated, expensive, no pooling
    HttpGet httpGet = new HttpGet(url);
    // ...
    try {
        HttpResponse response = httpClient.execute(httpGet);
        // ...
    } finally {
        httpClient.getConnectionManager().shutdown();
    }
}

Suggested Fix:

  1. Replace DefaultHttpClient with a shared CloseableHttpClient instance (singleton or bean).
  2. Configure the client with a PoolingHttpClientConnectionManager.
  3. Apply the timeout from JiraConfig to the RequestConfig.

Example Code:

// In JiraService class
private final CloseableHttpClient httpClient;

public JiraService(JiraConfig config) {
    this.config = config;
    // ... auth setup ...

    RequestConfig requestConfig = RequestConfig.custom()
            .setConnectTimeout(config.getTimeout())
            .setSocketTimeout(config.getTimeout())
            .setConnectionRequestTimeout(config.getTimeout())
            .build();

    this.httpClient = HttpClients.custom()
            .setDefaultRequestConfig(requestConfig)
            .setMaxConnTotal(50)
            .setMaxConnPerRoute(10)
            .build();
}

private String executeGet(String url) throws Exception {
    HttpGet httpGet = new HttpGet(url);
    httpGet.setHeader("Authorization", authHeader);
    // ... other headers ...

    try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
        int statusCode = response.getStatusLine().getStatusCode();
        String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");
        if (statusCode >= 200 && statusCode < 300) {
            return responseBody;
        } else {
            throw new Exception("Jira API Error: " + statusCode + " - " + responseBody);
        }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions