|
|
@@ -11,10 +11,13 @@ import io.vertx.ext.web.handler.BodyHandler;
|
|
|
import org.apache.logging.log4j.LogManager;
|
|
|
import org.apache.logging.log4j.Logger;
|
|
|
|
|
|
+import java.time.LocalDateTime;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
|
|
|
+import static cz.senslog.common.http.HttpContentType.APPLICATION_JSON;
|
|
|
+import static cz.senslog.common.http.HttpHeader.CONTENT_TYPE;
|
|
|
import static io.connector.core.AddressPath.Creator.create;
|
|
|
import static io.connector.core.AddressPath.Creator.createNormalized;
|
|
|
import static io.connector.core.AddressPath.SCHEDULER_CONSUMER;
|
|
|
@@ -44,53 +47,87 @@ class VertxScheduler extends Module {
|
|
|
this.scheduledModules = new HashMap<>(schedulerConfigs.size());
|
|
|
}
|
|
|
|
|
|
+ private long registerNewSchedulingRole(String moduleId, SchedulerConfig config) {
|
|
|
+ EventBus eventBus = vertx.eventBus();
|
|
|
+ if (config != null && config.getPeriodSecond() > 0) {
|
|
|
+ return vertx.setPeriodic(config.getPeriodMillisecond(), ctx -> {
|
|
|
+ if (config.shouldTerminate()) { return; }
|
|
|
+ DeliveryOptions fetcherOpt = new DeliveryOptions()
|
|
|
+ .addHeader(RESOURCE, SCHEDULER)
|
|
|
+ .addHeader(ADDRESS, config.getConsumer());
|
|
|
+ String providerAddress = createNormalized(SCHEDULER_PROVIDER, moduleId);
|
|
|
+ eventBus.request(providerAddress, config.getConfig(), fetcherOpt, reply -> {
|
|
|
+ if (reply.succeeded()) {
|
|
|
+
|
|
|
+ Message<Object> result = reply.result();
|
|
|
+ String source = result.headers().get(MODULE_TYPE);
|
|
|
+
|
|
|
+ if (source == null) {
|
|
|
+ logger.warn("Unknown module type of the address '{}'. The message will not be published.", providerAddress); return;
|
|
|
+ }
|
|
|
+
|
|
|
+ DeliveryOptions pusherOpt = new DeliveryOptions();
|
|
|
+ MultiMap headers = result.headers().addAll(fetcherOpt.getHeaders());
|
|
|
+ for (Map.Entry<String, String> entryHeader : headers.entries()) {
|
|
|
+ if (entryHeader.getKey().startsWith(MessageHeader.getPrefix())) {
|
|
|
+ pusherOpt.addHeader(entryHeader.getKey(), entryHeader.getValue());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ String consumerAddress = createNormalized(SCHEDULER_CONSUMER, source);
|
|
|
+ eventBus.publish(consumerAddress, result.body(), pusherOpt);
|
|
|
+ } else {
|
|
|
+ logger.catching(reply.cause());
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public void run() {
|
|
|
|
|
|
- EventBus eventBus = vertx.eventBus();
|
|
|
+// vertx.setPeriodic(1000, ctx -> { // every minute?
|
|
|
+// // TODO delete all rules after deadLine
|
|
|
+// });
|
|
|
+
|
|
|
for (Map.Entry<String, SchedulerConfig> configEntry : schedulerConfigs.entrySet()) {
|
|
|
String moduleId = configEntry.getKey();
|
|
|
SchedulerConfig config = configEntry.getValue();
|
|
|
-
|
|
|
- if (config != null && config.getPeriodSecond() > 0) {
|
|
|
- long schedulerId = vertx.setPeriodic(config.getPeriodMillisecond(), ctx -> {
|
|
|
- DeliveryOptions fetcherOpt = new DeliveryOptions()
|
|
|
- .addHeader(RESOURCE, SCHEDULER)
|
|
|
- .addHeader(ADDRESS, config.getConsumer());
|
|
|
- String providerAddress = createNormalized(SCHEDULER_PROVIDER, moduleId);
|
|
|
- // TODO instance of new JsonObject(), put config as a json
|
|
|
- eventBus.request(providerAddress, new JsonObject(), fetcherOpt, reply -> {
|
|
|
- if (reply.succeeded()) {
|
|
|
- Message<Object> result = reply.result();
|
|
|
- String source = result.headers().get(MODULE_TYPE);
|
|
|
- DeliveryOptions pusherOpt = new DeliveryOptions();
|
|
|
- MultiMap headers = result.headers().addAll(fetcherOpt.getHeaders());
|
|
|
- for (Map.Entry<String, String> entryHeader : headers.entries()) {
|
|
|
- if (entryHeader.getKey().startsWith(MessageHeader.getPrefix())) {
|
|
|
- pusherOpt.addHeader(entryHeader.getKey(), entryHeader.getValue());
|
|
|
- }
|
|
|
- }
|
|
|
- String consumerAddress = createNormalized(SCHEDULER_CONSUMER, source);
|
|
|
- eventBus.publish(consumerAddress, result.body(), pusherOpt);
|
|
|
- } else {
|
|
|
- logger.catching(reply.cause());
|
|
|
- }
|
|
|
- });
|
|
|
- });
|
|
|
+ long schedulerId = registerNewSchedulingRole(moduleId, config);
|
|
|
+ if (schedulerId >= 0) {
|
|
|
scheduledModules.put(moduleId, schedulerId);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- router().get(create("rules")).handler(BodyHandler.create()).handler(ctx -> {
|
|
|
+ router().get(create("rules")).handler(ctx -> {
|
|
|
JsonArray rules = new JsonArray();
|
|
|
for (Map.Entry<String, Long> entry : scheduledModules.entrySet()) {
|
|
|
+ String moduleId = entry.getKey();
|
|
|
+ Long schedulerId = entry.getValue();
|
|
|
+
|
|
|
+ SchedulerConfig config = schedulerConfigs.get(moduleId);
|
|
|
+
|
|
|
+ JsonObject settings = new JsonObject()
|
|
|
+ .put("consumer", config.getConsumer())
|
|
|
+ .put("period", config.getPeriodSecond());
|
|
|
+ if (!config.getDeadLine().equals(LocalDateTime.MAX)) {
|
|
|
+ settings.put("deadLine", config.getDeadLine());
|
|
|
+ }
|
|
|
+ settings.put("config", config.getConfig());
|
|
|
+
|
|
|
rules.add(new JsonObject()
|
|
|
- .put("id", entry.getValue())
|
|
|
- .put("module", entry.getKey())
|
|
|
- .put("config", new JsonObject())
|
|
|
+ .put("id", schedulerId)
|
|
|
+ .put("module", moduleId)
|
|
|
+ .put("settings", settings)
|
|
|
);
|
|
|
}
|
|
|
- ctx.response().end(rules.encode());
|
|
|
+ ctx.response().putHeader(CONTENT_TYPE, APPLICATION_JSON).end(rules.encode());
|
|
|
+ });
|
|
|
+
|
|
|
+ router().post(create("rule")).handler(BodyHandler.create()).handler(ctx -> {
|
|
|
+ ctx.response().end("added new rule with id");
|
|
|
});
|
|
|
|
|
|
router().delete(create("rule/:id")).handler(ctx -> {
|
|
|
@@ -101,7 +138,22 @@ class VertxScheduler extends Module {
|
|
|
} catch (NumberFormatException e) {
|
|
|
throw new RuntimeException(format("Param '%s' can not be converted to integer.", idString));
|
|
|
}
|
|
|
- ctx.response().end("Deleted rule " + id);
|
|
|
+
|
|
|
+ if (!scheduledModules.containsValue(id)) {
|
|
|
+ throw new RuntimeException(format("Identifier '%s' does not exist.", id));
|
|
|
+ }
|
|
|
+
|
|
|
+ boolean result = vertx.cancelTimer(id);
|
|
|
+
|
|
|
+ if (result) {
|
|
|
+ ctx.response().putHeader(CONTENT_TYPE, APPLICATION_JSON).end(new JsonObject()
|
|
|
+ .put("message", format("Scheduling rule of the ID %s was successfully terminated.", id))
|
|
|
+ .encode());
|
|
|
+ } else {
|
|
|
+ throw new RuntimeException(format(
|
|
|
+ "Scheduling rule of the ID %s was not terminated successfully.", id
|
|
|
+ ));
|
|
|
+ }
|
|
|
});
|
|
|
}
|
|
|
}
|