Merge "Add some validations and new arguments"
authorTomas Cere <tcere@cisco.com>
Wed, 4 May 2016 12:48:59 +0000 (12:48 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 4 May 2016 12:48:59 +0000 (12:48 +0000)
1  2 
netconf/tools/netconf-testtool/src/main/java/org/opendaylight/netconf/test/tool/TesttoolParameters.java

index 1d8eda8f7891298dce5769734490bd3d44925c61,0ad0f1831c8d5dd3b4606b518c9d537c55301554..23ed222c37c1153acc41a1c815e179403879b8d3
@@@ -1,5 -1,5 +1,5 @@@
  /*
 - * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
 + * Copyright (c) 2016 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,
@@@ -19,7 -19,6 +19,7 @@@ import java.io.IOException
  import java.io.InputStream;
  import java.io.InputStreamReader;
  import java.util.ArrayList;
 +import java.util.Iterator;
  import java.util.List;
  import java.util.concurrent.TimeUnit;
  import java.util.regex.Pattern;
@@@ -34,53 -33,80 +34,59 @@@ public class TesttoolParameters 
      private static final String PORT_KEY = "{PORT}";
      private static final String SSH = "{SSH}";
      private static final String ADDRESS_PORT = "{ADDRESS:PORT}";
 -    private static final String dest = "http://{ADDRESS:PORT}/restconf/config/network-topology:network-topology/topology/topology-netconf/node/{PORT}-sim-device";
 -
 -    private static final String RESOURCE = "/config-template.xml";
 -    private InputStream stream;
 +    private static final String dest = "http://{ADDRESS:PORT}/restconf/config/network-topology:network-topology/topology/topology-netconf/";
  
 +    private static final String RESOURCE = "/config-template.json";
      @Arg(dest = "edit-content")
      public File editContent;
 -
      @Arg(dest = "async")
      public boolean async;
 -
      @Arg(dest = "thread-amount")
      public int threadAmount;
 -
      @Arg(dest = "throttle")
      public int throttle;
 -
      @Arg(dest = "auth")
      public ArrayList<String> auth;
 -
      @Arg(dest = "controller-destination")
      public String controllerDestination;
 -
      @Arg(dest = "schemas-dir")
      public File schemasDir;
 -
      @Arg(dest = "devices-count")
      public int deviceCount;
 -
      @Arg(dest = "devices-per-port")
      public int devicesPerPort;
 -
      @Arg(dest = "starting-port")
      public int startingPort;
 -
      @Arg(dest = "generate-config-connection-timeout")
      public int generateConfigsTimeout;
 -
      @Arg(dest = "generate-config-address")
      public String generateConfigsAddress;
 -
      @Arg(dest = "distro-folder")
      public File distroFolder;
 -
      @Arg(dest = "generate-configs-batch-size")
      public int generateConfigBatchSize;
 -
      @Arg(dest = "ssh")
      public boolean ssh;
 -
      @Arg(dest = "exi")
      public boolean exi;
 -
      @Arg(dest = "debug")
      public boolean debug;
 -
      @Arg(dest = "notification-file")
      public File notificationFile;
 -
      @Arg(dest = "md-sal")
      public boolean mdSal;
 -
      @Arg(dest = "initial-config-xml-file")
      public File initialConfigXMLFile;
 -
      @Arg(dest = "time-out")
      public long timeOut;
 +    private InputStream stream;
  
+     @Arg(dest = "ip")
+     public String ip;
+     @Arg(dest = "thread-pool-size")
+     public int threadPoolSize;
      static ArgumentParser getParser() {
          final ArgumentParser parser = ArgumentParsers.newArgumentParser("netconf testtool");
  
          parser.addArgument("--thread-amount")
                  .type(Integer.class)
                  .setDefault(1)
-                 .dest("thread-amount");
+                 .dest("thread-amount")
+                 .help("The number of threads to use for configuring devices.");
  
          parser.addArgument("--throttle")
                  .type(Integer.class)
  
          parser.addArgument("--controller-destination")
                  .type(String.class)
 -                .help("Ip address and port of controller. Must be in following format <ip>:<port> "+
 -                      "if available it will be used for spawning netconf connectors via topology configuration as "+
 -                      "a part of URI. Example (http://<controller destination>/restconf/config/network-topology:network-topology/topology/topology-netconf/node/<node-id>)"+
 -                      "otherwise it will just start simulated devices and skip the execution of PUT requests")
 +                .help("Ip address and port of controller. Must be in following format <ip>:<port> " +
 +                        "if available it will be used for spawning netconf connectors via topology configuration as " +
 +                        "a part of URI. Example (http://<controller destination>/restconf/config/network-topology:network-topology/topology/topology-netconf/node/<node-id>)" +
 +                        "otherwise it will just start simulated devices and skip the execution of PUT requests")
                  .dest("controller-destination");
  
          parser.addArgument("--device-count")
  
          parser.addArgument("--generate-configs-batch-size")
                  .type(Integer.class)
 -                .setDefault(4000)
 +                .setDefault(1)
                  .help("Number of connector configs per generated file")
                  .dest("generate-configs-batch-size");
  
                  .help("the maximum time in seconds for executing each PUT request")
                  .dest("time-out");
  
+         parser.addArgument("-ip")
+                 .type(String.class)
+                 .setDefault("0.0.0.0")
+                 .help("Ip address which will be used for creating a socket address." +
+                         "It can either be a machine name, such as " +
+                         "java.sun.com, or a textual representation of its IP address.")
+                 .dest("ip");
+         parser.addArgument("--thread-pool-size")
+                 .type(Integer.class)
+                 .setDefault(8)
+                 .help("The number of threads to keep in the pool, when creating a device simulator. Even if they are idle.")
+                 .dest("thread-pool-size");
          return parser;
      }
  
          return null;
      }
  
 +    private static String modifyMessage(final StringBuilder payloadBuilder, final int payloadPosition, final int size) {
 +        if (size == 1) {
 +            return payloadBuilder.toString();
 +        }
 +
 +        if (payloadPosition == 0) {
 +            payloadBuilder.insert(payloadBuilder.toString().indexOf('{', 2), "[");
 +            payloadBuilder.replace(payloadBuilder.length() - 1, payloadBuilder.length(), ",");
 +        } else if (payloadPosition + 1 == size) {
 +            payloadBuilder.delete(0, payloadBuilder.toString().indexOf(':') + 1);
 +            payloadBuilder.insert(payloadBuilder.toString().indexOf('}', 2) + 1, "]");
 +        } else {
 +            payloadBuilder.delete(0, payloadBuilder.toString().indexOf(':') + 1);
 +            payloadBuilder.replace(payloadBuilder.length() - 2, payloadBuilder.length() - 1, ",");
 +            payloadBuilder.deleteCharAt(payloadBuilder.toString().lastIndexOf('}'));
 +        }
 +        return payloadBuilder.toString();
 +    }
 +
      void validate() {
          if (editContent == null) {
              stream = TesttoolParameters.class.getResourceAsStream(RESOURCE);
          }
      }
  
 -    public ArrayList<ArrayList<Execution.DestToPayload>> getThreadsPayloads(List<Integer> openDevices) {
 +    public ArrayList<ArrayList<Execution.DestToPayload>> getThreadsPayloads(final List<Integer> openDevices) {
          final String editContentString;
          try {
 -            if(stream == null)
 -            {
 +            if (stream == null) {
                  editContentString = Files.toString(editContent, Charsets.UTF_8);
              } else {
                  editContentString = CharStreams.toString(new InputStreamReader(stream, Charsets.UTF_8));
              throw new IllegalArgumentException("Cannot read content of " + editContent);
          }
  
 +        int from, to;
 +        Iterator<Integer> iterator;
 +
          final ArrayList<ArrayList<Execution.DestToPayload>> allThreadsPayloads = new ArrayList<>();
 -        for (int i = 0; i < threadAmount; i++) {
 -            final ArrayList<Execution.DestToPayload> payloads = new ArrayList<>();
 -            for (int j = 0; j < openDevices.size(); j++) {
 -                final StringBuilder destBuilder = new StringBuilder(dest);
 -                destBuilder.replace(destBuilder.indexOf(ADDRESS_PORT), destBuilder.indexOf(ADDRESS_PORT) + ADDRESS_PORT.length(), controllerDestination)
 -                        .replace(destBuilder.indexOf(PORT_KEY), destBuilder.indexOf(PORT_KEY) + PORT_KEY.length(), Integer.toString(openDevices.get(j)));
 -                payloads.add(new Execution.DestToPayload(destBuilder.toString(), prepareMessage(openDevices.get(j), editContentString)));
 +        if (generateConfigBatchSize > 1) {
 +
 +            final int batchedRequests = openDevices.size() / generateConfigBatchSize;
 +            final int batchedRequestsPerThread = batchedRequests / threadAmount;
 +            final int leftoverBatchedRequests = (batchedRequests) % threadAmount;
 +            final int leftoverRequests = openDevices.size() - (batchedRequests * generateConfigBatchSize);
 +
 +            final StringBuilder destBuilder = new StringBuilder(dest);
 +            destBuilder.replace(destBuilder.indexOf(ADDRESS_PORT), destBuilder.indexOf(ADDRESS_PORT) + ADDRESS_PORT.length(), controllerDestination);
 +
 +            for (int l = 0; l < threadAmount; l++) {
 +                from = l * (batchedRequests * batchedRequestsPerThread);
 +                to = from + (batchedRequests * batchedRequestsPerThread);
 +                iterator = openDevices.subList(from, to).iterator();
 +                allThreadsPayloads.add(createBatchedPayloads(batchedRequestsPerThread, iterator, editContentString, destBuilder.toString()));
 +            }
 +            ArrayList<Execution.DestToPayload> payloads = null;
 +            if (leftoverBatchedRequests > 0) {
 +                from = threadAmount * (batchedRequests * batchedRequestsPerThread);
 +                to = from + (batchedRequests * batchedRequestsPerThread);
 +                iterator = openDevices.subList(from, to).iterator();
 +                payloads = createBatchedPayloads(leftoverBatchedRequests, iterator, editContentString, destBuilder.toString());
 +            }
 +            String payload = "";
 +
 +            for (int j = 0; j < leftoverRequests; j++) {
 +                from = openDevices.size() - leftoverRequests;
 +                to = openDevices.size();
 +                iterator = openDevices.subList(from, to).iterator();
 +                final StringBuilder payloadBuilder = new StringBuilder(prepareMessage(iterator.next(), editContentString));
 +                payload += modifyMessage(payloadBuilder, j, leftoverRequests);
 +            }
 +            if (leftoverRequests > 0 || leftoverBatchedRequests > 0) {
 +
 +                if (payloads != null) {
 +                    payloads.add(new Execution.DestToPayload(destBuilder.toString(), payload));
 +                }
 +                allThreadsPayloads.add(payloads);
 +            }
 +        } else {
 +            final int requestPerThreads = openDevices.size() / threadAmount;
 +            final int leftoverRequests = openDevices.size() % threadAmount;
 +
 +            for (int i = 0; i < threadAmount; i++) {
 +                from = i * requestPerThreads;
 +                to = from + requestPerThreads;
 +                iterator = openDevices.subList(from, to).iterator();
 +                allThreadsPayloads.add(createPayloads(iterator, editContentString));
              }
 -            allThreadsPayloads.add(payloads);
 -        }
  
 +            if (leftoverRequests > 0) {
 +                from = (threadAmount) * requestPerThreads;
 +                to = from + leftoverRequests;
 +                iterator = openDevices.subList(from, to).iterator();
 +                allThreadsPayloads.add(createPayloads(iterator, editContentString));
 +            }
 +        }
          return allThreadsPayloads;
      }
  
          }
          return messageBuilder.toString();
      }
 +
 +    private ArrayList<Execution.DestToPayload> createPayloads(final Iterator<Integer> openDevices, final String editContentString) {
 +        final ArrayList<Execution.DestToPayload> payloads = new ArrayList<>();
 +
 +        while (openDevices.hasNext()) {
 +            final StringBuilder destBuilder = new StringBuilder(dest);
 +            destBuilder.replace(destBuilder.indexOf(ADDRESS_PORT), destBuilder.indexOf(ADDRESS_PORT) + ADDRESS_PORT.length(), controllerDestination);
 +            payloads.add(new Execution.DestToPayload(destBuilder.toString(), prepareMessage(openDevices.next(), editContentString)));
 +        }
 +        return payloads;
 +    }
 +
 +    private ArrayList<Execution.DestToPayload> createBatchedPayloads(final int batchedRequestsCount, final Iterator<Integer> openDevices, final String editContentString,
 +                                                                     final String destination) {
 +        final ArrayList<Execution.DestToPayload> payloads = new ArrayList<>();
 +
 +        for (int i = 0; i < batchedRequestsCount; i++) {
 +            String payload = "";
 +            for (int j = 0; j < generateConfigBatchSize; j++) {
 +                final StringBuilder payloadBuilder = new StringBuilder(prepareMessage(openDevices.next(), editContentString));
 +                payload += modifyMessage(payloadBuilder, j, generateConfigBatchSize);
 +            }
 +            payloads.add(new Execution.DestToPayload(destination, payload));
 +        }
 +        return payloads;
 +    }
  }