@Override public Object resolve(RoutingContext context, RequestBody annotation, Class<?> resultClass) { String body = context.getBodyAsString(); if (resultClass.equals(String.class)) { return body; } String contentType = ContentTypeProcessor.getContentType(context); if (contentType == null) { log.error("No suitable Content-Type found, request body can't be read"); return null; } if (contentType.equals("application/json") && resultClass.equals(JsonObject.class)) { return new JsonObject(body); } PayloadMarshaller marshaller = marshallers.get(contentType); if (marshaller == null) { log.error( "No marshaller found for Content-Type : " + contentType + ", request body can't be read"); return null; } try { return marshaller.unmarshallPayload(body, resultClass); } catch (MarshallingException me) { context.fail(me); return null; } }
// Check if there is a quorum for our group private void checkQuorum() { if (quorumSize == 0) { this.attainedQuorum = true; } else { List<String> nodes = clusterManager.getNodes(); int count = 0; for (String node : nodes) { String json = clusterMap.get(node); if (json != null) { JsonObject clusterInfo = new JsonObject(json); String group = clusterInfo.getString("group"); if (group.equals(this.group)) { count++; } } } boolean attained = count >= quorumSize; if (!attainedQuorum && attained) { // A quorum has been attained so we can deploy any currently undeployed HA deploymentIDs log.info( "A quorum has been obtained. Any deploymentIDs waiting on a quorum will now be deployed"); this.attainedQuorum = true; } else if (attainedQuorum && !attained) { // We had a quorum but we lost it - we must undeploy any HA deploymentIDs log.info( "There is no longer a quorum. Any HA deploymentIDs will be undeployed until a quorum is re-attained"); this.attainedQuorum = false; } } }
// Handle failover private void checkFailover(String failedNodeID, JsonObject theHAInfo) { try { JsonArray deployments = theHAInfo.getJsonArray("verticles"); String group = theHAInfo.getString("group"); String chosen = chooseHashedNode(group, failedNodeID.hashCode()); if (chosen != null && chosen.equals(this.nodeID)) { if (deployments != null && deployments.size() != 0) { log.info( "node" + nodeID + " says: Node " + failedNodeID + " has failed. This node will deploy " + deployments.size() + " deploymentIDs from that node."); for (Object obj : deployments) { JsonObject app = (JsonObject) obj; processFailover(app); } } // Failover is complete! We can now remove the failed node from the cluster map clusterMap.remove(failedNodeID); callFailoverCompleteHandler(failedNodeID, theHAInfo, true); } } catch (Throwable t) { log.error("Failed to handle failover", t); callFailoverCompleteHandler(failedNodeID, theHAInfo, false); } }
@Override public void start(final Future<Void> startFuture) throws Exception { LOGGER.info("starting {0}..", identifier()); // start the HELLO slacker protocol final JsonObject helloMessage = new JsonObject().put("i", identifier()).put("d", description()).put("v", version()); vertx .eventBus() .send( "reg.slacker-server", helloMessage, result -> { if (result.succeeded() && JsonObject.class.isInstance(result.result().body())) { final JsonObject response = (JsonObject) result.result().body(); if (response.containsKey("a")) { // everything went smoothly - register the listener and complete the startup registerListener(response.getString("a")); LOGGER.info("successfully registered {0} executor", identifier()); startFuture.complete(); } else { failStart(startFuture, "no address to bind was received"); } } else { // something unexpected happened failStart( startFuture, Optional.ofNullable(result.cause()) .map(Throwable::getMessage) .orElse("invalid response")); } }); }
@Override protected BlockingAction<Void> chownInternal( String path, String user, String group, Handler<AsyncResult<Void>> handler) { if (group != null && log.isDebugEnabled()) { log.debug("You are running on Windows and POSIX style file ownership is not supported"); } return super.chownInternal(path, user, group, handler); }
@Override public void start() throws Exception { address = MQTTSession.ADDRESS; JsonObject conf = config(); localBridgePort = conf.getInteger("local_bridge_port", 7007); idleTimeout = conf.getInteger("socket_idle_timeout", 120); ssl_cert_key = conf.getString("ssl_cert_key"); ssl_cert = conf.getString("ssl_cert"); ssl_trust = conf.getString("ssl_trust"); // [WebSocket -> BUS] listen WebSocket publish to BUS HttpServerOptions opt = new HttpServerOptions() .setTcpKeepAlive(true) .setIdleTimeout(idleTimeout) .setPort(localBridgePort); if (ssl_cert_key != null && ssl_cert != null && ssl_trust != null) { opt.setSsl(true) .setClientAuth(ClientAuth.REQUIRED) .setPemKeyCertOptions( new PemKeyCertOptions().setKeyPath(ssl_cert_key).setCertPath(ssl_cert)) .setPemTrustOptions(new PemTrustOptions().addCertPath(ssl_trust)); } netServer = vertx.createHttpServer(opt); netServer .websocketHandler( sock -> { final EventBusWebsocketBridge ebnb = new EventBusWebsocketBridge(sock, vertx.eventBus(), address); sock.closeHandler( aVoid -> { logger.info( "Bridge Server - closed connection from client ip: " + sock.remoteAddress()); ebnb.stop(); }); sock.exceptionHandler( throwable -> { logger.error("Bridge Server - Exception: " + throwable.getMessage(), throwable); ebnb.stop(); }); logger.info("Bridge Server - new connection from client ip: " + sock.remoteAddress()); RecordParser parser = ebnb.initialHandhakeProtocolParser(); sock.handler(parser::handle); }) .listen(); }
void start() { connection.setErrorHandler( th -> { log.debug("QUIT failed, ignoring exception", th); resultHandler.handle(null); }); connection.write( "QUIT", message -> { log.debug("QUIT result: " + message); if (!StatusCode.isStatusOk(message)) { log.warn("quit failed: " + message); } resultHandler.handle(null); }); }
private synchronized void checkQuorumWhenAdded(final String nodeID, final long start) { if (clusterMap.containsKey(nodeID)) { checkQuorum(); } else { vertx.setTimer( 200, tid -> { // This can block on a monitor so it needs to run as a worker vertx.executeBlockingInternal( () -> { if (System.currentTimeMillis() - start > 10000) { log.warn("Timed out waiting for group information to appear"); } else if (!stopped) { ContextImpl context = vertx.getContext(); try { // Remove any context we have here (from the timer) otherwise will screw // things up when verticles are deployed ContextImpl.setContext(null); checkQuorumWhenAdded(nodeID, start); } finally { ContextImpl.setContext(context); } } return null; }, null); }); } }
public void request() { final HttpClientRequest httpRequest = client.request( method, proxyToUri.getPort(), proxyToUri.getHost(), uri, resp -> { headers = resp.headers(); code = resp.statusCode(); resp.handler(this.body::appendBuffer); resp.endHandler( end -> { if (code >= 200 && code < 300) { call(onSuccess); } else { call(onFailure); } call(onComplete); }); // TODO can we start writing without waiting the whole buffer? }); httpRequest.exceptionHandler( ex -> { logger.error(format("Got exception processing request: %s", ex.getMessage())); code = INTERNAL_SERVER_ERROR.code(); call(onFailure); call(onComplete); }); httpRequest.headers().setAll(headers); httpRequest.write(requestBody); httpRequest.end(); }
// Process the failover of a deployment private void processFailover(JsonObject failedVerticle) { if (failDuringFailover) { throw new VertxException("Oops!"); } // This method must block until the failover is complete - i.e. the verticle is successfully // redeployed final String verticleName = failedVerticle.getString("verticle_name"); final CountDownLatch latch = new CountDownLatch(1); final AtomicReference<Throwable> err = new AtomicReference<>(); // Now deploy this verticle on this node ContextImpl ctx = vertx.getContext(); if (ctx != null) { // We could be on main thread in which case we don't want to overwrite tccl ContextImpl.setContext(null); } JsonObject options = failedVerticle.getJsonObject("options"); try { doDeployVerticle( verticleName, new DeploymentOptions(options), result -> { if (result.succeeded()) { log.info("Successfully redeployed verticle " + verticleName + " after failover"); } else { log.error("Failed to redeploy verticle after failover", result.cause()); err.set(result.cause()); } latch.countDown(); Throwable t = err.get(); if (t != null) { throw new VertxException(t); } }); } finally { if (ctx != null) { ContextImpl.setContext(ctx); } } try { if (!latch.await(120, TimeUnit.SECONDS)) { throw new VertxException("Timed out waiting for redeploy on failover"); } } catch (InterruptedException e) { throw new IllegalStateException(e); } }
// Deploy any deploymentIDs that are waiting for a quorum private void deployHADeployments() { int size = toDeployOnQuorum.size(); if (size != 0) { log.info( "There are " + size + " HA deploymentIDs waiting on a quorum. These will now be deployed"); Runnable task; while ((task = toDeployOnQuorum.poll()) != null) { try { task.run(); } catch (Throwable t) { log.error("Failed to run redeployment task", t); } } } }
// Undeploy any HA deploymentIDs now there is no quorum private void undeployHADeployments() { for (String deploymentID : deploymentManager.deployments()) { Deployment dep = deploymentManager.getDeployment(deploymentID); if (dep != null) { if (dep.deploymentOptions().isHa()) { ContextImpl ctx = vertx.getContext(); try { ContextImpl.setContext(null); deploymentManager.undeployVerticle( deploymentID, result -> { if (result.succeeded()) { log.info( "Successfully undeployed HA deployment " + deploymentID + "-" + dep.verticleIdentifier() + " as there is no quorum"); addToHADeployList( dep.verticleIdentifier(), dep.deploymentOptions(), result1 -> { if (result1.succeeded()) { log.info( "Successfully redeployed verticle " + dep.verticleIdentifier() + " after quorum was re-attained"); } else { log.error( "Failed to redeploy verticle " + dep.verticleIdentifier() + " after quorum was re-attained", result1.cause()); } }); } else { log.error("Failed to undeploy deployment on lost quorum", result.cause()); } }); } finally { ContextImpl.setContext(ctx); } } } } }
private <T> void reportFailure( Throwable t, Context context, Handler<AsyncResult<T>> completionHandler) { if (completionHandler != null) { reportResult(context, completionHandler, new FutureResultImpl<>(t)); } else { log.error(t.getMessage(), t); } }
@Override public void start() { getVertx() .eventBus() .consumer( "ping-pong", message -> { log.info(String.format("ping-pong receive: %s", message)); message.reply("pong"); }) .completionHandler( event -> { if (event.succeeded()) log.info("complete handler"); else log.info("failed"); }); log.info("Pong started"); }
@Override public synchronized Route failureHandler(Handler<RoutingContext> exceptionHandler) { if (this.failureHandler != null) { log.warn("Setting failureHandler for a route more than once!"); } this.failureHandler = exceptionHandler; checkAdd(); return this; }
@Override public synchronized Route handler(Handler<RoutingContext> contextHandler) { if (this.contextHandler != null) { log.warn("Setting handler for a route more than once!"); } this.contextHandler = contextHandler; checkAdd(); return this; }
/** * Registers the required {@link MessageCodec} for the {@link SlackerRequest} and {@link * SlackerResponse} messages. */ private void registerCodecs() { try { vertx .eventBus() .registerCodec(new SlackerRequestMessageCodec()) .registerCodec(new SlackerResponseMessageCodec()); } catch (final IllegalStateException e) { LOGGER.debug("codecs already registered", e); } }
private void checkHADeployments() { try { if (attainedQuorum) { deployHADeployments(); } else { undeployHADeployments(); } } catch (Throwable t) { log.error("Failed when checking HA deploymentIDs", t); } }
private <T> void reportResult( Context context, Handler<AsyncResult<T>> completionHandler, AsyncResult<T> result) { context.runOnContext( v -> { try { completionHandler.handle(result); } catch (Throwable t) { log.error("Failure in calling handler", t); } }); }
@Override public void postHandle(RoutingContext context) { PaginationContext pageContext = (PaginationContext) context.data().get(PaginationContext.DATA_ATTR); String linkHeader = pageContext.buildLinkHeader(context.request()); if (linkHeader != null) { context.response().headers().add(HttpHeaders.LINK, linkHeader); } else { log.warn("You did not set the total count on PaginationContext, response won't be paginated"); } context.next(); }
// Deploy an HA verticle public void deployVerticle( final String verticleName, DeploymentOptions deploymentOptions, final Handler<AsyncResult<String>> doneHandler) { if (attainedQuorum) { doDeployVerticle(verticleName, deploymentOptions, doneHandler); } else { log.info( "Quorum not attained. Deployment of verticle will be delayed until there's a quorum."); addToHADeployList(verticleName, deploymentOptions, doneHandler); } }
public void simulateKill() { if (!stopped) { killed = true; clusterManager.leave( ar -> { if (ar.failed()) { log.error("Failed to leave cluster", ar.cause()); } }); vertx.cancelTimer(quorumTimerID); stopped = true; } }
public static Config configFor(final JsonObject jsonConf) { final String baseUrl = jsonConf.getString("baseUrl"); final Clients clients = new Clients( baseUrl + "/callback", // oAuth clients facebookClient(jsonConf), twitterClient()); final Config config = new Config(clients); config.addAuthorizer(AUTHORIZER_ADMIN, new RequireAnyRoleAuthorizer("ROLE_ADMIN")); config.addAuthorizer(AUTHORIZER_CUSTOM, new CustomAuthorizer()); LOG.info("Config created " + config.toString()); return config; }
private Twinkle() { final Logger logger = LoggerFactory.getLogger(Twinkle.class); final Vertx vertx = Vertx.vertx(vertxOptions()); final HttpServer httpServer = vertx.createHttpServer(httpServerOptions()); final Router router = Router.router(vertx); router.get("/ping").handler(context -> context.response().end("pong")); router.mountSubRouter("/stats", new Metrics(vertx, httpServer).router()); httpServer .requestHandler(router::accept) .listen( 8080, result -> { if (result.succeeded()) { logger.info("Twinkle started"); } else { logger.error("Twinkle failed to start", result.cause()); vertx.close(shutdown -> logger.info("Twinkle shut down")); } }); }
/** * Handles an incoming request from the event bus * * @param request the request message to be handled */ private void handleExecutorEvent(final Message<SlackerRequest> request) { LOGGER.info("<=<= receiving incoming request <=<="); LOGGER.debug(request); // execute the request handling asynchronously context.runOnContext( a -> { final Future<SlackerResponse> future = futureFactory.future(); execute(request.body(), future); future.setHandler( handler -> { if (handler.succeeded()) { LOGGER.info("=>=> successfully handled request =>=>"); LOGGER.debug(handler.result()); request.reply( handler.result(), new DeliveryOptions().setCodecName(SlackerResponseMessageCodec.NAME)); } else { request.fail(ResultCode.ERROR.ordinal(), handler.cause().getMessage()); LOGGER.error("failed to handle request", handler.cause()); } }); }); }
public void undeployAll(Handler<AsyncResult<Void>> completionHandler) { Set<String> deploymentIDs = new HashSet<>(deployments.keySet()); AtomicInteger count = new AtomicInteger(deploymentIDs.size()); for (String deploymentID : deploymentIDs) { undeployVerticle( deploymentID, ar -> { if (ar.failed()) { log.error("Undeploy failed", ar.cause()); } if (count.incrementAndGet() == deploymentIDs.size()) { completionHandler.handle(new FutureResultImpl<>((Void) null)); } }); } }
@Override public void handle(RoutingContext context) { username = context.user().principal().getString("username"); jdbcClient.getConnection( connectionRes -> { if (connectionRes.succeeded()) { // System.out.println("Able to get JDBC Connection"); queryLocation(context, connectionRes); } else { log.error("Could not connect to the database."); context.fail(402); } }); }
private void queryBudget(RoutingContext context, SQLConnection connection) { connection.query( "SELECT budget FROM preferences WHERE username = '******'", res2 -> { if (res2.succeeded()) { // System.out.println("Able to get budget query"); ResultSet resultSet = res2.result(); for (JsonArray line : res2.result().getResults()) { Budget = line.encode(); Budget = Budget.replaceAll("[^a-zA-Z,' ']", ""); // System.out.println("Budget: "+Budget); } queryHotels(context, connection); } else { log.error("Could not select budget from pref table table"); } }); }
private void doDeployVerticle( final String verticleName, DeploymentOptions deploymentOptions, final Handler<AsyncResult<String>> doneHandler) { final Handler<AsyncResult<String>> wrappedHandler = asyncResult -> { if (asyncResult.succeeded()) { // Tell the other nodes of the cluster about the verticle for HA purposes addToHA(asyncResult.result(), verticleName, deploymentOptions); } if (doneHandler != null) { doneHandler.handle(asyncResult); } else if (asyncResult.failed()) { log.error("Failed to deploy verticle", asyncResult.cause()); } }; deploymentManager.deployVerticle(verticleName, deploymentOptions, wrappedHandler); }
private void queryHotels(RoutingContext context, SQLConnection connection) { // Retrieve Hotels connection.query( "SELECT name FROM hotel ", res2 -> { if (res2.succeeded()) { // System.out.println("Able to get hotel query"); for (JsonArray line : res2.result().getResults()) { Hotel[Hotelcounter] = line.encode(); Hotel[Hotelcounter] = Hotel[Hotelcounter].replaceAll("[^a-zA-Z' ']", ""); Hotelcounter++; } Hotelcounter = 0; queryHotelPricing(context, connection); } else { log.error("Could not select from the user table"); } }); }