use of io.vertx.rx.java.ObservableFuture 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 -> {
});
});
}
use of io.vertx.rx.java.ObservableFuture in project georocket by georocket.
the class ElasticsearchInstaller method extractArchive.
/**
* Extract the Elasticsearch ZIP archive to a destination path
* @param archivePath the path to the ZIP file
* @param destPath the destination path
* @param strip <code>true</code> if the first path element of all items in the
* ZIP file should be stripped away.
* @return emitting the path to the extracted contents (i.e.
* <code>destPath</code>)
*/
private Single<String> extractArchive(String archivePath, String destPath, boolean strip) {
ObservableFuture<String> observable = RxHelper.observableFuture();
Handler<AsyncResult<String>> handler = observable.toHandler();
// extract archive asynchronously
vertx.executeBlocking(f -> {
File archiveFile = new File(archivePath);
File destFile = new File(destPath);
destFile.mkdirs();
try {
extractZip(archiveFile, destFile, strip);
f.complete();
} catch (IOException e) {
FileUtils.deleteQuietly(destFile);
f.fail(e);
}
}, ar -> {
if (ar.failed()) {
handler.handle(Future.failedFuture(ar.cause()));
} else {
handler.handle(Future.succeededFuture(destPath));
}
});
// set executable permissions for Elasticsearch binary
return observable.doOnNext(path -> {
if (!SystemUtils.IS_OS_WINDOWS) {
log.info("Set executable permissions for \"bin/elasticsearch\"");
File archiveFile = new File(path);
File executable = new File(archiveFile, "bin/elasticsearch");
executable.setExecutable(true);
}
}).toSingle();
}
use of io.vertx.rx.java.ObservableFuture in project georocket by georocket.
the class FileStore method getOne.
@Override
public void getOne(String path, Handler<AsyncResult<ChunkReadStream>> handler) {
String absolutePath = Paths.get(root, path).toString();
// check if chunk exists
FileSystem fs = vertx.fileSystem();
ObservableFuture<Boolean> observable = RxHelper.observableFuture();
fs.exists(absolutePath, observable.toHandler());
observable.flatMap(exists -> {
if (!exists) {
return Observable.error(new FileNotFoundException("Could not find chunk: " + path));
}
return Observable.just(exists);
}).flatMap(exists -> {
// get chunk's size
ObservableFuture<FileProps> propsObservable = RxHelper.observableFuture();
fs.props(absolutePath, propsObservable.toHandler());
return propsObservable;
}).map(props -> props.size()).flatMap(size -> {
// open chunk
ObservableFuture<AsyncFile> openObservable = RxHelper.observableFuture();
OpenOptions openOptions = new OpenOptions().setCreate(false).setWrite(false);
fs.open(absolutePath, openOptions, openObservable.toHandler());
return openObservable.map(f -> new FileChunkReadStream(size, f));
}).subscribe(readStream -> {
// send chunk to peer
handler.handle(Future.succeededFuture(readStream));
}, err -> {
handler.handle(Future.failedFuture(err));
});
}
use of io.vertx.rx.java.ObservableFuture in project georocket by georocket.
the class ImportCommand method importFile.
/**
* Upload a file to GeoRocket
* @param path path to file to import
* @param client the GeoRocket client
* @param vertx the Vert.x instance
* @return an observable that will emit when the file has been uploaded
*/
protected Observable<Void> importFile(String path, GeoRocketClient client, Vertx vertx) {
// open file
FileSystem fs = vertx.fileSystem();
OpenOptions openOptions = new OpenOptions().setCreate(false).setWrite(false);
return fs.rxOpen(path, openOptions).flatMap(f -> fs.rxProps(path).map(props -> Pair.of(f, props.size()))).flatMapObservable(f -> {
ObservableFuture<Void> o = RxHelper.observableFuture();
Handler<AsyncResult<Void>> handler = o.toHandler();
AsyncFile file = f.getLeft().getDelegate();
WriteStream<Buffer> out = client.getStore().startImport(layer, tags, properties, Optional.of(f.getRight()), fallbackCRS, handler);
AtomicBoolean fileClosed = new AtomicBoolean();
Pump pump = Pump.pump(file, out);
file.endHandler(v -> {
file.close();
out.end();
fileClosed.set(true);
});
Handler<Throwable> exceptionHandler = t -> {
if (!fileClosed.get()) {
file.endHandler(null);
file.close();
}
handler.handle(Future.failedFuture(t));
};
file.exceptionHandler(exceptionHandler);
out.exceptionHandler(exceptionHandler);
pump.start();
return o;
});
}
Aggregations