Skip to content

Commit 86ec7c8

Browse files
author
Robin Duda
committed
Progress bar shows actual progress + fix for empty cells + menu fix.
1 parent 96ca79c commit 86ec7c8

File tree

9 files changed

+197
-93
lines changed

9 files changed

+197
-93
lines changed

src/main/java/com/codingchili/ApplicationLauncher.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
*/
2828
public class ApplicationLauncher {
2929
private static final Logger logger = Logger.getLogger(ApplicationLauncher.class.getName());
30-
public static String version = "1.2.2";
30+
public static String VERSION = "1.2.3";
3131
private Vertx vertx = Vertx.vertx();
3232
private String[] args;
3333

@@ -38,7 +38,7 @@ public static void main(String[] args) {
3838
public ApplicationLauncher(String[] args) {
3939
this.args = args;
4040

41-
logger.info(String.format("Starting excelastic %s..", version));
41+
logger.info(String.format("Starting excelastic %s..", VERSION));
4242
logger.info("to import files without the web interface use: <filename> <index> <mapping>");
4343
Future<Void> future = Future.future();
4444

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.codingchili.Controller;
2+
3+
public class Atomic<E> {
4+
private E reference;
5+
6+
public Atomic(E reference) {
7+
this.reference = reference;
8+
}
9+
10+
public E get() {
11+
return reference;
12+
}
13+
14+
public void set(E reference) {
15+
this.reference = reference;
16+
}
17+
}

src/main/java/com/codingchili/Controller/Website.java

+78-47
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,44 @@
11
package com.codingchili.Controller;
22

3-
import com.codingchili.ApplicationLauncher;
3+
import java.io.PrintWriter;
4+
import java.io.StringWriter;
5+
import java.util.Iterator;
6+
import java.util.logging.Level;
7+
import java.util.logging.Logger;
8+
49
import com.codingchili.Model.Configuration;
510
import com.codingchili.Model.ElasticWriter;
611
import com.codingchili.Model.FileParser;
712
import com.codingchili.Model.ParserException;
8-
import io.vertx.core.*;
13+
import static com.codingchili.ApplicationLauncher.VERSION;
14+
import static com.codingchili.Model.Configuration.INDEXING_ELASTICSEARCH;
15+
import static com.codingchili.Model.ElasticWriter.*;
16+
import static com.codingchili.Model.FileParser.INDEX;
17+
18+
import io.vertx.core.AbstractVerticle;
19+
import io.vertx.core.Context;
20+
import io.vertx.core.Future;
21+
import io.vertx.core.MultiMap;
22+
import io.vertx.core.Vertx;
923
import io.vertx.core.buffer.Buffer;
1024
import io.vertx.core.eventbus.DeliveryOptions;
25+
import io.vertx.core.eventbus.MessageConsumer;
26+
import io.vertx.core.json.JsonObject;
1127
import io.vertx.ext.web.FileUpload;
1228
import io.vertx.ext.web.Router;
1329
import io.vertx.ext.web.handler.BodyHandler;
1430
import io.vertx.ext.web.handler.StaticHandler;
1531
import io.vertx.ext.web.handler.TemplateHandler;
1632
import io.vertx.ext.web.templ.JadeTemplateEngine;
1733

18-
import java.io.PrintWriter;
19-
import java.io.StringWriter;
20-
import java.util.Iterator;
21-
import java.util.logging.Level;
22-
import java.util.logging.Logger;
23-
24-
import static com.codingchili.Model.ElasticWriter.INDEXING_TIMEOUT;
25-
import static com.codingchili.Model.FileParser.INDEX;
26-
2734
/**
2835
* @author Robin Duda
29-
* <p>
30-
* Manages the web interface and handles file uploads.
36+
* <p>
37+
* Manages the web interface and handles file uploads.
3138
*/
3239
public class Website extends AbstractVerticle {
3340
public static final String MAPPING = "mapping";
41+
public static final String UPLOAD_ID = "uploadId";
3442
private Logger logger = Logger.getLogger(getClass().getName());
3543
private static final String DONE = "/done";
3644
private static final String ERROR = "/error";
@@ -57,7 +65,7 @@ public void start(Future<Void> start) {
5765

5866
// adds values used in the template to all routes.
5967
router.route("/*").handler(context -> {
60-
context.put("version", ApplicationLauncher.version);
68+
context.put("version", VERSION);
6169
context.put("esVersion", ElasticWriter.getElasticVersion());
6270
context.put("esURL", Configuration.getElasticURL());
6371
context.put("connected", ElasticWriter.isConnected());
@@ -66,7 +74,25 @@ public void start(Future<Void> start) {
6674

6775
router.route("/*").handler(TemplateHandler.create(JadeTemplateEngine.create()));
6876

69-
vertx.createHttpServer().requestHandler(router::accept).listen(Configuration.getWebPort(), done -> {
77+
vertx.createHttpServer().websocketHandler(websock -> {
78+
websock.writeFinalTextFrame(new JsonObject().put("message", "websocket connected to excelastic " + VERSION +
79+
" using ElasticSearch " + getElasticVersion()).encode());
80+
81+
Atomic<String> uploadId = new Atomic<>("");
82+
MessageConsumer<JsonObject> consumer = vertx.eventBus().consumer(IMPORT_PROGRESS, data -> {
83+
try {
84+
if (uploadId.get().equals(data.body().getString(UPLOAD_ID))) {
85+
websock.writeFinalTextFrame(data.body().encode());
86+
}
87+
} catch (Throwable e) {
88+
websock.close();
89+
}
90+
});
91+
websock.handler(handler -> uploadId.set(handler.toJsonObject().getString(UPLOAD_ID)));
92+
websock.closeHandler(closed -> consumer.unregister());
93+
websock.exceptionHandler(sock -> consumer.unregister());
94+
95+
}).requestHandler(router::accept).listen(Configuration.getWebPort(), done -> {
7096
if (done.succeeded()) {
7197
Configuration.setWebPort(done.result().actualPort());
7298
logger.info("Started website on port " + Configuration.getWebPort());
@@ -79,35 +105,37 @@ public void start(Future<Void> start) {
79105

80106
/**
81107
* Adds the upload route to the given router
108+
*
82109
* @param router the upload route is added to the given router
83110
*/
84111
private void setRouterAPI(Router router) {
85112
router.route("/api/upload").handler(context -> {
86113
Iterator<FileUpload> iterator = context.fileUploads().iterator();
87114

88115
if (iterator.hasNext()) {
89-
logger.info("Receiving uploaded file.. ");
116+
MultiMap params = context.request().params();
117+
logger.info("Receiving uploaded file with request id " + params.get(UPLOAD_ID));
90118
FileUpload upload = context.fileUploads().iterator().next();
91119

92120
vertx.fileSystem().readFile(upload.uploadedFileName(), file -> {
93-
parse(file.result(), context.request().params(), upload.fileName(),
94-
Future.<Integer>future().setHandler(result -> {
95-
if (result.succeeded()) {
96-
String index = context.request().params().get(INDEX);
97-
logger.info(String.format("Imported file '%s' successfully into '%s'.",
98-
upload.fileName(), index));
99-
100-
context.put(INDEX, index);
101-
context.put(FILE, upload.fileName());
102-
context.put(IMPORTED, result.result());
103-
context.reroute(DONE);
104-
} else {
105-
context.put(MESSAGE, traceToText(result.cause()));
106-
logger.log(Level.SEVERE, String.format("Failed to parse file '%s'.",
107-
upload.fileName()), result.cause());
108-
context.reroute(ERROR);
109-
}
110-
}));
121+
parse(file.result(), params, upload.fileName(),
122+
Future.<Integer>future().setHandler(result -> {
123+
if (result.succeeded()) {
124+
String index = context.request().params().get(INDEX);
125+
logger.info(String.format("Imported file '%s' successfully into '%s'.",
126+
upload.fileName(), index));
127+
128+
context.put(INDEX, index);
129+
context.put(FILE, upload.fileName());
130+
context.put(IMPORTED, result.result());
131+
context.reroute(DONE);
132+
} else {
133+
context.put(MESSAGE, traceToText(result.cause()));
134+
logger.log(Level.SEVERE, String.format("Failed to parse file '%s'.",
135+
upload.fileName()), result.cause());
136+
context.reroute(ERROR);
137+
}
138+
}));
111139
});
112140
} else {
113141
context.put(MESSAGE, NO_FILE_WAS_UPLOADED);
@@ -118,6 +146,7 @@ private void setRouterAPI(Router router) {
118146

119147
/**
120148
* converts a throwables stack trace into a string.
149+
*
121150
* @param throwable the throwable to be converted.
122151
* @return a textual representation of the throwables trace,
123152
* may be used in the app to display errors.
@@ -131,26 +160,28 @@ private String traceToText(Throwable throwable) {
131160
/**
132161
* Parses a file upload request, converting the excel payload into json and waits
133162
* for elasticsearch to complete indexing.
134-
* @param buffer contains the excel file data
135-
* @param params upload parameters
163+
*
164+
* @param buffer contains the excel file data
165+
* @param params upload parameters
136166
* @param fileName the name of the uploaded file
137-
* @param future callback on completed parse + indexing.
167+
* @param future callback on completed parse + indexing.
138168
*/
139169
private void parse(Buffer buffer, MultiMap params, String fileName, Future<Integer> future) {
140170
vertx.<Integer>executeBlocking(blocking -> {
141171
try {
142172
int columnRow = Integer.parseInt(params.get(OFFSET));
143173
FileParser parser = new FileParser(buffer.getBytes(), columnRow, fileName);
144-
vertx.eventBus().send(Configuration.INDEXING_ELASTICSEARCH,
145-
parser.toImportable(params.get(INDEX), getMappingByParams(params)),
146-
new DeliveryOptions().setSendTimeout(INDEXING_TIMEOUT),
147-
reply -> {
148-
if (reply.succeeded()) {
149-
blocking.complete(parser.getImportedItems());
150-
} else {
151-
blocking.fail(reply.cause());
152-
}
153-
});
174+
JsonObject data = parser.toImportable(params.get(INDEX), getMappingByParams(params))
175+
.put(UPLOAD_ID, params.get(UPLOAD_ID));
176+
177+
vertx.eventBus().send(INDEXING_ELASTICSEARCH, data, new DeliveryOptions().setSendTimeout(INDEXING_TIMEOUT),
178+
reply -> {
179+
if (reply.succeeded()) {
180+
blocking.complete(parser.getImportedItems());
181+
} else {
182+
blocking.fail(reply.cause());
183+
}
184+
});
154185
} catch (ParserException | NumberFormatException e) {
155186
blocking.fail(new ParserException(e));
156187
}

src/main/java/com/codingchili/Model/ElasticWriter.java

+13-7
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import java.util.logging.Logger;
99

1010
import static com.codingchili.Controller.Website.MAPPING;
11+
import static com.codingchili.Controller.Website.UPLOAD_ID;
1112
import static com.codingchili.Model.FileParser.ITEMS;
1213

1314
/**
@@ -16,12 +17,14 @@
1617
* Writes json data to elasticsearch for indexing.
1718
*/
1819
public class ElasticWriter extends AbstractVerticle {
19-
public static final int INDEXING_TIMEOUT = 300000;
20+
public static final int INDEXING_TIMEOUT = 3000000;
2021
private static final String INDEX = "index";
2122
private static final String BULK = "/_bulk";
2223
private static final int POLL = 5000;
2324
private static final int MAX_BATCH = 255;
2425
public static final String ES_STATUS = "es-status";
26+
private static final String PROGRESS = "progress";
27+
public static final String IMPORT_PROGRESS = "import.progress";
2528
private static boolean connected = false;
2629
private static String version = "";
2730
private Logger logger = Logger.getLogger(getClass().getName());
@@ -90,6 +93,10 @@ private Future<Void> submitForIndexing(JsonArray items, JsonObject data, int cur
9093
String.format("Submitted items [%d -> %d] of %d with result [%d] %s into '%s' [%.1f%%]",
9194
current, max - 1, items.size(), response.statusCode(), response.statusMessage(), index, percent));
9295

96+
vertx.eventBus().publish(IMPORT_PROGRESS, new JsonObject()
97+
.put(PROGRESS, percent)
98+
.put(UPLOAD_ID, data.getString(UPLOAD_ID)));
99+
93100
future.complete();
94101
})).exceptionHandler(exception -> future.fail(exception.getMessage()))
95102
.end(bulkQuery(items, index, mapping, max, current));
@@ -110,18 +117,17 @@ private HttpClientRequest post(String path) {
110117
* @return a payload encoded as json-lines.
111118
*/
112119
private String bulkQuery(JsonArray list, String index, String mapping, int max, int current) {
113-
String query = "";
114-
JsonObject header = new JsonObject()
120+
StringBuilder query = new StringBuilder();
121+
String header = new JsonObject()
115122
.put("index", new JsonObject()
116123
.put("_index", index)
117-
.put("_type", mapping));
124+
.put("_type", mapping)).encode() + "\n";
118125

119126
for (int i = current; i < max; i++) {
120-
query += header.encode() + "\n";
121-
query += list.getJsonObject(i).encode() + "\n";
127+
query.append(header).append(list.getJsonObject(i).encode()).append("\n");
122128
}
123129

124-
return query;
130+
return query.toString();
125131
}
126132

127133
/**

0 commit comments

Comments
 (0)