From: Tomas Cere Date: Thu, 14 May 2015 15:31:09 +0000 (+0200) Subject: Http client for testing restconf X-Git-Tag: release/lithium~71 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=906e4830e121deb00efa64148a96dcc2d334ecb9 Http client for testing restconf use --help to find out all suported args. Change-Id: Ib9cae0479d672d4432bbc0fe87dc98a32f524784 Signed-off-by: Tomas Cere --- diff --git a/opendaylight/netconf/netconf-testtool/pom.xml b/opendaylight/netconf/netconf-testtool/pom.xml index 2648e67b23..afe414a94a 100644 --- a/opendaylight/netconf/netconf-testtool/pom.xml +++ b/opendaylight/netconf/netconf-testtool/pom.xml @@ -31,6 +31,11 @@ logback-classic compile + + com.ning + async-http-client + 1.9.24 + org.bouncycastle bcpkix-jdk15on @@ -71,10 +76,6 @@ org.slf4j slf4j-api - - xmlunit - xmlunit - com.google.guava guava @@ -181,9 +182,15 @@ META-INF/*.SF META-INF/*.DSA META-INF/*.RSA + org.opendaylight.controller.netconf.test.tool.client + + + com.ning + + @@ -210,6 +217,14 @@ META-INF/*.SF META-INF/*.DSA META-INF/*.RSA + org.opendaylight.controller.netconf.test.tool.client.http + org.opendaylight.controller.netconf.test.tool.rpc + org.opendaylight.controller.netconf.test.tool.AcceptingAuthProvider + org.opendaylight.controller.netconf.test.tool.DummyMonitoringService + org.opendaylight.controller.netconf.test.tool.FakeModuleBuilderCapability + org.opendaylight.controller.netconf.test.tool.Main + org.opendaylight.controller.netconf.test.tool.ModuleBuilderCapability + org.opendaylight.controller.netconf.test.tool.NetconfDeviceSimulator @@ -231,6 +246,68 @@ stress-client + + + restconf-perf-client + + shade + + package + + rest-perf-client + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + org.opendaylight.controller.netconf.test.tool.rpc + org.opendaylight.controller.netconf.test.tool.AcceptingAuthProvider + org.opendaylight.controller.netconf.test.tool.DummyMonitoringService + org.opendaylight.controller.netconf.test.tool.FakeModuleBuilderCapability + org.opendaylight.controller.netconf.test.tool.Main + org.opendaylight.controller.netconf.test.tool.ModuleBuilderCapability + org.opendaylight.controller.netconf.test.tool.NetconfDeviceSimulator + + + + + + org.bouncycastle:* + com.google:* + org.opendaylight.yangtools + org.opendaylight.yang + + + + + org.opendaylight.controller.netconf.test.tool.client.http.perf.RestPerfClient + + + true + rest-perf-client + + + + + + maven-assembly-plugin + + + src/main/assembly/stress-client.xml + + stress-client-${project.version}-package + + + + make-assembly + package + + single + + diff --git a/opendaylight/netconf/netconf-testtool/src/main/assembly/stress-client.xml b/opendaylight/netconf/netconf-testtool/src/main/assembly/stress-client.xml new file mode 100644 index 0000000000..5b640da96d --- /dev/null +++ b/opendaylight/netconf/netconf-testtool/src/main/assembly/stress-client.xml @@ -0,0 +1,30 @@ + + + + stress-client + + tar.gz + + + + target/lib + /lib + + * + + + + target + + + stress-client*.jar + + + + \ No newline at end of file diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/TestToolUtils.java b/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/TestToolUtils.java new file mode 100644 index 0000000000..0bc44082cc --- /dev/null +++ b/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/TestToolUtils.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * 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.controller.netconf.test.tool; + +public class TestToolUtils { + + public static String getMac(long mac) { + StringBuilder m = new StringBuilder(Long.toString(mac, 16)); + + for (int i = m.length(); i < 12; i++) { + m.insert(0, "0"); + } + + for (int j = m.length() - 2; j >= 2; j -= 2) { + m.insert(j, ":"); + } + + return m.toString(); + } +} diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/AsyncExecutionStrategy.java b/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/AsyncExecutionStrategy.java new file mode 100644 index 0000000000..f1d76bea07 --- /dev/null +++ b/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/AsyncExecutionStrategy.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * 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.controller.netconf.test.tool.client.http.perf; + +import com.ning.http.client.AsyncCompletionHandler; +import com.ning.http.client.AsyncHttpClient; +import com.ning.http.client.HttpResponseStatus; +import com.ning.http.client.ListenableFuture; +import com.ning.http.client.Request; +import com.ning.http.client.Response; +import java.util.ArrayList; +import java.util.concurrent.Semaphore; +import org.opendaylight.controller.netconf.test.tool.client.stress.ExecutionStrategy; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AsyncExecutionStrategy implements ExecutionStrategy{ + + private static final Logger LOG = LoggerFactory.getLogger(AsyncExecutionStrategy.class); + + private final Parameters params; + private final ArrayList payloads; + private final AsyncHttpClient asyncHttpClient; + private final Semaphore semaphore; + + AsyncExecutionStrategy(final Parameters params, final AsyncHttpClient asyncHttpClient, final ArrayList payloads) { + this.params = params; + this.asyncHttpClient = asyncHttpClient; + this.payloads = payloads; + this.semaphore = new Semaphore(RestPerfClient.throttle); + } + + @Override + public void invoke() { + final ArrayList> futures = new ArrayList<>(); + LOG.info("Begin sending async requests"); + + for (final Request request : payloads) { + try { + semaphore.acquire(); + } catch (InterruptedException e) { + LOG.warn("Semaphore acquire interrupted"); + } + futures.add(asyncHttpClient.executeRequest(request, new AsyncCompletionHandler() { + @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) throws Exception { + semaphore.release(); + return response; + } + })); + } + LOG.info("Requests sent, waiting for responses"); + + try { + semaphore.acquire(RestPerfClient.throttle); + } catch (InterruptedException e) { + LOG.warn("Semaphore acquire interrupted"); + } + + LOG.info("Responses received, ending..."); + } +} diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/Parameters.java b/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/Parameters.java new file mode 100644 index 0000000000..20f0fca2b6 --- /dev/null +++ b/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/Parameters.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * 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.controller.netconf.test.tool.client.http.perf; + +import com.google.common.base.Preconditions; +import java.io.File; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.UnknownHostException; +import net.sourceforge.argparse4j.ArgumentParsers; +import net.sourceforge.argparse4j.annotation.Arg; +import net.sourceforge.argparse4j.inf.ArgumentParser; + +public class Parameters { + + @Arg(dest = "ip") + public String ip; + + @Arg(dest = "port") + public int port; + + @Arg(dest = "destination") + public String destination; + + @Arg(dest = "edit-count") + public int editCount; + + @Arg(dest = "edit-content") + public File editContent; + + @Arg(dest = "async") + public boolean async; + + @Arg(dest = "thread-amount") + public int threadAmount; + + @Arg(dest = "same-device") + public boolean sameDevice; + + @Arg(dest = "device-port-range-start") + public int devicePortRangeStart; + + @Arg(dest = "throttle") + public int throttle; + + static ArgumentParser getParser() { + final ArgumentParser parser = ArgumentParsers.newArgumentParser("netconf stress client"); + + parser.description("Netconf stress client"); + + parser.addArgument("--ip") + .type(String.class) + .setDefault("127.0.0.1") + .help("Restconf server IP") + .dest("ip"); + + parser.addArgument("--port") + .type(Integer.class) + .setDefault(8181) + .help("Restconf server port") + .dest("port"); + + parser.addArgument("--destination") + .type(String.class) + .setDefault("/restconf/config/network-topology:network-topology/topology/topology-netconf/node/" + + "{DEVICE_PORT}-sim-device/yang-ext:mount/cisco-vpp:vpp/bridge-domains/bridge-domain/a") + .help("Destination to send the requests to after the ip:port part of the uri. " + + "Use {DEVICE_PORT} tag to use the device-port-range-start argument") + .dest("destination"); + + parser.addArgument("--edits") + .type(Integer.class) + .setDefault(50000) + .help("Amount requests to be sent") + .dest("edit-count"); + + parser.addArgument("--edit-content") + .type(File.class) + .setDefault(new File("edit.txt")) + .dest("edit-content"); + + parser.addArgument("--async-requests") + .type(Boolean.class) + .setDefault(true) + .dest("async"); + + parser.addArgument("--thread-amount") + .type(Integer.class) + .setDefault(1) + .dest("thread-amount"); + + parser.addArgument("--same-device") + .type(Boolean.class) + .setDefault(true) + .help("If true, every thread edits the device at the first port. If false, n-th thread edits device at n-th port.") + .dest("same-device"); + + parser.addArgument("--device-port-range-start") + .type(Integer.class) + .setDefault(17830) + .dest("device-port-range-start"); + + parser.addArgument("--throttle") + .type(Integer.class) + .setDefault(5000) + .help("Maximum amount of async requests that can be open at a time, " + + "with mutltiple threads this gets divided among all threads") + .dest("throttle"); + + return parser; + } + + void validate() { + Preconditions.checkArgument(port > 0, "Port =< 0"); + Preconditions.checkArgument(editCount > 0, "Edit count =< 0"); + + Preconditions.checkArgument(editContent.exists(), "Edit content file missing"); + Preconditions.checkArgument(editContent.isDirectory() == false, "Edit content file is a dir"); + Preconditions.checkArgument(editContent.canRead(), "Edit content file is unreadable"); + // TODO validate + } + + public InetSocketAddress getInetAddress() { + try { + return new InetSocketAddress(InetAddress.getByName(ip), port); + } catch (final UnknownHostException e) { + throw new IllegalArgumentException("Unknown ip", e); + } + } +} diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/PerfClientCallable.java b/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/PerfClientCallable.java new file mode 100644 index 0000000000..fa444d9b0c --- /dev/null +++ b/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/PerfClientCallable.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * 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.controller.netconf.test.tool.client.http.perf; + +import com.ning.http.client.AsyncHttpClient; +import com.ning.http.client.AsyncHttpClientConfig; +import com.ning.http.client.Request; +import java.util.ArrayList; +import java.util.concurrent.Callable; +import org.opendaylight.controller.netconf.test.tool.client.http.perf.RestPerfClient.DestToPayload; +import org.opendaylight.controller.netconf.test.tool.client.stress.ExecutionStrategy; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PerfClientCallable implements Callable{ + + private static final Logger LOG = LoggerFactory.getLogger(PerfClientCallable.class); + + private final Parameters params; + private final ArrayList payloads; + private final AsyncHttpClient asyncHttpClient; + private ExecutionStrategy executionStrategy; + + public PerfClientCallable(Parameters params, ArrayList payloads) { + this.params = params; + this.asyncHttpClient = new AsyncHttpClient(new AsyncHttpClientConfig.Builder() + .setConnectTimeout(Integer.MAX_VALUE) + .setRequestTimeout(Integer.MAX_VALUE) + .setAllowPoolingConnections(true) + .build()); + this.payloads = new ArrayList<>(); + for (DestToPayload payload : payloads) { + this.payloads.add(asyncHttpClient.preparePost(payload.getDestination()) + .addHeader("content-type", "application/json") + .addHeader("Accept", "application/xml") + .setBody(payload.getPayload()) + .setRequestTimeout(Integer.MAX_VALUE) + .build()); + } + executionStrategy = getExecutionStrategy(); + } + + private ExecutionStrategy getExecutionStrategy() { + return params.async + ? new AsyncExecutionStrategy(params, asyncHttpClient, payloads) + : new SyncExecutionStrategy(params, asyncHttpClient, payloads); + } + + @Override + public Void call() throws Exception{ + + executionStrategy.invoke(); + asyncHttpClient.closeAsynchronously(); + return null; + } +} diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/RestPerfClient.java b/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/RestPerfClient.java new file mode 100644 index 0000000000..81113b2f58 --- /dev/null +++ b/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/RestPerfClient.java @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * 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.controller.netconf.test.tool.client.http.perf; + + +import com.google.common.base.Charsets; +import com.google.common.base.Stopwatch; +import com.google.common.io.Files; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import net.sourceforge.argparse4j.inf.ArgumentParser; +import net.sourceforge.argparse4j.inf.ArgumentParserException; +import org.opendaylight.controller.netconf.test.tool.TestToolUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RestPerfClient { + + private static final Logger LOG = LoggerFactory.getLogger(RestPerfClient.class); + + private static final String HOST_KEY = "{HOST}"; + private static final String PORT_KEY = "{PORT}"; + private static final String DEVICE_PORT_KEY = "{DEVICE_PORT}"; + + private static final String PEER_KEY = "{PEERID}"; + private static final String INT_LEAF_KEY = "{INTLEAF}"; + + private static final String PHYS_ADDR_PLACEHOLDER = "{PHYS_ADDR}"; + + private static final String dest = "http://{HOST}:{PORT}"; + + private static long macStart = 0xAABBCCDD0000L; + + static int throttle; + + static final class DestToPayload { + + private final String destination; + private final String payload; + + public DestToPayload(String destination, String payload) { + this.destination = destination; + this.payload = payload; + } + + public String getDestination() { + return destination; + } + + public String getPayload() { + return payload; + } + } + + public static void main(String[] args) throws IOException { + + Parameters parameters = parseArgs(args, Parameters.getParser()); + parameters.validate(); + throttle = parameters.throttle / parameters.threadAmount; + + if (parameters.async && parameters.threadAmount > 1) { + LOG.info("Throttling per thread: {}", throttle); + } + + final String editContentString; + try { + editContentString = Files.toString(parameters.editContent, Charsets.UTF_8); + } catch (final IOException e) { + throw new IllegalArgumentException("Cannot read content of " + parameters.editContent); + } + + final int threadAmount = parameters.threadAmount; + LOG.info("thread amount: {}", threadAmount); + final int requestsPerThread = parameters.editCount / parameters.threadAmount; + LOG.info("requestsPerThread: {}", requestsPerThread); + final int leftoverRequests = parameters.editCount % parameters.threadAmount; + LOG.info("leftoverRequests: {}", leftoverRequests); + + final ArrayList> allThreadsPayloads = new ArrayList<>(); + for (int i = 0; i < threadAmount; i++) { + final ArrayList payloads = new ArrayList<>(); + for (int j = 0; j < requestsPerThread; j++) { + final int devicePort = parameters.sameDevice ? parameters.devicePortRangeStart : parameters.devicePortRangeStart + i; + final StringBuilder destBuilder = new StringBuilder(dest); + destBuilder.replace(destBuilder.indexOf(HOST_KEY), destBuilder.indexOf(HOST_KEY) + HOST_KEY.length(), parameters.ip) + .replace(destBuilder.indexOf(PORT_KEY), destBuilder.indexOf(PORT_KEY) + PORT_KEY.length(), parameters.port + ""); + final StringBuilder suffixBuilder = new StringBuilder(parameters.destination); + if (suffixBuilder.indexOf(DEVICE_PORT_KEY) != -1) { + suffixBuilder.replace(suffixBuilder.indexOf(DEVICE_PORT_KEY), suffixBuilder.indexOf(DEVICE_PORT_KEY) + DEVICE_PORT_KEY.length(), devicePort + ""); + } + destBuilder.append(suffixBuilder); + + payloads.add(new DestToPayload(destBuilder.toString(), prepareMessage(i, j, editContentString))); + } + allThreadsPayloads.add(payloads); + } + + for (int i = 0; i < leftoverRequests; i++) { + ArrayList payloads = allThreadsPayloads.get(allThreadsPayloads.size() - 1); + + final int devicePort = parameters.sameDevice ? parameters.devicePortRangeStart : parameters.devicePortRangeStart + threadAmount - 1; + final StringBuilder destBuilder = new StringBuilder(dest); + destBuilder.replace(destBuilder.indexOf(HOST_KEY), destBuilder.indexOf(HOST_KEY) + HOST_KEY.length(), parameters.ip) + .replace(destBuilder.indexOf(PORT_KEY), destBuilder.indexOf(PORT_KEY) + PORT_KEY.length(), parameters.port + ""); + final StringBuilder suffixBuilder = new StringBuilder(parameters.destination); + if (suffixBuilder.indexOf(DEVICE_PORT_KEY) != -1) { + suffixBuilder.replace(suffixBuilder.indexOf(DEVICE_PORT_KEY), suffixBuilder.indexOf(DEVICE_PORT_KEY) + DEVICE_PORT_KEY.length(), devicePort + ""); + } + destBuilder.append(suffixBuilder); + payloads.add(new DestToPayload(destBuilder.toString(), prepareMessage(threadAmount - 1, requestsPerThread + i, editContentString))); + } + + final ArrayList callables = new ArrayList<>(); + for (ArrayList payloads : allThreadsPayloads) { + callables.add(new PerfClientCallable(parameters, payloads)); + } + + final ExecutorService executorService = Executors.newFixedThreadPool(threadAmount); + + LOG.info("Starting performance test"); + final Stopwatch started = Stopwatch.createStarted(); + try { + final List> futures = executorService.invokeAll(callables, 5, TimeUnit.MINUTES); + for (final Future future : futures) { + try { + future.get(4L, TimeUnit.MINUTES); + } catch (ExecutionException | TimeoutException e) { + throw new RuntimeException(e); + } + } + executorService.shutdownNow(); + } catch (final InterruptedException e) { + throw new RuntimeException("Unable to execute requests", e); + } + started.stop(); + + LOG.info("FINISHED. Execution time: {}", started); + LOG.info("Requests per second: {}", (parameters.editCount * 1000.0 / started.elapsed(TimeUnit.MILLISECONDS))); + + System.exit(0); + } + + private static Parameters parseArgs(final String[] args, final ArgumentParser parser) { + final Parameters opt = new Parameters(); + try { + parser.parseArgs(args, opt); + return opt; + } catch (final ArgumentParserException e) { + parser.handleError(e); + } + + System.exit(1); + return null; + } + + private static String prepareMessage(final int idi, final int idj, final String editContentString) { + StringBuilder messageBuilder = new StringBuilder(editContentString); + if (editContentString.contains(PEER_KEY)) { + messageBuilder.replace(messageBuilder.indexOf(PEER_KEY), messageBuilder.indexOf(PEER_KEY) + PEER_KEY.length(), Integer.toString(idi)) + .replace(messageBuilder.indexOf(INT_LEAF_KEY), messageBuilder.indexOf(INT_LEAF_KEY) + INT_LEAF_KEY.length(), Integer.toString(idj)); + } + + int idx = messageBuilder.indexOf(PHYS_ADDR_PLACEHOLDER); + + while (idx != -1) { + messageBuilder.replace(idx, idx + PHYS_ADDR_PLACEHOLDER.length(), TestToolUtils.getMac(macStart++)); + idx = messageBuilder.indexOf(PHYS_ADDR_PLACEHOLDER); + } + + return messageBuilder.toString(); + } +} diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/SyncExecutionStrategy.java b/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/SyncExecutionStrategy.java new file mode 100644 index 0000000000..c3d964649b --- /dev/null +++ b/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/http/perf/SyncExecutionStrategy.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * 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.controller.netconf.test.tool.client.http.perf; + +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.ArrayList; +import java.util.concurrent.ExecutionException; +import org.opendaylight.controller.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 ArrayList payloads; + private final AsyncHttpClient asyncHttpClient; + + SyncExecutionStrategy(final Parameters params, final AsyncHttpClient asyncHttpClient, final ArrayList payloads) { + this.params = params; + this.asyncHttpClient = asyncHttpClient; + this.payloads = payloads; + } + + @Override + public void invoke() { + + LOG.info("Begin sending sync requests"); + for (Request request : payloads) { + 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(response.getResponseBody()); + } + } catch (InterruptedException | ExecutionException | IOException e) { + LOG.warn(e.toString()); + } + } + LOG.info("End sending sync requests"); + + } +} diff --git a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/StressClient.java b/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/StressClient.java index e03de59f2c..36b947aac4 100644 --- a/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/StressClient.java +++ b/opendaylight/netconf/netconf-testtool/src/main/java/org/opendaylight/controller/netconf/test/tool/client/stress/StressClient.java @@ -32,6 +32,7 @@ import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.opendaylight.controller.netconf.api.NetconfMessage; import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl; import org.opendaylight.controller.netconf.nettyutil.handler.ssh.client.AsyncSshHandler; +import org.opendaylight.controller.netconf.test.tool.TestToolUtils; import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.opendaylight.controller.sal.connect.api.RemoteDevice; import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator; @@ -193,7 +194,7 @@ public final class StressClient { final StringBuilder stringBuilder = new StringBuilder(specificEditContent); int idx = stringBuilder.indexOf(PHYS_ADDR_PLACEHOLDER); while (idx!= -1) { - stringBuilder.replace(idx, idx + PHYS_ADDR_PLACEHOLDER.length(), getMac(macStart++)); + stringBuilder.replace(idx, idx + PHYS_ADDR_PLACEHOLDER.length(), TestToolUtils.getMac(macStart++)); idx = stringBuilder.indexOf(PHYS_ADDR_PLACEHOLDER); } specificEditContent = stringBuilder.toString(); @@ -227,20 +228,6 @@ public final class StressClient { return netconfClientDispatcher; } - public static String getMac(long mac) { - StringBuilder m = new StringBuilder(Long.toString(mac, 16)); - - for (int i = m.length(); i < 12; i++) { - m.insert(0, "0"); - } - - for (int j = m.length() - 2; j >= 2; j-=2) { - m.insert(j, ":"); - } - - return m.toString(); - } - private static Parameters parseArgs(final String[] args, final ArgumentParser parser) { final Parameters opt = new Parameters(); try { diff --git a/opendaylight/netconf/netconf-testtool/src/main/resources/logback.xml b/opendaylight/netconf/netconf-testtool/src/main/resources/logback.xml new file mode 100644 index 0000000000..df3ab10f48 --- /dev/null +++ b/opendaylight/netconf/netconf-testtool/src/main/resources/logback.xml @@ -0,0 +1,22 @@ + + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + \ No newline at end of file