Search in sources :

Example 56 with AsyncResult

use of io.vertx.core.AsyncResult in project georocket by georocket.

the class StoreEndpoint method onPost.

/**
 * Handles the HTTP POST request
 * @param context the routing context
 */
private void onPost(RoutingContext context) {
    HttpServerRequest request = context.request();
    request.pause();
    String layer = getEndpointPath(context);
    String tagsStr = request.getParam("tags");
    String propertiesStr = request.getParam("props");
    String fallbackCRSString = request.getParam("fallbackCRS");
    List<String> tags = StringUtils.isNotEmpty(tagsStr) ? Splitter.on(',').trimResults().splitToList(tagsStr) : null;
    Map<String, Object> properties = new HashMap<>();
    if (StringUtils.isNotEmpty(propertiesStr)) {
        String regex = "(?<!" + Pattern.quote("\\") + ")" + Pattern.quote(":");
        String[] parts = propertiesStr.split(",");
        for (String part : parts) {
            part = part.trim();
            String[] property = part.split(regex);
            if (property.length != 2) {
                request.response().setStatusCode(400).end("Invalid property syntax: " + part);
                return;
            }
            String key = StringEscapeUtils.unescapeJava(property[0].trim());
            String value = StringEscapeUtils.unescapeJava(property[1].trim());
            properties.put(key, value);
        }
    }
    // get temporary filename
    String incoming = storagePath + "/incoming";
    String filename = new ObjectId().toString();
    String filepath = incoming + "/" + filename;
    String correlationId = UUID.randomUUID().toString();
    long startTime = System.currentTimeMillis();
    this.onReceivingFileStarted(correlationId, layer, startTime);
    // create directory for incoming files
    FileSystem fs = vertx.fileSystem();
    ObservableFuture<Void> observable = RxHelper.observableFuture();
    fs.mkdirs(incoming, observable.toHandler());
    observable.flatMap(v -> {
        // create temporary file
        ObservableFuture<AsyncFile> openObservable = RxHelper.observableFuture();
        fs.open(filepath, new OpenOptions(), openObservable.toHandler());
        return openObservable;
    }).flatMap(f -> {
        // write request body into temporary file
        ObservableFuture<Void> pumpObservable = RxHelper.observableFuture();
        Handler<AsyncResult<Void>> pumpHandler = pumpObservable.toHandler();
        Pump.pump(request, f).start();
        Handler<Throwable> errHandler = (Throwable t) -> {
            request.endHandler(null);
            f.close();
            pumpHandler.handle(Future.failedFuture(t));
        };
        f.exceptionHandler(errHandler);
        request.exceptionHandler(errHandler);
        request.endHandler(v -> {
            f.close();
            pumpHandler.handle(Future.succeededFuture());
        });
        request.resume();
        return pumpObservable;
    }).flatMap(v -> {
        String contentTypeHeader = request.getHeader("Content-Type");
        String mimeType = null;
        try {
            ContentType contentType = ContentType.parse(contentTypeHeader);
            mimeType = contentType.getMimeType();
        } catch (ParseException | IllegalArgumentException ex) {
        // mimeType already null
        }
        // detect content type of file to import
        if (mimeType == null || mimeType.trim().isEmpty() || mimeType.equals("application/octet-stream") || mimeType.equals("application/x-www-form-urlencoded")) {
            // fallback: if the client has not sent a Content-Type or if it's
            // a generic one, then try to guess it
            log.debug("Mime type '" + mimeType + "' is invalid or generic. " + "Trying to guess the right type.");
            return detectContentType(filepath).doOnNext(guessedType -> {
                log.debug("Guessed mime type '" + guessedType + "'.");
            });
        }
        return Observable.just(mimeType);
    }).subscribe(detectedContentType -> {
        long duration = System.currentTimeMillis() - startTime;
        this.onReceivingFileFinished(correlationId, duration, layer, null);
        // run importer
        JsonObject msg = new JsonObject().put("filename", filename).put("layer", layer).put("contentType", detectedContentType).put("correlationId", correlationId);
        if (tags != null) {
            msg.put("tags", new JsonArray(tags));
        }
        if (!properties.isEmpty()) {
            msg.put("properties", new JsonObject(properties));
        }
        if (fallbackCRSString != null) {
            msg.put("fallbackCRSString", fallbackCRSString);
        }
        request.response().setStatusCode(// Accepted
        202).putHeader("X-Correlation-Id", correlationId).setStatusMessage("Accepted file - importing in progress").end();
        // run importer
        vertx.eventBus().send(AddressConstants.IMPORTER_IMPORT, msg);
    }, err -> {
        long duration = System.currentTimeMillis() - startTime;
        this.onReceivingFileFinished(correlationId, duration, layer, err);
        fail(request.response(), err);
        err.printStackTrace();
        fs.delete(filepath, ar -> {
        });
    });
}
Also used : Arrays(java.util.Arrays) Router(io.vertx.ext.web.Router) RxStoreCursor(io.georocket.storage.RxStoreCursor) RoutingContext(io.vertx.ext.web.RoutingContext) StringUtils(org.apache.commons.lang3.StringUtils) ChunkMeta(io.georocket.storage.ChunkMeta) RxStore(io.georocket.storage.RxStore) StoreCursor(io.georocket.storage.StoreCursor) Single(rx.Single) Pair(org.apache.commons.lang3.tuple.Pair) Map(java.util.Map) Pump(io.vertx.core.streams.Pump) JsonObject(io.vertx.core.json.JsonObject) Logger(io.vertx.core.logging.Logger) Splitter(com.google.common.base.Splitter) OpenOptions(io.vertx.core.file.OpenOptions) ContentType(org.apache.http.entity.ContentType) UUID(java.util.UUID) Future(io.vertx.core.Future) FileNotFoundException(java.io.FileNotFoundException) List(java.util.List) Buffer(io.vertx.core.buffer.Buffer) HttpServerResponse(io.vertx.core.http.HttpServerResponse) FileSystem(io.vertx.core.file.FileSystem) RxHelper(io.vertx.rx.java.RxHelper) MultiMerger(io.georocket.output.MultiMerger) Pattern(java.util.regex.Pattern) AddressConstants(io.georocket.constants.AddressConstants) AsyncFile(io.vertx.core.file.AsyncFile) HttpServerRequest(io.vertx.core.http.HttpServerRequest) MimeTypeUtils(io.georocket.util.MimeTypeUtils) HashMap(java.util.HashMap) LoggerFactory(io.vertx.core.logging.LoggerFactory) Observable(rx.Observable) ServerAPIException(io.georocket.ServerAPIException) WriteStream(io.vertx.core.streams.WriteStream) StoreFactory(io.georocket.storage.StoreFactory) AsyncResult(io.vertx.core.AsyncResult) HttpException(io.georocket.util.HttpException) ParseException(org.apache.http.ParseException) ObservableFuture(io.vertx.rx.java.ObservableFuture) Vertx(io.vertx.core.Vertx) IOException(java.io.IOException) StringEscapeUtils(org.apache.commons.text.StringEscapeUtils) RxAsyncCursor(io.georocket.storage.RxAsyncCursor) File(java.io.File) JsonArray(io.vertx.core.json.JsonArray) ObjectId(org.bson.types.ObjectId) Merger(io.georocket.output.Merger) Handler(io.vertx.core.Handler) ConfigConstants(io.georocket.constants.ConfigConstants) OpenOptions(io.vertx.core.file.OpenOptions) ContentType(org.apache.http.entity.ContentType) HashMap(java.util.HashMap) ObjectId(org.bson.types.ObjectId) HttpServerRequest(io.vertx.core.http.HttpServerRequest) JsonObject(io.vertx.core.json.JsonObject) JsonArray(io.vertx.core.json.JsonArray) ObservableFuture(io.vertx.rx.java.ObservableFuture) FileSystem(io.vertx.core.file.FileSystem) JsonObject(io.vertx.core.json.JsonObject) AsyncResult(io.vertx.core.AsyncResult)

Example 57 with AsyncResult

use of io.vertx.core.AsyncResult in project georocket by georocket.

the class RemoteElasticsearchClient method performRequest.

/**
 * Perform an HTTP request
 * @param req the request to perform
 * @param body the body to send in the request (may be null)
 * @return an observable emitting the parsed response body (may be null if no
 * body was received)
 */
private Observable<JsonObject> performRequest(HttpClientRequest req, String body) {
    ObservableFuture<JsonObject> observable = RxHelper.observableFuture();
    Handler<AsyncResult<JsonObject>> handler = observable.toHandler();
    req.exceptionHandler(t -> {
        handler.handle(Future.failedFuture(t));
    });
    req.handler(res -> {
        int code = res.statusCode();
        if (code == 200) {
            Buffer buf = Buffer.buffer();
            res.handler(b -> {
                buf.appendBuffer(b);
            });
            res.endHandler(v -> {
                if (buf.length() > 0) {
                    handler.handle(Future.succeededFuture(buf.toJsonObject()));
                } else {
                    handler.handle(Future.succeededFuture());
                }
            });
        } else {
            handler.handle(Future.failedFuture(new HttpException(code)));
        }
    });
    if (body != null) {
        req.setChunked(false);
        Buffer buf = Buffer.buffer(body);
        req.putHeader("Content-Length", String.valueOf(buf.length()));
        req.end(buf);
    } else {
        req.end();
    }
    return observable;
}
Also used : Buffer(io.vertx.rxjava.core.buffer.Buffer) JsonObject(io.vertx.core.json.JsonObject) HttpException(io.georocket.util.HttpException) AsyncResult(io.vertx.core.AsyncResult)

Example 58 with AsyncResult

use of io.vertx.core.AsyncResult in project vert.x by eclipse.

the class Http2ConnectionBase method updateSettings.

protected void updateSettings(Http2Settings settingsUpdate, Handler<AsyncResult<Void>> completionHandler) {
    Http2Settings current = handler.decoder().localSettings();
    for (Map.Entry<Character, Long> entry : current.entrySet()) {
        Character key = entry.getKey();
        if (Objects.equals(settingsUpdate.get(key), entry.getValue())) {
            settingsUpdate.remove(key);
        }
    }
    Handler<Void> pending = v -> {
        synchronized (Http2ConnectionBase.this) {
            localSettings.putAll(settingsUpdate);
        }
        if (completionHandler != null) {
            completionHandler.handle(Future.succeededFuture());
        }
    };
    updateSettingsHandlers.add(pending);
    handler.writeSettings(settingsUpdate).addListener(fut -> {
        if (!fut.isSuccess()) {
            synchronized (Http2ConnectionBase.this) {
                updateSettingsHandlers.remove(pending);
            }
            if (completionHandler != null) {
                completionHandler.handle(Future.failedFuture(fut.cause()));
            }
        }
    });
}
Also used : VertxException(io.vertx.core.VertxException) LoggerFactory(io.vertx.core.impl.logging.LoggerFactory) ConnectionBase(io.vertx.core.net.impl.ConnectionBase) ArrayList(java.util.ArrayList) VertxByteBufAllocator(io.vertx.core.buffer.impl.VertxByteBufAllocator) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ChannelPromise(io.netty.channel.ChannelPromise) ChannelFutureListener(io.netty.channel.ChannelFutureListener) Http2Exception(io.netty.handler.codec.http2.Http2Exception) Map(java.util.Map) Http2Stream(io.netty.handler.codec.http2.Http2Stream) AsyncResult(io.vertx.core.AsyncResult) HttpConnection(io.vertx.core.http.HttpConnection) Logger(io.vertx.core.impl.logging.Logger) io.netty.buffer(io.netty.buffer) IdleStateEvent(io.netty.handler.timeout.IdleStateEvent) PromiseInternal(io.vertx.core.impl.future.PromiseInternal) VertxInternal(io.vertx.core.impl.VertxInternal) Http2Flags(io.netty.handler.codec.http2.Http2Flags) StreamPriority(io.vertx.core.http.StreamPriority) Promise(io.vertx.core.Promise) GoAway(io.vertx.core.http.GoAway) Http2FrameListener(io.netty.handler.codec.http2.Http2FrameListener) Future(io.vertx.core.Future) ChannelFuture(io.netty.channel.ChannelFuture) Http2Settings(io.netty.handler.codec.http2.Http2Settings) Nullable(io.vertx.codegen.annotations.Nullable) Objects(java.util.Objects) EventLoopContext(io.vertx.core.impl.EventLoopContext) Http2Connection(io.netty.handler.codec.http2.Http2Connection) Buffer(io.vertx.core.buffer.Buffer) Http2Headers(io.netty.handler.codec.http2.Http2Headers) Handler(io.vertx.core.Handler) ArrayDeque(java.util.ArrayDeque) Http2Settings(io.netty.handler.codec.http2.Http2Settings) Map(java.util.Map)

Example 59 with AsyncResult

use of io.vertx.core.AsyncResult in project vert.x by eclipse.

the class WebSocketEndpoint method tryConnect.

private void tryConnect(ContextInternal ctx, Handler<AsyncResult<HttpClientConnection>> handler) {
    class Listener implements Handler<AsyncResult<HttpClientConnection>> {

        private void onEvict() {
            decRefCount();
            Waiter h;
            synchronized (WebSocketEndpoint.this) {
                if (--inflightConnections > maxPoolSize || waiters.isEmpty()) {
                    return;
                }
                h = waiters.poll();
            }
            tryConnect(h.context, h.handler);
        }

        @Override
        public void handle(AsyncResult<HttpClientConnection> ar) {
            if (ar.succeeded()) {
                HttpClientConnection c = ar.result();
                if (incRefCount()) {
                    c.evictionHandler(v -> onEvict());
                    handler.handle(Future.succeededFuture(c));
                } else {
                    c.close();
                    handler.handle(Future.failedFuture("Connection closed"));
                }
            } else {
                handler.handle(Future.failedFuture(ar.cause()));
            }
        }
    }
    EventLoopContext eventLoopContext;
    if (ctx instanceof EventLoopContext) {
        eventLoopContext = (EventLoopContext) ctx;
    } else {
        eventLoopContext = ctx.owner().createEventLoopContext(ctx.nettyEventLoop(), ctx.workerPool(), ctx.classLoader());
    }
    connector.httpConnect(eventLoopContext, new Listener());
}
Also used : Handler(io.vertx.core.Handler) AsyncResult(io.vertx.core.AsyncResult) EventLoopContext(io.vertx.core.impl.EventLoopContext)

Example 60 with AsyncResult

use of io.vertx.core.AsyncResult in project vert.x by eclipse.

the class FakeStreamTest method testAsyncEnd.

@Test
public void testAsyncEnd() {
    Promise<Void> end = Promise.promise();
    AtomicInteger ended = new AtomicInteger();
    AtomicReference<AsyncResult> endRes = new AtomicReference<>();
    stream.setEnd(end.future());
    stream.endHandler(v -> ended.incrementAndGet());
    stream.end(endRes::set);
    assertEquals(0, ended.get());
    assertNull(endRes.get());
    end.complete();
    assertEquals(1, ended.get());
    assertTrue(endRes.get().succeeded());
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AtomicReference(java.util.concurrent.atomic.AtomicReference) AsyncResult(io.vertx.core.AsyncResult) Test(org.junit.Test)

Aggregations

AsyncResult (io.vertx.core.AsyncResult)162 Handler (io.vertx.core.Handler)106 Test (org.junit.Test)72 JsonObject (io.vertx.core.json.JsonObject)68 CountDownLatch (java.util.concurrent.CountDownLatch)62 Future (io.vertx.core.Future)59 List (java.util.List)49 RequestParameter (io.vertx.ext.web.api.RequestParameter)48 RequestParameters (io.vertx.ext.web.api.RequestParameters)48 HashMap (java.util.HashMap)45 Map (java.util.Map)42 IOException (java.io.IOException)41 ArrayList (java.util.ArrayList)40 Vertx (io.vertx.core.Vertx)35 Collectors (java.util.stream.Collectors)35 RoutingContext (io.vertx.ext.web.RoutingContext)28 Buffer (io.vertx.core.buffer.Buffer)24 StandardCharsets (java.nio.charset.StandardCharsets)23 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)23 Consumer (java.util.function.Consumer)23