Package net.kuujo.vertigo.cluster.impl

Source Code of net.kuujo.vertigo.cluster.impl.DefaultCluster

/*
* Copyright 2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.kuujo.vertigo.cluster.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.kuujo.vertigo.Config;
import net.kuujo.vertigo.cluster.Cluster;
import net.kuujo.vertigo.cluster.ClusterException;
import net.kuujo.vertigo.cluster.Group;
import net.kuujo.vertigo.cluster.Node;
import net.kuujo.vertigo.cluster.data.AsyncCounter;
import net.kuujo.vertigo.cluster.data.AsyncList;
import net.kuujo.vertigo.cluster.data.AsyncMap;
import net.kuujo.vertigo.cluster.data.AsyncMultiMap;
import net.kuujo.vertigo.cluster.data.AsyncQueue;
import net.kuujo.vertigo.cluster.data.AsyncSet;
import net.kuujo.vertigo.cluster.data.impl.DefaultAsyncCounter;
import net.kuujo.vertigo.cluster.data.impl.DefaultAsyncList;
import net.kuujo.vertigo.cluster.data.impl.DefaultAsyncMap;
import net.kuujo.vertigo.cluster.data.impl.DefaultAsyncMultiMap;
import net.kuujo.vertigo.cluster.data.impl.DefaultAsyncQueue;
import net.kuujo.vertigo.cluster.data.impl.DefaultAsyncSet;
import net.kuujo.vertigo.component.ComponentConfig;
import net.kuujo.vertigo.component.ModuleConfig;
import net.kuujo.vertigo.network.ActiveNetwork;
import net.kuujo.vertigo.network.NetworkConfig;
import net.kuujo.vertigo.network.NetworkContext;
import net.kuujo.vertigo.network.impl.DefaultActiveNetwork;
import net.kuujo.vertigo.network.impl.DefaultNetworkConfig;
import net.kuujo.vertigo.util.Args;
import net.kuujo.vertigo.util.Configs;
import net.kuujo.vertigo.util.Contexts;
import net.kuujo.vertigo.util.CountingCompletionHandler;
import net.kuujo.vertigo.util.serialization.SerializerFactory;

import org.vertx.java.core.AsyncResult;
import org.vertx.java.core.Handler;
import org.vertx.java.core.Vertx;
import org.vertx.java.core.eventbus.Message;
import org.vertx.java.core.impl.DefaultFutureResult;
import org.vertx.java.core.json.JsonArray;
import org.vertx.java.core.json.JsonObject;
import org.vertx.java.platform.Container;

/**
* Default cluster client implementation.
*
* @author <a href="http://github.com/kuujo">Jordan Halterman</a>
*/
public class DefaultCluster implements Cluster {
  private static final long DEFAULT_REPLY_TIMEOUT = 30000;
  private final String address;
  private final Vertx vertx;
  private final Container container;
  private final Map<Handler<Node>, Handler<Message<String>>> joinHandlers = new HashMap<>();
  private final Map<Handler<Node>, Handler<Message<String>>> leaveHandlers = new HashMap<>();

  public DefaultCluster(String address, Vertx vertx, Container container) {
    Args.checkUriScheme(address, "%s is not a valid cluster address. Cluster addresses must be alpha-numeric, begin with a letter, and may contain the following symbols: -.+", address);
    this.address = address;
    this.vertx = vertx;
    this.container = container;
  }

  @Override
  public String address() {
    return address;
  }

  @Override
  public Cluster registerJoinHandler(final Handler<Node> handler) {
    return registerJoinHandler(handler, null);
  }

  @Override
  public Cluster registerJoinHandler(final Handler<Node> handler, final Handler<AsyncResult<Void>> doneHandler) {
    Handler<Message<String>> messageHandler = new Handler<Message<String>>() {
      @Override
      public void handle(Message<String> message) {
        handler.handle(new DefaultNode(message.body(), vertx, container));
      }
    };
    joinHandlers.put(handler, messageHandler);
    vertx.eventBus().registerHandler(String.format("%s.join", address), messageHandler, doneHandler);
    return this;
  }

  @Override
  public Cluster unregisterJoinHandler(final Handler<Node> handler) {
    return unregisterJoinHandler(handler, null);
  }

  @Override
  public Cluster unregisterJoinHandler(final Handler<Node> handler, final Handler<AsyncResult<Void>> doneHandler) {
    Handler<Message<String>> messageHandler = joinHandlers.remove(handler);
    if (messageHandler != null) {
      vertx.eventBus().unregisterHandler(String.format("%s.join", address), messageHandler, doneHandler);
    } else {
      new DefaultFutureResult<Void>((Void) null).setHandler(doneHandler);
    }
    return this;
  }

  @Override
  public Cluster registerLeaveHandler(final Handler<Node> handler) {
    return registerLeaveHandler(handler, null);
  }

  @Override
  public Cluster registerLeaveHandler(final Handler<Node> handler, final Handler<AsyncResult<Void>> doneHandler) {
    Handler<Message<String>> messageHandler = new Handler<Message<String>>() {
      @Override
      public void handle(Message<String> message) {
        handler.handle(new DefaultNode(message.body(), vertx, container));
      }
    };
    leaveHandlers.put(handler, messageHandler);
    vertx.eventBus().registerHandler(String.format("%s.leave", address), messageHandler, doneHandler);
    return this;
  }

  @Override
  public Cluster unregisterLeaveHandler(final Handler<Node> handler) {
    return unregisterLeaveHandler(handler, null);
  }

  @Override
  public Cluster unregisterLeaveHandler(final Handler<Node> handler, final Handler<AsyncResult<Void>> doneHandler) {
    Handler<Message<String>> messageHandler = leaveHandlers.remove(handler);
    if (messageHandler != null) {
      vertx.eventBus().unregisterHandler(String.format("%s.leave", address), messageHandler, doneHandler);
    } else {
      new DefaultFutureResult<Void>((Void) null).setHandler(doneHandler);
    }
    return this;
  }

  @Override
  public Cluster ping(final Handler<AsyncResult<Cluster>> resultHandler) {
    JsonObject message = new JsonObject()
        .putString("action", "ping");
    vertx.eventBus().sendWithTimeout(address, message, DEFAULT_REPLY_TIMEOUT, new Handler<AsyncResult<Message<JsonObject>>>() {
      @Override
      public void handle(AsyncResult<Message<JsonObject>> result) {
        if (result.failed()) {
          new DefaultFutureResult<Cluster>(new ClusterException(result.cause())).setHandler(resultHandler);
        } else if (result.result().body().getString("status").equals("error")) {
          new DefaultFutureResult<Cluster>(new ClusterException(result.result().body().getString("message"))).setHandler(resultHandler);
        } else if (result.result().body().getString("status").equals("pong")) {
          if (result.result().body().getString("result").equals("cluster")) {
            new DefaultFutureResult<Cluster>(DefaultCluster.this).setHandler(resultHandler);
          } else {
            new DefaultFutureResult<Cluster>(new ClusterException("Not a valid cluster address.")).setHandler(resultHandler);
          }
        }
      }
    });
    return this;
  }

  @Override
  public Cluster getGroup(final String group, final Handler<AsyncResult<Group>> resultHandler) {
    JsonObject message = new JsonObject()
        .putString("action", "find")
        .putString("type", "group")
        .putString("group", group);
    vertx.eventBus().sendWithTimeout(address, message, DEFAULT_REPLY_TIMEOUT, new Handler<AsyncResult<Message<JsonObject>>>() {
      @Override
      public void handle(AsyncResult<Message<JsonObject>> result) {
        if (result.failed()) {
          new DefaultFutureResult<Group>(new ClusterException(result.cause())).setHandler(resultHandler);
        } else if (result.result().body().getString("status").equals("error")) {
          new DefaultFutureResult<Group>(new ClusterException(result.result().body().getString("message"))).setHandler(resultHandler);
        } else if (result.result().body().getString("status").equals("ok")) {
          new DefaultFutureResult<Group>(new DefaultGroup(result.result().body().getString("result"), vertx, container)).setHandler(resultHandler);
        }
      }
    });
    return this;
  }

  @Override
  public Cluster getGroups(final Handler<AsyncResult<Collection<Group>>> resultHandler) {
    JsonObject message = new JsonObject()
        .putString("action", "list")
        .putString("type", "group");
    vertx.eventBus().sendWithTimeout(address, message, DEFAULT_REPLY_TIMEOUT, new Handler<AsyncResult<Message<JsonObject>>>() {
      @Override
      public void handle(AsyncResult<Message<JsonObject>> result) {
        if (result.failed()) {
          new DefaultFutureResult<Collection<Group>>(new ClusterException(result.cause())).setHandler(resultHandler);
        } else if (result.result().body().getString("status").equals("error")) {
          new DefaultFutureResult<Collection<Group>>(new ClusterException(result.result().body().getString("message"))).setHandler(resultHandler);
        } else if (result.result().body().getString("status").equals("ok")) {
          JsonArray jsonGroups = result.result().body().getArray("result");
          List<Group> groups = new ArrayList<>();
          for (Object jsonGroup : jsonGroups) {
            groups.add(new DefaultGroup((String) jsonGroup, vertx, container));
          }
          new DefaultFutureResult<Collection<Group>>(groups).setHandler(resultHandler);
        }
      }
    });
    return this;
  }

  @Override
  public Cluster selectGroup(Object key, final Handler<AsyncResult<Group>> resultHandler) {
    JsonObject message = new JsonObject()
        .putString("action", "select")
        .putString("type", "group")
        .putValue("key", key);
    vertx.eventBus().sendWithTimeout(address, message, DEFAULT_REPLY_TIMEOUT, new Handler<AsyncResult<Message<JsonObject>>>() {
      @Override
      public void handle(AsyncResult<Message<JsonObject>> result) {
        if (result.failed()) {
          new DefaultFutureResult<Group>(new ClusterException(result.cause())).setHandler(resultHandler);
        } else if (result.result().body().getString("status").equals("error")) {
          new DefaultFutureResult<Group>(new ClusterException(result.result().body().getString("message"))).setHandler(resultHandler);
        } else if (result.result().body().getString("status").equals("ok")) {
          new DefaultFutureResult<Group>(new DefaultGroup(result.result().body().getString("result"), vertx, container)).setHandler(resultHandler);
        }
      }
    });
    return this;
  }

  @Override
  public Cluster getNode(String node, final Handler<AsyncResult<Node>> resultHandler) {
    JsonObject message = new JsonObject()
        .putString("action", "find")
        .putString("type", "node")
        .putString("node", node);
    vertx.eventBus().sendWithTimeout(address, message, DEFAULT_REPLY_TIMEOUT, new Handler<AsyncResult<Message<JsonObject>>>() {
      @Override
      public void handle(AsyncResult<Message<JsonObject>> result) {
        if (result.failed()) {
          new DefaultFutureResult<Node>(new ClusterException(result.cause())).setHandler(resultHandler);
        } else if (result.result().body().getString("status").equals("error")) {
          new DefaultFutureResult<Node>(new ClusterException(result.result().body().getString("message"))).setHandler(resultHandler);
        } else if (result.result().body().getString("status").equals("ok")) {
          new DefaultFutureResult<Node>(new DefaultNode(result.result().body().getString("result"), vertx, container)).setHandler(resultHandler);
        }
      }
    });
    return this;
  }

  @Override
  public Cluster getNodes(final Handler<AsyncResult<Collection<Node>>> resultHandler) {
    JsonObject message = new JsonObject()
        .putString("action", "list")
        .putString("type", "node");
    vertx.eventBus().sendWithTimeout(address, message, DEFAULT_REPLY_TIMEOUT, new Handler<AsyncResult<Message<JsonObject>>>() {
      @Override
      public void handle(AsyncResult<Message<JsonObject>> result) {
        if (result.failed()) {
          new DefaultFutureResult<Collection<Node>>(new ClusterException(result.cause())).setHandler(resultHandler);
        } else if (result.result().body().getString("status").equals("error")) {
          new DefaultFutureResult<Collection<Node>>(new ClusterException(result.result().body().getString("message"))).setHandler(resultHandler);
        } else if (result.result().body().getString("status").equals("ok")) {
          JsonArray jsonNodes = result.result().body().getArray("result");
          List<Node> nodes = new ArrayList<>();
          for (Object jsonNode : jsonNodes) {
            nodes.add(new DefaultNode((String) jsonNode, vertx, container));
          }
          new DefaultFutureResult<Collection<Node>>(nodes).setHandler(resultHandler);
        }
      }
    });
    return this;
  }

  @Override
  public Cluster selectNode(Object key, final Handler<AsyncResult<Node>> resultHandler) {
    JsonObject message = new JsonObject()
        .putString("action", "select")
        .putString("type", "node")
        .putValue("key", key);
    vertx.eventBus().sendWithTimeout(address, message, DEFAULT_REPLY_TIMEOUT, new Handler<AsyncResult<Message<JsonObject>>>() {
      @Override
      public void handle(AsyncResult<Message<JsonObject>> result) {
        if (result.failed()) {
          new DefaultFutureResult<Node>(new ClusterException(result.cause())).setHandler(resultHandler);
        } else if (result.result().body().getString("status").equals("error")) {
          new DefaultFutureResult<Node>(new ClusterException(result.result().body().getString("message"))).setHandler(resultHandler);
        } else if (result.result().body().getString("status").equals("ok")) {
          new DefaultFutureResult<Node>(new DefaultNode(result.result().body().getString("result"), vertx, container)).setHandler(resultHandler);
        }
      }
    });
    return this;
  }

  @Override
  public Cluster installModule(String moduleName) {
    return installModule(moduleName, null);
  }

  @Override
  public Cluster installModule(final String moduleName, final Handler<AsyncResult<Void>> doneHandler) {
    getNodes(new Handler<AsyncResult<Collection<Node>>>() {
      @Override
      public void handle(AsyncResult<Collection<Node>> result) {
        if (result.failed()) {
          new DefaultFutureResult<Void>(result.cause()).setHandler(doneHandler);
        } else {
          final CountingCompletionHandler<Void> counter = new CountingCompletionHandler<Void>(result.result().size()).setHandler(doneHandler);
          for (Node node : result.result()) {
            node.installModule(moduleName, counter);
          }
        }
      }
    });
    return this;
  }

  @Override
  public Cluster uninstallModule(String moduleName) {
    return uninstallModule(moduleName, null);
  }

  @Override
  public Cluster uninstallModule(final String moduleName, final Handler<AsyncResult<Void>> doneHandler) {
    getNodes(new Handler<AsyncResult<Collection<Node>>>() {
      @Override
      public void handle(AsyncResult<Collection<Node>> result) {
        if (result.failed()) {
          new DefaultFutureResult<Void>(result.cause()).setHandler(doneHandler);
        } else {
          final CountingCompletionHandler<Void> counter = new CountingCompletionHandler<Void>(result.result().size()).setHandler(doneHandler);
          for (Node node : result.result()) {
            node.uninstallModule(moduleName, counter);
          }
        }
      }
    });
    return this;
  }

  @Override
  public Cluster deployModule(String moduleName) {
    return deployModule(moduleName, null, 1, false, null);
  }

  @Override
  public Cluster deployModule(String moduleName, JsonObject config) {
    return deployModule(moduleName, config, 1, false, null);
  }

  @Override
  public Cluster deployModule(String moduleName, int instances) {
    return deployModule(moduleName, null, instances, false, null);
  }

  @Override
  public Cluster deployModule(String moduleName, JsonObject config, int instances) {
    return deployModule(moduleName, config, instances, false, null);
  }

  @Override
  public Cluster deployModule(String moduleName, JsonObject config, int instances, boolean ha) {
    return deployModule(moduleName, config, instances, ha, null);
  }

  @Override
  public Cluster deployModule(String moduleName, Handler<AsyncResult<String>> doneHandler) {
    return deployModule(moduleName, null, 1, false, doneHandler);
  }

  @Override
  public Cluster deployModule(String moduleName, JsonObject config, Handler<AsyncResult<String>> doneHandler) {
    return deployModule(moduleName, config, 1, false, doneHandler);
  }

  @Override
  public Cluster deployModule(String moduleName, int instances, Handler<AsyncResult<String>> doneHandler) {
    return deployModule(moduleName, null, instances, false, doneHandler);
  }

  @Override
  public Cluster deployModule(String moduleName, JsonObject config, int instances, Handler<AsyncResult<String>> doneHandler) {
    return deployModule(moduleName, config, instances, false, doneHandler);
  }

  @Override
  public Cluster deployModule(String moduleName, JsonObject config, int instances, boolean ha, final Handler<AsyncResult<String>> doneHandler) {
    JsonObject message = new JsonObject()
        .putString("action", "deploy")
        .putString("type", "module")
        .putString("module", moduleName)
        .putObject("config", config != null ? config : new JsonObject())
        .putNumber("instances", instances)
        .putBoolean("ha", ha);
    vertx.eventBus().sendWithTimeout(address, message, DEFAULT_REPLY_TIMEOUT, new Handler<AsyncResult<Message<JsonObject>>>() {
      @Override
      public void handle(AsyncResult<Message<JsonObject>> result) {
        if (result.failed()) {
          new DefaultFutureResult<String>(new ClusterException(result.cause())).setHandler(doneHandler);
        } else if (result.result().body().getString("status").equals("error")) {
          new DefaultFutureResult<String>(new ClusterException(result.result().body().getString("message"))).setHandler(doneHandler);
        } else if (result.result().body().getString("status").equals("ok")) {
          new DefaultFutureResult<String>(result.result().body().getString("id")).setHandler(doneHandler);
        }
      }
    });
    return this;
  }

  @Override
  public Cluster deployVerticle(String main) {
    return deployVerticle(main, null, 1, false, null);
  }

  @Override
  public Cluster deployVerticle(String main, JsonObject config) {
    return deployVerticle(main, config, 1, false, null);
  }

  @Override
  public Cluster deployVerticle(String main, int instances) {
    return deployVerticle(main, null, instances, false, null);
  }

  @Override
  public Cluster deployVerticle(String main, JsonObject config, int instances) {
    return deployVerticle(main, config, instances, false, null);
  }

  @Override
  public Cluster deployVerticle(String main, JsonObject config, int instances, boolean ha) {
    return deployVerticle(main, config, instances, ha, null);
  }

  @Override
  public Cluster deployVerticle(String main, Handler<AsyncResult<String>> doneHandler) {
    return deployVerticle(main, null, 1, false, doneHandler);
  }

  @Override
  public Cluster deployVerticle(String main, JsonObject config, Handler<AsyncResult<String>> doneHandler) {
    return deployVerticle(main, config, 1, false, doneHandler);
  }

  @Override
  public Cluster deployVerticle(String main, int instances, Handler<AsyncResult<String>> doneHandler) {
    return deployVerticle(main, null, instances, false, doneHandler);
  }

  @Override
  public Cluster deployVerticle(String main, JsonObject config, int instances, final Handler<AsyncResult<String>> doneHandler) {
    return deployVerticle(main, config, instances, false, doneHandler);
  }

  @Override
  public Cluster deployVerticle(String main, JsonObject config, int instances, boolean ha, final Handler<AsyncResult<String>> doneHandler) {
    JsonObject message = new JsonObject()
        .putString("action", "deploy")
        .putString("type", "verticle")
        .putString("main", main)
        .putObject("config", config != null ? config : new JsonObject())
        .putNumber("instances", instances)
        .putBoolean("ha", ha);
    vertx.eventBus().sendWithTimeout(address, message, DEFAULT_REPLY_TIMEOUT, new Handler<AsyncResult<Message<JsonObject>>>() {
      @Override
      public void handle(AsyncResult<Message<JsonObject>> result) {
        if (result.failed()) {
          new DefaultFutureResult<String>(new ClusterException(result.cause())).setHandler(doneHandler);
        } else if (result.result().body().getString("status").equals("error")) {
          new DefaultFutureResult<String>(new ClusterException(result.result().body().getString("message"))).setHandler(doneHandler);
        } else if (result.result().body().getString("status").equals("ok")) {
          new DefaultFutureResult<String>(result.result().body().getString("id")).setHandler(doneHandler);
        }
      }
    });
    return this;
  }

  @Override
  public Cluster deployWorkerVerticle(String main) {
    return deployWorkerVerticle(main, null, 1, false, false, null);
  }

  @Override
  public Cluster deployWorkerVerticle(String main, JsonObject config) {
    return deployWorkerVerticle(main, config, 1, false, false, null);
  }

  @Override
  public Cluster deployWorkerVerticle(String main, int instances) {
    return deployWorkerVerticle(main, null, instances, false, false, null);
  }

  @Override
  public Cluster deployWorkerVerticle(String main, JsonObject config, int instances, boolean multiThreaded) {
    return deployWorkerVerticle(main, config, instances, multiThreaded, false, null);
  }

  @Override
  public Cluster deployWorkerVerticle(String main, JsonObject config, int instances, boolean multiThreaded, boolean ha) {
    return deployWorkerVerticle(main, config, instances, multiThreaded, ha, null);
  }

  @Override
  public Cluster deployWorkerVerticle(String main, Handler<AsyncResult<String>> doneHandler) {
    return deployWorkerVerticle(main, null, 1, false, false, doneHandler);
  }

  @Override
  public Cluster deployWorkerVerticle(String main, JsonObject config, Handler<AsyncResult<String>> doneHandler) {
    return deployWorkerVerticle(main, config, 1, false, false, doneHandler);
  }

  @Override
  public Cluster deployWorkerVerticle(String main, int instances, Handler<AsyncResult<String>> doneHandler) {
    return deployWorkerVerticle(main, null, instances, false, false, doneHandler);
  }

  @Override
  public Cluster deployWorkerVerticle(String main, JsonObject config, int instances, boolean multiThreaded, Handler<AsyncResult<String>> doneHandler) {
    return deployWorkerVerticle(main, config, instances, multiThreaded, false, doneHandler);
  }

  @Override
  public Cluster deployWorkerVerticle(String main, JsonObject config, int instances, boolean multiThreaded, boolean ha, final Handler<AsyncResult<String>> doneHandler) {
    JsonObject message = new JsonObject()
        .putString("action", "deploy")
        .putString("type", "verticle")
        .putString("main", main)
        .putObject("config", config != null ? config : new JsonObject())
        .putNumber("instances", instances)
        .putBoolean("worker", true)
        .putBoolean("multi-threaded", multiThreaded)
        .putBoolean("ha", ha);
    vertx.eventBus().sendWithTimeout(address, message, DEFAULT_REPLY_TIMEOUT, new Handler<AsyncResult<Message<JsonObject>>>() {
      @Override
      public void handle(AsyncResult<Message<JsonObject>> result) {
        if (result.failed()) {
          new DefaultFutureResult<String>(new ClusterException(result.cause())).setHandler(doneHandler);
        } else if (result.result().body().getString("status").equals("error")) {
          new DefaultFutureResult<String>(new ClusterException(result.result().body().getString("message"))).setHandler(doneHandler);
        } else if (result.result().body().getString("status").equals("ok")) {
          new DefaultFutureResult<String>(result.result().body().getString("id")).setHandler(doneHandler);
        }
      }
    });
    return this;
  }

  @Override
  public Cluster undeployModule(String deploymentID) {
    return undeployModule(deploymentID, null);
  }

  @Override
  public Cluster undeployModule(String deploymentID, final Handler<AsyncResult<Void>> doneHandler) {
    JsonObject message = new JsonObject()
        .putString("action", "undeploy")
        .putString("type", "module")
        .putString("id", deploymentID);
    vertx.eventBus().sendWithTimeout(address, message, DEFAULT_REPLY_TIMEOUT, new Handler<AsyncResult<Message<JsonObject>>>() {
      @Override
      public void handle(AsyncResult<Message<JsonObject>> result) {
        if (result.failed()) {
          new DefaultFutureResult<Void>(new ClusterException(result.cause())).setHandler(doneHandler);
        } else if (result.result().body().getString("status").equals("error")) {
          new DefaultFutureResult<Void>(new ClusterException(result.result().body().getString("message"))).setHandler(doneHandler);
        } else if (result.result().body().getString("status").equals("ok")) {
          new DefaultFutureResult<Void>((Void) null).setHandler(doneHandler);
        }
      }
    });
    return this;
  }

  @Override
  public Cluster undeployVerticle(String deploymentID) {
    return undeployVerticle(deploymentID, null);
  }

  @Override
  public Cluster undeployVerticle(String deploymentID, final Handler<AsyncResult<Void>> doneHandler) {
    JsonObject message = new JsonObject()
        .putString("action", "undeploy")
        .putString("type", "verticle")
        .putString("id", deploymentID);
    vertx.eventBus().sendWithTimeout(address, message, DEFAULT_REPLY_TIMEOUT, new Handler<AsyncResult<Message<JsonObject>>>() {
      @Override
      public void handle(AsyncResult<Message<JsonObject>> result) {
        if (result.failed()) {
          new DefaultFutureResult<Void>(new ClusterException(result.cause())).setHandler(doneHandler);
        } else if (result.result().body().getString("status").equals("error")) {
          new DefaultFutureResult<Void>(new ClusterException(result.result().body().getString("message"))).setHandler(doneHandler);
        } else if (result.result().body().getString("status").equals("ok")) {
          new DefaultFutureResult<Void>((Void) null).setHandler(doneHandler);
        }
      }
    });
    return this;
  }

  @Override
  public Cluster getNetworks(final Handler<AsyncResult<Collection<ActiveNetwork>>> resultHandler) {
    JsonObject message = new JsonObject()
        .putString("action", "list")
        .putString("type", "network");
    vertx.eventBus().sendWithTimeout(address, message, DEFAULT_REPLY_TIMEOUT, new Handler<AsyncResult<Message<JsonObject>>>() {
      @Override
      public void handle(AsyncResult<Message<JsonObject>> result) {
        if (result.failed()) {
          new DefaultFutureResult<Collection<ActiveNetwork>>(new ClusterException(result.cause())).setHandler(resultHandler);
        } else if (result.result().body().getString("status").equals("error")) {
          new DefaultFutureResult<Collection<ActiveNetwork>>(new ClusterException(result.result().body().getString("message"))).setHandler(resultHandler);
        } else {
          final List<ActiveNetwork> networks = new ArrayList<>();
          JsonArray jsonNetworks = result.result().body().getArray("result");
          final CountingCompletionHandler<Void> counter = new CountingCompletionHandler<Void>(jsonNetworks.size());
          counter.setHandler(new Handler<AsyncResult<Void>>() {
            @Override
            public void handle(AsyncResult<Void> result) {
              if (result.failed()) {
                new DefaultFutureResult<Collection<ActiveNetwork>>(result.cause()).setHandler(resultHandler);
              } else {
                new DefaultFutureResult<Collection<ActiveNetwork>>(networks).setHandler(resultHandler);
              }
            }
          });
          for (Object jsonNetwork : jsonNetworks) {
            createActiveNetwork(Contexts.<NetworkContext>deserialize((JsonObject) jsonNetwork), new Handler<AsyncResult<ActiveNetwork>>() {
              @Override
              public void handle(AsyncResult<ActiveNetwork> result) {
                if (result.failed()) {
                  counter.fail(result.cause());
                } else {
                  networks.add(result.result());
                  counter.succeed();
                }
              }
            });
          }
        }
      }
    });
    return this;
  }

  @Override
  public Cluster getNetwork(String name, final Handler<AsyncResult<ActiveNetwork>> resultHandler) {
    JsonObject message = new JsonObject()
        .putString("action", "find")
        .putString("type", "network")
        .putString("network", name);
    vertx.eventBus().sendWithTimeout(address, message, DEFAULT_REPLY_TIMEOUT, new Handler<AsyncResult<Message<JsonObject>>>() {
      @Override
      public void handle(AsyncResult<Message<JsonObject>> result) {
        if (result.failed()) {
          new DefaultFutureResult<ActiveNetwork>(new ClusterException(result.cause())).setHandler(resultHandler);
        } else if (result.result().body().getString("status").equals("error")) {
          new DefaultFutureResult<ActiveNetwork>(new ClusterException(result.result().body().getString("message"))).setHandler(resultHandler);
        } else {
          createActiveNetwork(Contexts.<NetworkContext>deserialize(result.result().body().getObject("result")), resultHandler);
        }
      }
    });
    return this;
  }

  @Override
  public Cluster deployNetwork(String name) {
    return deployNetwork(name, null);
  }

  @Override
  public Cluster deployNetwork(String name, Handler<AsyncResult<ActiveNetwork>> doneHandler) {
    return deployNetwork(new DefaultNetworkConfig(name), doneHandler);
  }

  @Override
  public Cluster deployNetwork(JsonObject network) {
    return deployNetwork(network, null);
  }

  @Override
  public Cluster deployNetwork(JsonObject network, Handler<AsyncResult<ActiveNetwork>> doneHandler) {
    return deployNetwork(Configs.createNetwork(network), doneHandler);
  }

  @Override
  public Cluster deployNetwork(NetworkConfig network) {
    return deployNetwork(network, null);
  }

  @Override
  public Cluster deployNetwork(final NetworkConfig network, final Handler<AsyncResult<ActiveNetwork>> doneHandler) {
    // When deploying a network, we first need to select the node to which
    // the network belongs. Each network will have a randomly selected master.
    // In order for the network to be able to distribute components across the
    // cluster it needs to have all the installables locally installed.
    selectNode(network.getName(), new Handler<AsyncResult<Node>>() {
      @Override
      public void handle(AsyncResult<Node> result) {
        if (result.failed()) {
          new DefaultFutureResult<ActiveNetwork>(result.cause()).setHandler(doneHandler);
        } else {
          // Once we've selected a node we need to install all the modules to the node.
          final Node node = result.result();
          List<ModuleConfig> modules = new ArrayList<>();
          for (ComponentConfig<?> component : network.getComponents()) {
            if (component.getType().equals(ComponentConfig.Type.MODULE)) {
              modules.add((ModuleConfig) component);
            }
          }

          final CountingCompletionHandler<Void> counter = new CountingCompletionHandler<Void>(modules.size());
          counter.setHandler(new Handler<AsyncResult<Void>>() {
            @Override
            public void handle(AsyncResult<Void> result) {
              if (result.failed()) {
                new DefaultFutureResult<ActiveNetwork>(result.cause()).setHandler(doneHandler);
              } else {
                // Once all the modules have been installed we can deploy the network.
                JsonObject message = new JsonObject()
                    .putString("action", "deploy")
                    .putString("type", "network")
                    .putObject("network", SerializerFactory.getSerializer(Config.class).serializeToObject(network));
                vertx.eventBus().sendWithTimeout(address, message, DEFAULT_REPLY_TIMEOUT, new Handler<AsyncResult<Message<JsonObject>>>() {
                  @Override
                  public void handle(AsyncResult<Message<JsonObject>> result) {
                    if (result.failed()) {
                      new DefaultFutureResult<ActiveNetwork>(new ClusterException(result.cause())).setHandler(doneHandler);
                    } else if (result.result().body().getString("status").equals("error")) {
                      new DefaultFutureResult<ActiveNetwork>(new ClusterException(result.result().body().getString("message"))).setHandler(doneHandler);
                    } else {
                      createActiveNetwork(Contexts.<NetworkContext>deserialize(result.result().body().getObject("context")), doneHandler);
                    }
                  }
                });
              }
            }
          });

          for (ModuleConfig module : modules) {
            node.installModule(module.getModule(), counter);
          }
        }
      }
    });
    return this;
  }

  @Override
  public Cluster undeployNetwork(String name) {
    return undeployNetwork(name, null);
  }

  @Override
  public Cluster undeployNetwork(String name, final Handler<AsyncResult<Void>> doneHandler) {
    JsonObject message = new JsonObject()
        .putString("action", "undeploy")
        .putString("type", "network")
        .putString("network", name);
    vertx.eventBus().sendWithTimeout(address, message, DEFAULT_REPLY_TIMEOUT, new Handler<AsyncResult<Message<JsonObject>>>() {
      @Override
      public void handle(AsyncResult<Message<JsonObject>> result) {
        if (result.failed()) {
          new DefaultFutureResult<Void>(new ClusterException(result.cause())).setHandler(doneHandler);
        } else if (result.result().body().getString("status").equals("error")) {
          new DefaultFutureResult<Void>(new ClusterException(result.result().body().getString("message"))).setHandler(doneHandler);
        } else {
          new DefaultFutureResult<Void>((Void) null).setHandler(doneHandler);
        }
      }
    });
    return this;
  }

  @Override
  public Cluster undeployNetwork(JsonObject network) {
    return undeployNetwork(network, null);
  }

  @Override
  public Cluster undeployNetwork(JsonObject network, Handler<AsyncResult<Void>> doneHandler) {
    return undeployNetwork(Configs.createNetwork(network), doneHandler);
  }

  @Override
  public Cluster undeployNetwork(NetworkConfig network) {
    return undeployNetwork(network, null);
  }

  @Override
  public Cluster undeployNetwork(NetworkConfig network, final Handler<AsyncResult<Void>> doneHandler) {
    JsonObject message = new JsonObject()
        .putString("action", "undeploy")
        .putString("type", "network")
        .putObject("network", SerializerFactory.getSerializer(Config.class).serializeToObject(network));
    vertx.eventBus().sendWithTimeout(address, message, DEFAULT_REPLY_TIMEOUT, new Handler<AsyncResult<Message<JsonObject>>>() {
      @Override
      public void handle(AsyncResult<Message<JsonObject>> result) {
        if (result.failed()) {
          new DefaultFutureResult<Void>(new ClusterException(result.cause())).setHandler(doneHandler);
        } else if (result.result().body().getString("status").equals("error")) {
          new DefaultFutureResult<Void>(new ClusterException(result.result().body().getString("message"))).setHandler(doneHandler);
        } else {
          new DefaultFutureResult<Void>((Void) null).setHandler(doneHandler);
        }
      }
    });
    return this;
  }

  /**
   * Creates and returns an active network.
   */
  private void createActiveNetwork(final NetworkContext context, final Handler<AsyncResult<ActiveNetwork>> doneHandler) {
    final DefaultActiveNetwork active = new DefaultActiveNetwork(context.config(), DefaultCluster.this);
    vertx.eventBus().registerHandler(String.format("%s.%s.change", context.name(), context.name()), new Handler<Message<JsonObject>>() {
      @Override
      public void handle(Message<JsonObject> message) {
        String event = message.body().getString("type");
        if (event.equals("change") && message.body().getString("value") != null) {
          active.update(Contexts.<NetworkContext>deserialize(new JsonObject(message.body().getString("value"))));
        }
      }
    }, new Handler<AsyncResult<Void>>() {
      @Override
      public void handle(AsyncResult<Void> result) {
        if (result.failed()) {
          new DefaultFutureResult<ActiveNetwork>(new ClusterException(result.cause())).setHandler(doneHandler);
        } else {
          new DefaultFutureResult<ActiveNetwork>(active).setHandler(doneHandler);
        }
      }
    });
  }

  @Override
  public <K, V> AsyncMap<K, V> getMap(String name) {
    return new DefaultAsyncMap<K, V>(address, name, vertx);
  }

  @Override
  public <K, V> AsyncMultiMap<K, V> getMultiMap(String name) {
    return new DefaultAsyncMultiMap<K, V>(address, name, vertx);
  }

  @Override
  public <T> AsyncSet<T> getSet(String name) {
    return new DefaultAsyncSet<T>(address, name, vertx);
  }

  @Override
  public <T> AsyncList<T> getList(String name) {
    return new DefaultAsyncList<T>(address, name, vertx);
  }

  @Override
  public <T> AsyncQueue<T> getQueue(String name) {
    return new DefaultAsyncQueue<T>(address, name, vertx);
  }

  @Override
  public AsyncCounter getCounter(String name) {
    return new DefaultAsyncCounter(address, name, vertx);
  }

  @Override
  public String toString() {
    return String.format("Cluster[%s]", address);
  }

  @Override
  public boolean equals(Object object) {
    return object instanceof Cluster && ((Cluster) object).address().equals(address);
  }

}
TOP

Related Classes of net.kuujo.vertigo.cluster.impl.DefaultCluster

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.