private JsonObject setDefaults(JsonObject config) {
   config = config.copy();
   // Set the defaults
   if (config.getNumber("session_timeout") == null) {
     config.putNumber("session_timeout", 5l * 1000);
   }
   if (config.getBoolean("insert_JSESSIONID") == null) {
     config.putBoolean("insert_JSESSIONID", true);
   }
   if (config.getNumber("heartbeat_period") == null) {
     config.putNumber("heartbeat_period", 25l * 1000);
   }
   if (config.getNumber("max_bytes_streaming") == null) {
     config.putNumber("max_bytes_streaming", 128 * 1024);
   }
   if (config.getString("prefix") == null) {
     config.putString("prefix", "/");
   }
   if (config.getString("library_url") == null) {
     config.putString("library_url", "http://cdn.sockjs.org/sockjs-0.2.1.min.js");
   }
   if (config.getArray("disabled_transports") == null) {
     config.putArray("disabled_transports", new JsonArray());
   }
   return config;
 }
 /** Redeploys a deployment. */
 private void doRedeploy(final JsonObject deploymentInfo) {
   if (deploymentInfo.getString("type").equals("module")) {
     log.info(
         String.format(
             "%s - redeploying module %s",
             DefaultGroupManager.this, deploymentInfo.getString("module")));
     final CountDownLatch latch = new CountDownLatch(1);
     platform.deployModule(
         deploymentInfo.getString("module"),
         deploymentInfo.getObject("config", new JsonObject()),
         deploymentInfo.getInteger("instances", 1),
         createRedeployHandler(deploymentInfo, latch));
     try {
       latch.await(10, TimeUnit.SECONDS);
     } catch (InterruptedException e) {
     }
   } else if (deploymentInfo.getString("type").equals("verticle")) {
     log.info(
         String.format(
             "%s - redeploying verticle %s",
             DefaultGroupManager.this, deploymentInfo.getString("main")));
     final CountDownLatch latch = new CountDownLatch(1);
     if (deploymentInfo.getBoolean("worker", false)) {
       platform.deployWorkerVerticle(
           deploymentInfo.getString("main"),
           deploymentInfo.getObject("config", new JsonObject()),
           deploymentInfo.getInteger("instances", 1),
           deploymentInfo.getBoolean("multi-threaded"),
           createRedeployHandler(deploymentInfo, latch));
     } else {
       platform.deployVerticle(
           deploymentInfo.getString("main"),
           deploymentInfo.getObject("config", new JsonObject()),
           deploymentInfo.getInteger("instances", 1),
           createRedeployHandler(deploymentInfo, latch));
     }
     try {
       latch.await(10, TimeUnit.SECONDS);
     } catch (InterruptedException e) {
     }
   }
 }
  /*
  Empty inboundPermitted means reject everything - this is the default.
  If at least one match is supplied and all the fields of any match match then the message inboundPermitted,
  this means that specifying one match with a JSON empty object means everything is accepted
   */
  private Match checkMatches(boolean inbound, String address, Object body) {

    if (inbound && acceptedReplyAddresses.remove(address)) {
      // This is an inbound reply, so we accept it
      return new Match(true, false);
    }

    List<JsonObject> matches = inbound ? inboundPermitted : outboundPermitted;

    for (JsonObject matchHolder : matches) {
      String matchAddress = matchHolder.getString("address");
      String matchRegex;
      if (matchAddress == null) {
        matchRegex = matchHolder.getString("address_re");
      } else {
        matchRegex = null;
      }

      boolean addressOK;
      if (matchAddress == null) {
        if (matchRegex == null) {
          addressOK = true;
        } else {
          addressOK = regexMatches(matchRegex, address);
        }
      } else {
        addressOK = matchAddress.equals(address);
      }

      if (addressOK) {
        boolean matched = true;
        // Can send message other than JSON too - in which case we can't do deep matching on
        // structure of message
        if (body instanceof JsonObject) {
          JsonObject match = matchHolder.getObject("match");
          if (match != null) {
            for (String fieldName : match.getFieldNames()) {
              if (!match.getField(fieldName).equals(((JsonObject) body).getField(fieldName))) {
                matched = false;
                break;
              }
            }
          }
        }
        if (matched) {
          Boolean b = matchHolder.getBoolean("requires_auth");
          return new Match(true, b != null && b);
        }
      }
    }
    return new Match(false, false);
  }
  public void start() {

    // handler config JSON
    JsonObject config = container.config();

    int port = config.getNumber("hec_port").intValue();
    int poolsize = config.getNumber("hec_poolsize").intValue();
    this.token = config.getString("hec_token");
    this.index = config.getString("index");
    this.source = config.getString("source");
    this.sourcetype = config.getString("sourcetype");
    boolean useHTTPs = config.getBoolean("hec_https");

    this.hecBatchMode = config.getBoolean("hec_batch_mode");
    this.hecMaxBatchSizeBytes = config.getNumber("hec_max_batch_size_bytes").longValue();
    this.hecMaxBatchSizeEvents = config.getNumber("hec_max_batch_size_events").longValue();
    this.hecMaxInactiveTimeBeforeBatchFlush =
        config.getNumber("hec_max_inactive_time_before_batch_flush").longValue();

    this.batchBuffer = Collections.synchronizedList(new LinkedList<String>());
    this.lastEventReceivedTime = System.currentTimeMillis();

    // Event Bus (so we can receive the data)
    String eventBusAddress = config.getString("output_address");
    EventBus eb = vertx.eventBus();

    client = vertx.createHttpClient().setPort(port).setHost("localhost").setMaxPoolSize(poolsize);
    if (useHTTPs) {
      client.setSSLContext(getSSLContext());
      client.setVerifyHost(false);
      client.setSSL(true);
      client.setTrustAll(true);
    }

    // data handler that will process our received data
    Handler<Message<String>> myHandler =
        new Handler<Message<String>>() {

          public void handle(Message<String> message) {

            try {

              String messageContent = escapeMessageIfNeeded(message.body());

              StringBuffer json = new StringBuffer();
              json.append("{\"").append("event\":").append(messageContent).append(",\"");

              if (!index.equalsIgnoreCase("default"))
                json.append("index\":\"").append(index).append("\",\"");

              json.append("source\":\"")
                  .append(source)
                  .append("\",\"")
                  .append("sourcetype\":\"")
                  .append(sourcetype)
                  .append("\"")
                  .append("}");

              String bodyContent = json.toString();

              if (hecBatchMode) {
                lastEventReceivedTime = System.currentTimeMillis();
                currentBatchSizeBytes += bodyContent.length();
                batchBuffer.add(bodyContent);
                if (flushBuffer()) {
                  bodyContent = rollOutBatchBuffer();
                  batchBuffer.clear();
                  currentBatchSizeBytes = 0;
                  hecPost(bodyContent);
                }
              } else {
                hecPost(bodyContent);
              }

            } catch (Exception e) {
              logger.error("Error writing received data: " + ModularInput.getStackTrace(e));
            }
          }

          /**
           * from Tivo
           *
           * @param message
           * @return
           */
          private String escapeMessageIfNeeded(String message) {
            String trimmedMessage = message.trim();
            if (trimmedMessage.startsWith("{") && trimmedMessage.endsWith("}")) {
              // this is *probably* JSON.
              return trimmedMessage;
            } else if (trimmedMessage.startsWith("\"")
                && trimmedMessage.endsWith("\"")
                && !message.substring(1, message.length() - 1).contains("\"")) {
              // this appears to be a quoted string with no internal
              // quotes
              return trimmedMessage;
            } else {
              // don't know what this thing is, so need to escape all
              // quotes, and
              // then wrap the result in quotes
              return "\"" + message.replace("\"", "\\\"") + "\"";
            }
          }
        };

    if (hecBatchMode) {
      new BatchBufferActivityCheckerThread().start();
    }
    // start listening for data
    eb.registerHandler(eventBusAddress, myHandler);
  }