Reduce dependencies by using JRE-provided HTTP client.
JIRA: NETCONF-751
Change-Id: I49a51306a042ed534bafd7174633e300f00ce305
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
<artifactId>logback-classic</artifactId>
<scope>compile</scope>
</dependency>
- <dependency>
- <groupId>com.ning</groupId>
- <artifactId>async-http-client</artifactId>
- <version>1.9.40</version>
- </dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
*/
package org.opendaylight.netconf.test.tool;
-import com.ning.http.client.AsyncCompletionHandler;
-import com.ning.http.client.AsyncHttpClient;
-import com.ning.http.client.AsyncHttpClientConfig;
-import com.ning.http.client.HttpResponseStatus;
-import com.ning.http.client.Realm;
-import com.ning.http.client.Request;
-import com.ning.http.client.Response;
import java.io.IOException;
+import java.net.Authenticator;
+import java.net.PasswordAuthentication;
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpRequest.BodyPublishers;
+import java.net.http.HttpResponse;
+import java.net.http.HttpResponse.BodyHandlers;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
import java.util.concurrent.Semaphore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Execution implements Callable<Void> {
- private final ArrayList<Request> payloads;
- private final AsyncHttpClient asyncHttpClient;
+ private final ArrayList<HttpRequest> payloads;
+ private final HttpClient httpClient;
private static final Logger LOG = LoggerFactory.getLogger(Execution.class);
private final boolean invokeAsync;
private final Semaphore semaphore;
}
this.semaphore = new Semaphore(this.throttle);
- this.asyncHttpClient = new AsyncHttpClient(new AsyncHttpClientConfig.Builder()
- .setConnectTimeout(Integer.MAX_VALUE)
- .setRequestTimeout(Integer.MAX_VALUE)
- .setAllowPoolingConnections(true)
- .build());
-
+ this.httpClient = HttpClient.newBuilder()
+ .authenticator(new Authenticator() {
+ @Override
+ protected PasswordAuthentication getPasswordAuthentication() {
+ return new PasswordAuthentication(params.controllerAuthUsername,
+ params.controllerAuthPassword.toCharArray());
+ }
+ })
+ .build();
this.payloads = new ArrayList<>();
for (DestToPayload payload : payloads) {
- AsyncHttpClient.BoundRequestBuilder requestBuilder = asyncHttpClient.preparePost(payload.getDestination())
- .addHeader("Content-Type", "application/json")
- .addHeader("Accept", "application/json")
- .setBody(payload.getPayload())
- .setRequestTimeout(Integer.MAX_VALUE);
-
- requestBuilder.setRealm(new Realm.RealmBuilder()
- .setScheme(Realm.AuthScheme.BASIC)
- .setPrincipal(params.controllerAuthUsername)
- .setPassword(params.controllerAuthPassword)
- .setMethodName("POST")
- .setUsePreemptiveAuth(true)
- .build());
-
- this.payloads.add(requestBuilder.build());
+ HttpRequest request = HttpRequest.newBuilder(URI.create(payload.getDestination()))
+ .POST(BodyPublishers.ofString(payload.getPayload(), StandardCharsets.UTF_8))
+ .header("Content-Type", "application/json")
+ .header("Accept", "application/json")
+ .build();
+
+ this.payloads.add(request);
}
}
private void invokeSync() {
LOG.info("Begin sending sync requests");
- for (Request request : payloads) {
+ for (HttpRequest request : payloads) {
try {
- Response response = asyncHttpClient.executeRequest(request).get();
- if (response.getStatusCode() != 200 && response.getStatusCode() != 204) {
- if (response.getStatusCode() == 409) {
+ HttpResponse<String> response = httpClient.send(request, BodyHandlers.ofString());
+
+ if (response.statusCode() != 200 && response.statusCode() != 204) {
+ if (response.statusCode() == 409) {
LOG.warn("Request failed, status code: {} - one or more of the devices"
- + " is already configured, skipping the whole batch", response.getStatusCode());
+ + " is already configured, skipping the whole batch", response.statusCode());
} else {
- LOG.warn("Status code: {}", response.getStatusCode());
- LOG.warn("url: {}", request.getUrl());
- LOG.warn("body: {}", response.getResponseBody());
+ LOG.warn("Status code: {}", response.statusCode());
+ LOG.warn("url: {}", request.uri());
+ LOG.warn("body: {}", response.body());
}
}
- } catch (InterruptedException | ExecutionException | IOException e) {
+ } catch (InterruptedException | IOException e) {
LOG.warn("Failed to execute request", e);
}
}
private void invokeAsync() {
LOG.info("Begin sending async requests");
- for (final Request request : payloads) {
+ for (final HttpRequest request : payloads) {
try {
semaphore.acquire();
} catch (InterruptedException e) {
LOG.warn("Semaphore acquire interrupted");
}
- asyncHttpClient.executeRequest(request, new AsyncCompletionHandler<Response>() {
- @Override
- public STATE onStatusReceived(final HttpResponseStatus status) throws Exception {
- super.onStatusReceived(status);
- if (status.getStatusCode() != 200 && status.getStatusCode() != 204) {
- if (status.getStatusCode() == 409) {
- LOG.warn("Request failed, status code: {} - one or more of the devices"
- + " is already configured, skipping the whole batch", status.getStatusCode());
- } else {
- LOG.warn("Request failed, status code: {}",
- status.getStatusCode() + status.getStatusText());
- LOG.warn("request: {}", request.toString());
- }
+ httpClient.sendAsync(request, BodyHandlers.ofString()).whenComplete((response, error) -> {
+ if (response.statusCode() != 200 && response.statusCode() != 204) {
+ if (response.statusCode() == 409) {
+ LOG.warn("Request failed, status code: {} - one or more of the devices"
+ + " is already configured, skipping the whole batch", response.statusCode());
+ } else {
+ LOG.warn("Request failed, status code: {}", response.statusCode());
+ LOG.warn("request: {}", request);
}
- return STATE.CONTINUE;
- }
-
- @Override
- public Response onCompleted(final Response response) {
- semaphore.release();
- return response;
}
+ semaphore.release();
});
}
LOG.info("Requests sent, waiting for responses");
import ch.qos.logback.classic.Level;
import com.google.common.base.Stopwatch;
import com.google.common.io.CharStreams;
-import com.ning.http.client.AsyncHttpClient;
-import com.ning.http.client.AsyncHttpClientConfig.Builder;
-import com.ning.http.client.Request;
-import com.ning.http.client.Response;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ConnectException;
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
import java.util.List;
import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
+ "network-topology:network-topology/topology/topology-netconf/";
private static final Pattern PATTERN = Pattern.compile("connected");
- private final AsyncHttpClient asyncHttpClient = new AsyncHttpClient(new Builder()
- .setConnectTimeout(Integer.MAX_VALUE)
- .setRequestTimeout(Integer.MAX_VALUE)
- .setAllowPoolingConnections(true)
- .build());
+ private final HttpClient httpClient = HttpClient.newBuilder().build();
private final NetconfDeviceSimulator simulator;
private final int deviceCount;
- private final Request request;
+ private final HttpRequest request;
ScaleVerifyCallable(final NetconfDeviceSimulator simulator, final int deviceCount) {
LOG.info("New callable created");
this.simulator = simulator;
this.deviceCount = deviceCount;
- AsyncHttpClient.BoundRequestBuilder requestBuilder = asyncHttpClient.prepareGet(RESTCONF_URL)
- .addHeader("content-type", "application/xml")
- .addHeader("Accept", "application/xml")
- .setRequestTimeout(Integer.MAX_VALUE);
- request = requestBuilder.build();
+ request = HttpRequest.newBuilder(URI.create(RESTCONF_URL))
+ .GET()
+ .header("Content-Type", "application/xml")
+ .header("Accept", "application/xml")
+ .build();
}
@Override
public Void call() throws Exception {
try {
- final Response response = asyncHttpClient.executeRequest(request).get();
+ final HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
- if (response.getStatusCode() != 200 && response.getStatusCode() != 204) {
- LOG.warn("Request failed, status code: {}", response.getStatusCode() + response.getStatusText());
+ if (response.statusCode() != 200 && response.statusCode() != 204) {
+ LOG.warn("Request failed, status code: {}", response.statusCode());
EXECUTOR.schedule(new ScaleVerifyCallable(simulator, deviceCount), RETRY_DELAY, TimeUnit.SECONDS);
} else {
- final String body = response.getResponseBody();
+ final String body = response.body();
final Matcher matcher = PATTERN.matcher(body);
int count = 0;
while (matcher.find()) {
SEMAPHORE.release();
}
}
- } catch (ConnectException | ExecutionException e) {
+ } catch (ConnectException e) {
LOG.warn("Failed to connect to Restconf, is the controller running?", e);
EXECUTOR.schedule(new ScaleVerifyCallable(simulator, deviceCount), RETRY_DELAY, TimeUnit.SECONDS);
}
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-
package org.opendaylight.netconf.test.tool.client.http.perf;
import static org.opendaylight.netconf.test.tool.client.http.perf.RequestMessageUtils.formRequest;
-import com.ning.http.client.AsyncCompletionHandler;
-import com.ning.http.client.AsyncHttpClient;
-import com.ning.http.client.HttpResponseStatus;
-import com.ning.http.client.Request;
-import com.ning.http.client.Response;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse.BodyHandlers;
import java.util.concurrent.Semaphore;
import org.opendaylight.netconf.test.tool.client.stress.ExecutionStrategy;
import org.slf4j.Logger;
private static final Logger LOG = LoggerFactory.getLogger(AsyncExecutionStrategy.class);
+ private final HttpClient httpClient;
private final Parameters params;
- private final AsyncHttpClient asyncHttpClient;
private final Semaphore semaphore;
RestPerfClient.RequestData payloads;
- AsyncExecutionStrategy(final Parameters params, final AsyncHttpClient asyncHttpClient,
- final RestPerfClient.RequestData payloads) {
+ AsyncExecutionStrategy(final Parameters params, final HttpClient httpClient,
+ final RestPerfClient.RequestData payloads) {
this.params = params;
- this.asyncHttpClient = asyncHttpClient;
+ this.httpClient = httpClient;
this.payloads = payloads;
this.semaphore = new Semaphore(RestPerfClient.throttle);
}
LOG.info("Begin sending async requests");
for (int i = 0; i < payloads.getRequests(); i++) {
- String message = RequestMessageUtils.prepareMessage(payloads.getThreadId(), i,
+ final String message = RequestMessageUtils.prepareMessage(payloads.getThreadId(), i,
payloads.getContentString(), payloads.getPort());
- Request request = formRequest(asyncHttpClient, payloads.getDestination(), params, message);
+ final String url = payloads.getDestination();
+ final HttpRequest request = formRequest(url, message);
try {
semaphore.acquire();
} catch (InterruptedException e) {
LOG.warn("Semaphore acquire interrupted");
}
- asyncHttpClient.executeRequest(request, new AsyncCompletionHandler<Response>() {
- @Override
- public STATE onStatusReceived(HttpResponseStatus status) throws Exception {
- super.onStatusReceived(status);
- if (status.getStatusCode() != 200 && status.getStatusCode() != 204) {
- LOG.warn("Request failed, status code: {}", status.getStatusCode() + status.getStatusText());
- LOG.warn("request: {}", request.toString());
- }
- return STATE.CONTINUE;
- }
-
- @Override
- public Response onCompleted(Response response) {
- semaphore.release();
- return response;
+ httpClient.sendAsync(request, BodyHandlers.ofString()).whenComplete((response, error) -> {
+ switch (response.statusCode()) {
+ case 200:
+ case 204:
+ break;
+ default:
+ LOG.warn("Request failed, status code: {}", response.statusCode());
+ LOG.warn("request: {}", request);
}
+ semaphore.release();
});
}
LOG.info("Requests sent, waiting for responses");
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-
package org.opendaylight.netconf.test.tool.client.http.perf;
-import com.ning.http.client.AsyncHttpClient;
-import com.ning.http.client.AsyncHttpClientConfig;
+import java.net.Authenticator;
+import java.net.PasswordAuthentication;
+import java.net.http.HttpClient;
+import java.net.http.HttpClient.Builder;
import java.util.concurrent.Callable;
import org.opendaylight.netconf.test.tool.client.http.perf.RestPerfClient.RequestData;
import org.opendaylight.netconf.test.tool.client.stress.ExecutionStrategy;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
public class PerfClientCallable implements Callable<Void> {
- private static final Logger LOG = LoggerFactory.getLogger(PerfClientCallable.class);
-
- private final Parameters params;
- private final AsyncHttpClient asyncHttpClient;
- private ExecutionStrategy executionStrategy;
- private RequestData payloads;
+ private final ExecutionStrategy executionStrategy;
- public PerfClientCallable(Parameters params, RequestData payloads) {
- this.params = params;
- this.payloads = payloads;
- this.asyncHttpClient = new AsyncHttpClient(new AsyncHttpClientConfig.Builder()
- .setConnectTimeout(Integer.MAX_VALUE)
- .setRequestTimeout(Integer.MAX_VALUE)
- .setAllowPoolingConnections(true)
- .build());
- executionStrategy = getExecutionStrategy();
- }
+ public PerfClientCallable(final Parameters params, final RequestData payloads) {
+ final Builder builder = HttpClient.newBuilder();
+ if (params.auth != null) {
+ builder.authenticator(new Authenticator() {
+ @Override
+ protected PasswordAuthentication getPasswordAuthentication() {
+ return new PasswordAuthentication(params.auth.get(0), params.auth.get(1).toCharArray());
+ }
+ });
+ }
- private ExecutionStrategy getExecutionStrategy() {
- return params.async
- ? new AsyncExecutionStrategy(params, asyncHttpClient, payloads)
- : new SyncExecutionStrategy(params, asyncHttpClient, payloads);
+ this.executionStrategy = params.async
+ ? new AsyncExecutionStrategy(params, builder.build(), payloads)
+ : new SyncExecutionStrategy(builder.build(), payloads);
}
@Override
public Void call() {
executionStrategy.invoke();
- asyncHttpClient.closeAsynchronously();
return null;
}
}
*/
package org.opendaylight.netconf.test.tool.client.http.perf;
-import com.ning.http.client.AsyncHttpClient;
-import com.ning.http.client.Realm;
-import com.ning.http.client.Request;
+import java.net.URI;
+import java.net.http.HttpRequest;
+import java.net.http.HttpRequest.BodyPublishers;
+import java.nio.charset.StandardCharsets;
import org.opendaylight.netconf.test.tool.TestToolUtils;
public final class RequestMessageUtils {
return messageBuilder.toString();
}
- public static RestPerfClient.RequestData formPayload(Parameters parameters, String editContentString,
- int threadId, int requests) {
+ public static RestPerfClient.RequestData formPayload(final Parameters parameters, final String editContentString,
+ final int threadId, final int requests) {
final int devicePort = parameters.sameDevice
? parameters.devicePortRangeStart : parameters.devicePortRangeStart + threadId;
final StringBuilder destBuilder = new StringBuilder(DEST);
threadId, devicePort, requests);
}
- public static Request formRequest(AsyncHttpClient asyncHttpClient, String url, Parameters params, String msg) {
- AsyncHttpClient.BoundRequestBuilder requestBuilder = asyncHttpClient.preparePost(url)
- .addHeader("content-type", "application/json")
- .addHeader("Accept", "application/xml")
- .setBody(msg)
- .setRequestTimeout(Integer.MAX_VALUE);
-
- if (params.auth != null) {
- requestBuilder.setRealm(new Realm.RealmBuilder()
- .setScheme(Realm.AuthScheme.BASIC)
- .setPrincipal(params.auth.get(0))
- .setPassword(params.auth.get(1))
- .setUsePreemptiveAuth(true)
- .build());
- }
- return requestBuilder.build();
+ public static HttpRequest formRequest(final String url, final String msg) {
+ return HttpRequest.newBuilder(URI.create(url))
+ .POST(BodyPublishers.ofString(msg, StandardCharsets.UTF_8))
+ .header("content-type", "application/json")
+ .header("Accept", "application/xml")
+ .build();
}
-
-
}
import static org.opendaylight.netconf.test.tool.client.http.perf.RequestMessageUtils.formRequest;
-import com.ning.http.client.AsyncHttpClient;
-import com.ning.http.client.Request;
-import com.ning.http.client.Response;
import java.io.IOException;
-import java.util.concurrent.ExecutionException;
+import java.net.http.HttpClient;
+import java.net.http.HttpResponse;
+import java.net.http.HttpResponse.BodyHandlers;
import org.opendaylight.netconf.test.tool.client.stress.ExecutionStrategy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
public class SyncExecutionStrategy implements ExecutionStrategy {
-
private static final Logger LOG = LoggerFactory.getLogger(SyncExecutionStrategy.class);
- private final Parameters params;
+ private final HttpClient httpClient;
private final RestPerfClient.RequestData payloads;
- private final AsyncHttpClient asyncHttpClient;
- SyncExecutionStrategy(final Parameters params, final AsyncHttpClient asyncHttpClient,
- final RestPerfClient.RequestData payloads) {
- this.params = params;
- this.asyncHttpClient = asyncHttpClient;
+ SyncExecutionStrategy(final HttpClient httpClient, final RestPerfClient.RequestData payloads) {
+ this.httpClient = httpClient;
this.payloads = payloads;
}
LOG.info("Begin sending sync requests");
for (int i = 0; i < payloads.getRequests(); i++) {
- String message = RequestMessageUtils.prepareMessage(payloads.getThreadId(), i,
+ final String message = RequestMessageUtils.prepareMessage(payloads.getThreadId(), i,
payloads.getContentString(), payloads.getPort());
- Request request = formRequest(asyncHttpClient, payloads.getDestination(), params, message);
+ final HttpResponse<String> response;
try {
- Response response = asyncHttpClient.executeRequest(request).get();
- if (response.getStatusCode() != 200 && response.getStatusCode() != 204) {
- LOG.warn("Status code: {}", response.getStatusCode());
- LOG.warn("url: {}", request.getUrl());
- LOG.warn("body: {}", response.getResponseBody());
- }
- } catch (InterruptedException | ExecutionException | IOException e) {
+ response = httpClient.send(formRequest(payloads.getDestination(), message), BodyHandlers.ofString());
+ } catch (InterruptedException | IOException e) {
LOG.warn("Failed to execute request", e);
+ return;
+ }
+
+ if (response.statusCode() != 200 && response.statusCode() != 204) {
+ LOG.warn("Status code: {}", response.statusCode());
+ LOG.warn("url: {}", response.uri());
+ LOG.warn("body: {}", response.body());
}
}
LOG.info("End sending sync requests");
-
}
}