VinciFrame serveon()

in jVinci/src/main/java/org/apache/vinci/transport/vns/service/VNS.java [807:935]


  VinciFrame serveon(VinciFrame in) {
    logRequest(VNSConstants.SERVEON_COMMAND, in.fgetString("vinci:REMOTEIP"), null);

    Service S = null, srv = null;
    VinciFrame out = new VinciFrame();

    String name = in.fgetString("SERVICE");
    if (strip(name) == null)
      return new ErrorFrame("Invalid service name specified : " + name);
    String host = in.fgetString("HOST");

    if (strip(host) == null) {
      Debug.p("Getting host from socket peer info");
      host = in.fgetString("vinci:REMOTEHOST");
      if (host == null)
        host = in.fgetString("vinci:REMOTEIP");
      if (host == null)
        return new ErrorFrame("Host could not be parsed - specify HOST");
      Debug.p("Peer host is : " + host);
    }

    String level = in.fgetString("LEVEL");

    // Default as specified in SPEC.txt
    if (strip(level) == null || level.trim().toLowerCase().equals("none"))
      level = "0";

    if (level.equals("all")) {
      out.fadd("vinci:ERROR", "Specific level must be given or none at all");
      return out;
    }

    String instance = in.fgetString("INSTANCE");
    try {
      instance = "" + Integer.parseInt(instance);
    } catch (Exception e) {
      instance = null;
    }

    if (instance == null)
      instance = "0";

    Debug.p("Host = " + host);
    String realhost = in.fgetString("IP");
    try {
      if (realhost == null)
        realhost = InetAddress.getByName(host).getHostAddress();
    } catch (Exception e) {
      out.fadd("vinci:ERROR", "Could not resolve IP due to Exception " + e);
      return out;
    }

    Debug.p("search: realhost = " + realhost + " - instance = " + instance);

    synchronized (SR) {
      level = "" + SR.getLevel(name, level);
    }

    Debug.p("Level = " + level);

    // Update the cache
    updateCache(name + "[" + level + "]");

    Object[] services;
    synchronized (SR) {
      services = SR.getServices(name, level);
    }

    if (services != null) {
      for (int i = 0; i < services.length; i++) {
        S = (Service) services[i];
        Debug.p("current: realhost = " + S.realhost + " - instance = " + S.instance);
        if (S.realhost.equals(realhost) && instance.equals("" + S.instance)
                && S.level.equals(level)) {
          srv = S;
          break;
        }
      }
    }

    if (srv == null) {
      Debug.p("Creating now");
      Hashtable H = new Hashtable();
      H.put("NAME", name);
      H.put("HOST", host);
      H.put("LEVEL", level);
      H.put("INSTANCE", instance);
      H.put("IP", realhost);
      srv = new Service(H);
      boolean ok = false;
      synchronized (SR) {
        Debug.p("Adding service : " + H.get("NAME") + ", lvl=" + H.get("LEVEL") + ",instance="
                + H.get("INSTANCE") + ",ip=" + H.get("IP"));
        ok = SR.addService(srv);
      }
      if (!ok) {
        out.fadd("vinci:ERROR", "COuld not find or add service " + name);
        return out;
      }
    } else {
      if (srv.minport != srv.maxport) { // if it isn't running on a fixed port
        final String s_host = srv.host;
        final int s_port = srv.port;
        new Thread(new Runnable() {
          @Override
          public void run() {
            Debug.p("Trying to shutdown old service ...");
            VinciFrame shutdown = new VinciFrame();
            shutdown.fadd("vinci:SHUTDOWN",
                    "Identical service started on this host. Use the INSTANCE tag to run multiple instances of the same service on a single host.");
            try {
              VinciFrame f = BaseClient.rpc(shutdown, s_host, s_port, 10000);
              Debug.p("Shutdown response received: " + f.toXML());
            } catch (Exception e) {
              Debug.p("Old service already closed: " + e);
            }
          }
        }).start();
      }
    }

    srv.updatePort();
    out.fadd("HOST", srv.host);
    out.fadd("PORT", srv.port);
    out.fadd("LEVEL", srv.level);
    out.fadd("INSTANCE", srv.instance);
    out.fadd("IP", srv.realhost);
    return out;
  }