Problem closing WSClient in Playframework

996 views Asked by At

I have a Problem with the WSClient in playframework.

When i send a request closing the WSClient in the finally Block after :

 public WSResponse sendPostRequest(String url, String bodyAsJson,  Map<String,List<String>> headers) throws Exception {
        WSResponse response;
        CompletionStage<WSResponse> wsResponseCompletionStage;

        try {
            //Headers
            WSRequest request = ws.url(url);
            request = mapHeaderParams(headers, request);
            //sending request to api......
            wsResponseCompletionStage = request.post(bodyAsJson);
            request.getHeaders().put("Authorization", Arrays.asList("Basic "+ "xyz"));
            response = wsResponseCompletionStage.toCompletableFuture().get();
            logger.debug("Response Data from Api : " + response.getBody());
        } catch (Exception e) {
            logger.error("Error Posting Data to Api : " + e.getMessage());
            ws.close();
            throw e;
        }finally {
            ws.close();
        }
        return response;
    }

i always get an error when i want to send the next Request :

java.lang.IllegalStateException: Closed

..and when i dont close my ws client, it is constantly logging in my application.logs like this and dont stop it at all :

debug] o.a.n.c.DefaultChannelPool - Closed 0 connections out of 1 in 0 ms [debug] o.a.n.c.DefaultChannelPool - Entry count for : https://api.com:443 : 1 [debug] o.a.n.c.DefaultChannelPool - Closed 0 connections out of 1 in 0 ms [debug] o.a.n.c.DefaultChannelPool - Entry count for : https://api.com:443 : 1 [debug] o.a.n.c.DefaultChannelPool - Closed 0 connections out of 1 in 0 ms

.. so the WSClient never closes!

Here is my WebClient Class :

@Singleton
public class ApiRequestClient{

    @Inject
    private WSClient ws;

    final Logger.ALogger logger = Logger.of(this.getClass());

    @Inject
    public ApiRequestClient(WSClient ws) {
        this.ws = ws;
    }


    public WSRequest mapHeaderParams(Map<String, List<String>> headers, WSRequest request) {
        //not working !!!! ....
        //request.getHeaders().putAll(headersa);
        //thats why we do ......
        Set keySet = headers.keySet();
        for(Object key : keySet){
            request.setHeader(key.toString(), headers.get(key).get(0));
        }
        return request;
    }


    public WSResponse sendPostRequest(String url, String bodyAsJson,  Map<String,List<String>> headers) throws Exception {
        WSResponse response;
        CompletionStage<WSResponse> wsResponseCompletionStage;

        try {
            //Headers
            WSRequest request = ws.url(url);
            request = mapHeaderParams(headers, request);
            //sending request to api......
            wsResponseCompletionStage = request.post(bodyAsJson);
            //FIXME !!!!
            request.getHeaders().put("Authorization", Arrays.asList("Basic "+ "xyz"));
            response = wsResponseCompletionStage.toCompletableFuture().get();
            logger.debug("Response Data from Api : " + response.getBody());
        } catch (Exception e) {
            logger.error("Error Posting Data to Api : " + e.getMessage());
            ws.close();
            throw e;
        }finally {
            ws.close();
        }
        return response;
    }

    public static Map<String, String> queryStringToParameterMap(Map<String, String[]> queryString) {
        Map<String, String> params = new HashMap<String, String>();
        Set<String> keys = queryString.keySet();
        for (String key : keys) {
            params.put(key, queryString.get(key)[0]);
        }
        return params;
    }

}

Anyone knows this strange Behaviour??

THX a lot

1

There are 1 answers

0
Valerii Rusakov On

You don't need to close WSClient manually after each call until you use dependency injection. Play will handle it creation on start up and clean up it on shutdown automatically. This is done in AhcWSModule by subscribing on application stop hook.

You need to call close method only when creating WSClient manually as described in documentation.