示例#1
0
 DefaultAsyncFile(
     final VertxInternal vertx,
     final String path,
     String perms,
     final boolean read,
     final boolean write,
     final boolean createNew,
     final boolean flush,
     final Context context)
     throws Exception {
   if (!read && !write) {
     throw new FileSystemException("Cannot open file for neither reading nor writing");
   }
   this.vertx = vertx;
   Path file = Paths.get(path);
   HashSet<OpenOption> options = new HashSet<>();
   if (read) options.add(StandardOpenOption.READ);
   if (write) options.add(StandardOpenOption.WRITE);
   if (createNew) options.add(StandardOpenOption.CREATE);
   if (flush) options.add(StandardOpenOption.DSYNC);
   if (perms != null) {
     FileAttribute<?> attrs =
         PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString(perms));
     ch = AsynchronousFileChannel.open(file, options, vertx.getBackgroundPool(), attrs);
   } else {
     ch = AsynchronousFileChannel.open(file, options, vertx.getBackgroundPool());
   }
   this.context = context;
 }
示例#2
0
 public DefaultNetServer(VertxInternal vertx) {
   this.vertx = vertx;
   ctx = vertx.getOrAssignContext();
   if (vertx.isWorker()) {
     throw new IllegalStateException("Cannot be used in a worker application");
   }
   ctx.addCloseHook(
       new Runnable() {
         public void run() {
           close();
         }
       });
   tcpHelper.setReuseAddress(true);
 }
示例#3
0
  private void actualClose(final Context closeContext, final Handler<Void> done) {
    if (id != null) {
      vertx.sharedNetServers().remove(id);
    }

    for (DefaultNetSocket sock : socketMap.values()) {
      sock.internalClose();
    }

    // We need to reset it since sock.internalClose() above can call into the close handlers of
    // sockets on the same thread
    // which can cause context id for the thread to change!

    Context.setContext(closeContext);

    ChannelGroupFuture fut = serverChannelGroup.close();
    if (done != null) {
      fut.addListener(
          new ChannelGroupFutureListener() {
            public void operationComplete(ChannelGroupFuture channelGroupFuture) throws Exception {
              executeCloseDone(closeContext, done);
            }
          });
    }
  }
示例#4
0
  public void close(final Handler<Void> done) {
    if (!listening) {
      if (done != null) {
        executeCloseDone(ctx, done);
      }
      return;
    }
    listening = false;
    synchronized (vertx.sharedNetServers()) {
      if (actualServer != null) {
        actualServer.handlerManager.removeHandler(connectHandler, ctx);

        if (actualServer.handlerManager.hasHandlers()) {
          // The actual server still has handlers so we don't actually close it
          if (done != null) {
            executeCloseDone(ctx, done);
          }
        } else {
          // No Handlers left so close the actual server
          // The done handler needs to be executed on the context that calls close, NOT the context
          // of the actual server
          actualServer.actualClose(ctx, done);
        }
      }
    }
  }
示例#5
0
 void handleException(Exception e) {
   if (exceptionHandler != null) {
     exceptionHandler.handle(e);
   } else {
     vertx.reportException(e);
   }
 }
示例#6
0
  public DefaultSockJSServer(final VertxInternal vertx, final HttpServer httpServer) {
    this.vertx = vertx;
    this.sessions = vertx.sharedData().getMap("_vertx.sockjssessions");
    // Any previous request and websocket handlers will become default handlers
    // if nothing else matches
    rm.noMatch(httpServer.requestHandler());
    wsMatcher.noMatch(
        new Handler<WebSocketMatcher.Match>() {
          Handler<ServerWebSocket> wsHandler = httpServer.websocketHandler();

          public void handle(WebSocketMatcher.Match match) {
            if (wsHandler != null) {
              wsHandler.handle(match.ws);
            }
          }
        });
    httpServer.requestHandler(
        new Handler<HttpServerRequest>() {
          @Override
          public void handle(HttpServerRequest req) {
            if (log.isTraceEnabled()) {
              log.trace("Got request in sockjs server: " + req.uri);
            }
            rm.handle(req);
          }
        });
    httpServer.websocketHandler(wsMatcher);
  }
示例#7
0
 private VerticleHolder getVerticleHolder() {
   Context context = vertx.getContext();
   if (context != null) {
     VerticleHolder holder = (VerticleHolder) context.getDeploymentHandle();
     return holder;
   } else {
     return null;
   }
 }
示例#8
0
 // Must be synchronized since called directly from different thread
 private void addVerticle(Deployment deployment, Verticle verticle, VerticleFactory factory) {
   String loggerName =
       "org.vertx.deployments." + deployment.name + "-" + deployment.verticles.size();
   Logger logger = LoggerFactory.getLogger(loggerName);
   Context context = vertx.getContext();
   VerticleHolder holder =
       new VerticleHolder(
           deployment, context, verticle, loggerName, logger, deployment.config, factory);
   deployment.verticles.add(holder);
   context.setDeploymentHandle(holder);
 }
示例#9
0
 public synchronized void uninstallModule(String moduleName) {
   log.info("Uninstalling module " + moduleName + " from directory " + modRoot);
   File modDir = new File(modRoot, moduleName);
   if (!modDir.exists()) {
     log.error("Cannot find module to uninstall");
   } else {
     try {
       vertx.fileSystem().deleteSync(modDir.getAbsolutePath(), true);
       log.info("Module " + moduleName + " successfully uninstalled");
     } catch (Exception e) {
       log.error("Failed to delete directory: " + e.getMessage());
     }
   }
 }
示例#10
0
  private boolean unzipModule(
      final ModuleIdentifier modID, final ModuleZipInfo zipInfo, boolean deleteZip) {
    // We synchronize to prevent a race whereby it tries to unzip the same module at the
    // same time (e.g. deployModule for the same module name has been called in parallel)
    String modName = modID.toString();
    synchronized (modName.intern()) {
      if (!checkModDirs()) {
        return false;
      }

      File fdest = new File(modRoot, modName);
      File sdest = new File(systemModRoot, modName);
      if (fdest.exists() || sdest.exists()) {
        // This can happen if the same module is requested to be installed
        // at around the same time
        // It's ok if this happens
        log.warn("Module " + modID + " is already installed");
        return true;
      }

      // Unzip into temp dir first
      File tdest = unzipIntoTmpDir(zipInfo, deleteZip);
      if (tdest == null) {
        return false;
      }

      // Check if it's a system module
      JsonObject conf = loadModuleConfig(modID, tdest);
      ModuleFields fields = new ModuleFields(conf);

      boolean system = fields.isSystem();

      // Now copy it to the proper directory
      String moveFrom = tdest.getAbsolutePath();
      try {
        vertx
            .fileSystem()
            .moveSync(moveFrom, system ? sdest.getAbsolutePath() : fdest.getAbsolutePath());
      } catch (Exception e) {
        log.error("Failed to move module", e);
        return false;
      }

      log.info("Module " + modID + " successfully installed");
      return true;
    }
  }
示例#11
0
  public DefaultSockJSServer(final VertxInternal vertx, final HttpServer httpServer) {
    this.vertx = vertx;
    this.sessions = vertx.sharedData().getMap("_vertx.sockjssessions");
    // Any previous request and websocket handlers will become default handlers
    // if nothing else matches
    rm.noMatch(httpServer.requestHandler());
    wsMatcher.noMatch(
        new Handler<WebSocketMatcher.Match>() {
          Handler<ServerWebSocket> wsHandler = httpServer.websocketHandler();

          public void handle(WebSocketMatcher.Match match) {
            wsHandler.handle(match.ws);
          }
        });

    httpServer.requestHandler(rm);
    httpServer.websocketHandler(wsMatcher);
  }
示例#12
0
 private Handler<String> wrapDoneHandler(final Handler<String> doneHandler) {
   if (doneHandler == null) {
     return null;
   }
   final Context context = vertx.getContext();
   return new Handler<String>() {
     @Override
     public void handle(final String deploymentID) {
       if (context == null) {
         doneHandler.handle(deploymentID);
       } else {
         context.execute(
             new Runnable() {
               public void run() {
                 doneHandler.handle(deploymentID);
               }
             });
       }
     }
   };
 }
示例#13
0
 @Override
 protected void channelRead(
     final C connection,
     final DefaultContext context,
     final ChannelHandlerContext chctx,
     final Object msg)
     throws Exception {
   if (connection != null) {
     // we are reading from the channel
     Channel ch = chctx.channel();
     // We need to do this since it's possible the server is being used from a worker context
     if (context.isOnCorrectWorker(ch.eventLoop())) {
       try {
         vertx.setContext(context);
         doMessageReceived(connection, chctx, msg);
       } catch (Throwable t) {
         context.reportException(t);
       }
     } else {
       context.execute(
           new Runnable() {
             public void run() {
               try {
                 doMessageReceived(connection, chctx, msg);
               } catch (Throwable t) {
                 context.reportException(t);
               }
             }
           });
     }
   } else {
     try {
       doMessageReceived(connection, chctx, msg);
     } catch (Throwable t) {
       chctx.pipeline().fireExceptionCaught(t);
     }
   }
 }
示例#14
0
  public NetServer listen(int port, String host) {
    if (connectHandler == null) {
      throw new IllegalStateException("Set connect handler first");
    }
    if (listening) {
      throw new IllegalStateException("Listen already called");
    }
    listening = true;

    synchronized (vertx.sharedNetServers()) {
      id = new ServerID(port, host);
      DefaultNetServer shared = vertx.sharedNetServers().get(id);
      if (shared == null) {
        serverChannelGroup = new DefaultChannelGroup("vertx-acceptor-channels");

        ChannelFactory factory =
            new NioServerSocketChannelFactory(vertx.getAcceptorPool(), availableWorkers);
        ServerBootstrap bootstrap = new ServerBootstrap(factory);

        tcpHelper.checkSSL();

        bootstrap.setPipelineFactory(
            new ChannelPipelineFactory() {
              public ChannelPipeline getPipeline() {
                ChannelPipeline pipeline = Channels.pipeline();
                if (tcpHelper.isSSL()) {
                  SSLEngine engine = tcpHelper.getSSLContext().createSSLEngine();
                  engine.setUseClientMode(false);
                  switch (tcpHelper.getClientAuth()) {
                    case REQUEST:
                      {
                        engine.setWantClientAuth(true);
                        break;
                      }
                    case REQUIRED:
                      {
                        engine.setNeedClientAuth(true);
                        break;
                      }
                    case NONE:
                      {
                        engine.setNeedClientAuth(false);
                        break;
                      }
                  }
                  pipeline.addLast("ssl", new SslHandler(engine));
                }
                pipeline.addLast(
                    "chunkedWriter",
                    new ChunkedWriteHandler()); // For large file / sendfile support
                pipeline.addLast("handler", new ServerHandler());
                return pipeline;
              }
            });

        bootstrap.setOptions(tcpHelper.generateConnectionOptions(true));

        try {
          // TODO - currently bootstrap.bind is blocking - need to make it non blocking by not using
          // bootstrap directly
          Channel serverChannel =
              bootstrap.bind(new InetSocketAddress(InetAddress.getByName(host), port));
          serverChannelGroup.add(serverChannel);
          log.trace("Net server listening on " + host + ":" + port);
        } catch (UnknownHostException e) {
          log.error("Failed to bind", e);
        }
        vertx.sharedNetServers().put(id, this);
        actualServer = this;
      } else {
        // Server already exists with that host/port - we will use that
        checkConfigs(actualServer, this);
        actualServer = shared;
      }
      actualServer.handlerManager.addHandler(connectHandler, ctx);
    }
    return this;
  }
示例#15
0
  private void doDeploy(
      final String depName,
      boolean autoRedeploy,
      boolean worker,
      boolean multiThreaded,
      String theMain,
      final ModuleIdentifier modID,
      final JsonObject config,
      final URL[] urls,
      int instances,
      final File modDir,
      final ModuleReference mr,
      final Handler<String> doneHandler) {
    checkWorkerContext();

    final String deploymentName = depName != null ? depName : genDepName();

    log.debug(
        "Deploying name : " + deploymentName + " main: " + theMain + " instances: " + instances);

    // How we determine which language implementation to use:
    // 1. Look for a prefix on the main, e.g. 'groovy:org.foo.myproject.MyGroovyMain' would force
    // the groovy
    //    language impl to be used
    // 2. If there is no prefix, then look at the extension, if any. If there is an extension
    // mapping for that
    //    extension, use that.
    // 3. No prefix and no extension mapping - use the default runtime

    LanguageImplInfo langImplInfo = null;

    final String main;
    // Look for a prefix
    int prefixMarker = theMain.indexOf(COLON);
    if (prefixMarker != -1) {
      String prefix = theMain.substring(0, prefixMarker);
      langImplInfo = languageImpls.get(prefix);
      if (langImplInfo == null) {
        throw new IllegalStateException("No language implementation known for prefix " + prefix);
      }
      main = theMain.substring(prefixMarker + 1);
    } else {
      main = theMain;
    }
    if (langImplInfo == null) {
      // No prefix - now look at the extension
      int extensionMarker = main.lastIndexOf('.');
      if (extensionMarker != -1) {
        String extension = main.substring(extensionMarker + 1);
        String langImplName = extensionMappings.get(extension);
        if (langImplName != null) {
          langImplInfo = languageImpls.get(langImplName);
          if (langImplInfo == null) {
            throw new IllegalStateException(
                "Extension mapping for "
                    + extension
                    + " specified as "
                    + langImplName
                    + ", but no language implementation known for that name");
          }
        }
      }
    }
    if (langImplInfo == null) {
      // Use the default
      langImplInfo = languageImpls.get(defaultLanguageImplName);
      if (langImplInfo == null) {
        throw new IllegalStateException(
            "Default language implementation is "
                + defaultLanguageImplName
                + " but no language implementation known for that name");
      }
    }

    // Include the language impl module as a parent of the classloader
    if (langImplInfo.moduleName != null) {
      if (!loadIncludedModules(modDir, mr, langImplInfo.moduleName)) {
        log.error("Failed to load module: " + langImplInfo.moduleName);
        doneHandler.handle(null);
        return;
      }
    }

    final VerticleFactory verticleFactory;

    final Container container = new DefaultContainer(this);

    try {
      // TODO not one verticle factory per module ref, but one per language per module ref
      verticleFactory = mr.getVerticleFactory(langImplInfo.factoryName, vertx, container);
    } catch (Exception e) {
      log.error("Failed to instantiate verticle factory", e);
      doneHandler.handle(null);
      return;
    }

    final int instCount = instances;

    class AggHandler {
      AtomicInteger count = new AtomicInteger(0);
      boolean failed;

      void done(boolean res) {
        if (!res) {
          failed = true;
        }
        if (count.incrementAndGet() == instCount) {
          String deploymentID = failed ? null : deploymentName;
          callDoneHandler(doneHandler, deploymentID);
        }
      }
    }

    final AggHandler aggHandler = new AggHandler();

    String parentDeploymentName = getDeploymentName();
    final Deployment deployment =
        new Deployment(
            deploymentName,
            main,
            modID,
            instances,
            config == null ? new JsonObject() : config.copy(),
            urls,
            modDir,
            parentDeploymentName,
            mr,
            autoRedeploy);
    mr.incRef();
    deployments.put(deploymentName, deployment);

    if (parentDeploymentName != null) {
      Deployment parentDeployment = deployments.get(parentDeploymentName);
      parentDeployment.childDeployments.add(deploymentName);
    }

    ClassLoader oldTCCL = Thread.currentThread().getContextClassLoader();
    Thread.currentThread().setContextClassLoader(mr.mcl);
    try {

      for (int i = 0; i < instances; i++) {

        // Launch the verticle instance

        Runnable runner =
            new Runnable() {
              public void run() {

                Verticle verticle = null;
                boolean error = true;

                try {
                  verticle = verticleFactory.createVerticle(main);
                  error = false;
                } catch (ClassNotFoundException e) {
                  log.error(
                      "Cannot find verticle "
                          + main
                          + " in "
                          + verticleFactory.getClass().getName(),
                      e);
                } catch (Throwable t) {
                  log.error(
                      "Failed to create verticle "
                          + main
                          + " in "
                          + verticleFactory.getClass().getName(),
                      t);
                }

                if (error) {
                  doUndeploy(
                      deploymentName,
                      new SimpleHandler() {
                        public void handle() {
                          aggHandler.done(false);
                        }
                      });
                  return;
                }
                verticle.setContainer(container);
                verticle.setVertx(vertx);

                try {
                  addVerticle(deployment, verticle, verticleFactory);
                  if (modDir != null) {
                    setPathAdjustment(modDir);
                  }
                  VoidResult vr = new VoidResult();
                  verticle.start(vr);
                  vr.setHandler(
                      new AsyncResultHandler<Void>() {
                        @Override
                        public void handle(AsyncResult<Void> ar) {
                          if (ar.succeeded()) {
                            aggHandler.done(true);
                          } else {
                            log.error(
                                "Failed to deploy verticle "
                                    + main
                                    + " in "
                                    + verticleFactory.getClass().getName(),
                                ar.exception);
                            aggHandler.done(false);
                          }
                        }
                      });
                } catch (Throwable t) {
                  t.printStackTrace();
                  vertx.reportException(t);
                  doUndeploy(
                      deploymentName,
                      new SimpleHandler() {
                        public void handle() {
                          aggHandler.done(false);
                        }
                      });
                }
              }
            };

        if (worker) {
          vertx.startInBackground(runner, multiThreaded);
        } else {
          vertx.startOnEventLoop(runner);
        }
      }
    } finally {
      Thread.currentThread().setContextClassLoader(oldTCCL);
    }
  }
示例#16
0
 public DefaultHttpClient(VertxInternal vertx) {
   this.vertx = vertx;
   actualCtx = vertx.getOrCreateContext();
   actualCtx.addCloseHook(closeHook);
 }
示例#17
0
 protected void handleHandlerException(Throwable t) {
   vertx.reportException(t);
 }
示例#18
0
 // We calculate a path adjustment that can be used by the fileSystem object
 // so that the *effective* working directory can be the module directory
 // this allows moduleRefs to read and write the file system as if they were
 // in the module dir, even though the actual working directory will be
 // wherever vertx run or vertx start was called from
 private void setPathAdjustment(File modDir) {
   Path cwd = Paths.get(".").toAbsolutePath().getParent();
   Path pmodDir = Paths.get(modDir.getAbsolutePath());
   Path relative = cwd.relativize(pmodDir);
   vertx.getContext().setPathAdjustment(relative);
 }