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; }
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); }
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); } }); } }
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); } } } }
void handleException(Exception e) { if (exceptionHandler != null) { exceptionHandler.handle(e); } else { vertx.reportException(e); } }
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); }
private VerticleHolder getVerticleHolder() { Context context = vertx.getContext(); if (context != null) { VerticleHolder holder = (VerticleHolder) context.getDeploymentHandle(); return holder; } else { return null; } }
// 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); }
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()); } } }
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; } }
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); }
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); } }); } } }; }
@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); } } }
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; }
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); } }
public DefaultHttpClient(VertxInternal vertx) { this.vertx = vertx; actualCtx = vertx.getOrCreateContext(); actualCtx.addCloseHook(closeHook); }
protected void handleHandlerException(Throwable t) { vertx.reportException(t); }
// 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); }