Refactored many things and removed unnecessary things like IDEA files and stuff
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
package net.miarma.contaminus.clase;
|
||||
|
||||
import io.vertx.core.AbstractVerticle;
|
||||
import io.vertx.core.Promise;
|
||||
|
||||
public class BroadcastVerticle extends AbstractVerticle {
|
||||
@Override
|
||||
public void start(Promise<Void> promise) {
|
||||
vertx.setPeriodic(2000, _a -> {
|
||||
vertx.eventBus().publish("broadcast.addr", "Ola");
|
||||
});
|
||||
try {
|
||||
promise.complete();
|
||||
} catch (Exception e) {
|
||||
promise.fail(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package net.miarma.contaminus.clase;
|
||||
|
||||
import io.vertx.core.AbstractVerticle;
|
||||
import io.vertx.core.Promise;
|
||||
import io.vertx.core.eventbus.Message;
|
||||
import net.miarma.contaminus.common.Constants;
|
||||
|
||||
public class ConsumerVerticle1 extends AbstractVerticle {
|
||||
@Override
|
||||
public void start(Promise<Void> promise) {
|
||||
vertx.eventBus().consumer("broadcast.addr", this::handleMsg);
|
||||
try {
|
||||
promise.complete();
|
||||
} catch (Exception e) {
|
||||
promise.fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleMsg(Message<String> msg) {
|
||||
Constants.LOGGER.info("Ola Broadcast soy Consumer1");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package net.miarma.contaminus.clase;
|
||||
|
||||
import io.vertx.core.AbstractVerticle;
|
||||
import io.vertx.core.Promise;
|
||||
import io.vertx.core.eventbus.Message;
|
||||
import net.miarma.contaminus.common.Constants;
|
||||
|
||||
public class ConsumerVerticle2 extends AbstractVerticle {
|
||||
@Override
|
||||
public void start(Promise<Void> promise) {
|
||||
vertx.eventBus().consumer("broadcast.addr", this::handleMsg);
|
||||
try {
|
||||
promise.complete();
|
||||
} catch (Exception e) {
|
||||
promise.fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleMsg(Message<String> msg) {
|
||||
Constants.LOGGER.info("Ola Broadcast soy Consumer2");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package net.miarma.contaminus.clase;
|
||||
|
||||
import io.vertx.core.AbstractVerticle;
|
||||
import io.vertx.core.Promise;
|
||||
import net.miarma.contaminus.common.Constants;
|
||||
|
||||
public class MainVerticleClase extends AbstractVerticle {
|
||||
@Override
|
||||
public void start(Promise<Void> promise) {
|
||||
vertx.deployVerticle(new BroadcastVerticle(), result -> {
|
||||
if(result.succeeded()) {
|
||||
Constants.LOGGER.info("📡 BroadcastVerticle desplegado");
|
||||
} else {
|
||||
Constants.LOGGER.error("❌ Error al desplegar BroadcastVerticle", result.cause());
|
||||
}
|
||||
});
|
||||
vertx.deployVerticle(new ConsumerVerticle1(), result -> {
|
||||
if(result.succeeded()) {
|
||||
Constants.LOGGER.info("📡 ConsumerVerticle1 desplegado");
|
||||
} else {
|
||||
Constants.LOGGER.error("❌ Error al desplegar ConsumerVerticle1", result.cause());
|
||||
}
|
||||
});
|
||||
vertx.deployVerticle(new ConsumerVerticle2(), result -> {
|
||||
if(result.succeeded()) {
|
||||
Constants.LOGGER.info("📡 ConsumerVerticle2 desplegado");
|
||||
} else {
|
||||
Constants.LOGGER.error("❌ Error al desplegar ConsumerVerticle2", result.cause());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package net.miarma.contaminus.common;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Properties;
|
||||
|
||||
public class ConfigManager {
|
||||
private static ConfigManager instance;
|
||||
private final File configFile;
|
||||
private final Properties config;
|
||||
|
||||
private ConfigManager() {
|
||||
this.configFile = new File(Constants.CONFIG_FILE);
|
||||
this.config = new Properties();
|
||||
|
||||
if (!configFile.exists()) {
|
||||
try {
|
||||
createFiles();
|
||||
} catch (IOException e) {
|
||||
Constants.LOGGER.error("Error creating configuration files: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
loadConfig();
|
||||
}
|
||||
|
||||
public static synchronized ConfigManager getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new ConfigManager();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
private void createFiles() throws IOException {
|
||||
File baseDir = new File(Constants.BASE_DIR);
|
||||
if (!baseDir.exists()) baseDir.mkdirs();
|
||||
|
||||
try (InputStream defaultConfigStream = getClass().getClassLoader().getResourceAsStream("default.properties");
|
||||
FileOutputStream fos = new FileOutputStream(configFile)) {
|
||||
|
||||
if (defaultConfigStream != null) {
|
||||
byte[] buffer = new byte[1024];
|
||||
int bytesRead;
|
||||
while ((bytesRead = defaultConfigStream.read(buffer)) != -1) {
|
||||
fos.write(buffer, 0, bytesRead);
|
||||
}
|
||||
} else {
|
||||
Constants.LOGGER.error("File not found: default.properties");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void loadConfig() {
|
||||
try (FileInputStream fis = new FileInputStream(configFile)) {
|
||||
config.load(fis);
|
||||
} catch (IOException e) {
|
||||
Constants.LOGGER.error("Error loading configuration file: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
public String getStringProperty(String key) {
|
||||
return config.getProperty(key);
|
||||
}
|
||||
|
||||
public int getIntProperty(String key) {
|
||||
return Integer.parseInt(config.getProperty(key));
|
||||
}
|
||||
|
||||
public boolean getBooleanProperty(String key) {
|
||||
return Boolean.parseBoolean(config.getProperty(key));
|
||||
}
|
||||
|
||||
public void setProperty(String key, String value) {
|
||||
config.setProperty(key, value);
|
||||
saveConfig();
|
||||
}
|
||||
|
||||
private void saveConfig() {
|
||||
try (FileOutputStream fos = new FileOutputStream(configFile)) {
|
||||
config.store(fos, "Configuration for: " + Constants.APP_NAME);
|
||||
} catch (IOException e) {
|
||||
Constants.LOGGER.error("Error saving configuration file: ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package net.miarma.contaminus.common;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import io.vertx.core.impl.logging.Logger;
|
||||
import io.vertx.core.impl.logging.LoggerFactory;
|
||||
|
||||
public class Constants {
|
||||
public static final String APP_NAME = "ContaminUS";
|
||||
public static final String API_PREFIX = "/api/v1";
|
||||
public static final String HOME_DIR = System.getProperty("user.home") + File.separator;
|
||||
public static final String BASE_DIR = HOME_DIR +
|
||||
(SystemInfo.getOS() == OSType.WINDOWS ? ".contaminus" :
|
||||
SystemInfo.getOS() == OSType.LINUX ? ".config" + File.separator +
|
||||
"contaminus" : null);
|
||||
public static final String CONFIG_FILE = BASE_DIR + File.separator + "config.properties";
|
||||
public static final Logger LOGGER = LoggerFactory.getLogger(APP_NAME);
|
||||
|
||||
public static final String GET_GROUPS = API_PREFIX + "/groups";
|
||||
public static final String GET_GROUP_BY_ID = API_PREFIX + "/groups/:groupId";
|
||||
public static final String GET_GROUP_DEVICES = API_PREFIX + "/groups/:groupId/devices";
|
||||
public static final String POST_GROUPS = API_PREFIX + "/groups";
|
||||
public static final String PUT_GROUP_BY_ID = API_PREFIX + "/groups/:groupId";
|
||||
|
||||
public static final String GET_DEVICES = API_PREFIX + "/devices";
|
||||
public static final String GET_DEVICE_BY_ID = API_PREFIX + "/devices/:deviceId";
|
||||
public static final String GET_DEVICE_SENSORS = API_PREFIX + "/devices/:deviceId/sensors";
|
||||
public static final String POST_DEVICES = API_PREFIX + "/devices";
|
||||
public static final String PUT_DEVICE_BY_ID = API_PREFIX + "/devices/:deviceId";
|
||||
|
||||
public static final String GET_SENSORS = API_PREFIX + "/sensors";
|
||||
public static final String GET_SENSOR_BY_ID = API_PREFIX + "/sensors/:sensorId";
|
||||
public static final String GET_SENSOR_VALUES = API_PREFIX + "/sensors/:sensorId/values";
|
||||
public static final String POST_SENSORS = API_PREFIX + "/sensors";
|
||||
public static final String PUT_SENSOR_BY_ID = API_PREFIX + "/sensors/:sensorId";
|
||||
|
||||
public static final String GET_ACTUATORS = API_PREFIX + "/actuators";
|
||||
public static final String GET_ACTUATOR_BY_ID = API_PREFIX + "/actuators/:actuatorId";
|
||||
public static final String POST_ACTUATORS = API_PREFIX + "/actuators";
|
||||
public static final String PUT_ACTUATOR_BY_ID = API_PREFIX + "/actuators/:actuatorId";
|
||||
|
||||
public static final String GET_GPS_VALUES = API_PREFIX + "/gps-values";
|
||||
public static final String GET_GPS_VALUE_BY_ID = API_PREFIX + "/gps-values/:valueId";
|
||||
public static final String POST_GPS_VALUES = API_PREFIX + "/gps-values";
|
||||
|
||||
public static final String GET_AIR_VALUES = API_PREFIX + "/air-values";
|
||||
public static final String GET_AIR_VALUE_BY_ID = API_PREFIX + "/air-values/:valueId";
|
||||
public static final String POST_AIR_VALUES = API_PREFIX + "/air-values";
|
||||
|
||||
private Constants() {
|
||||
throw new AssertionError("Utility class cannot be instantiated.");
|
||||
}
|
||||
}
|
||||
25
backend/src/main/java/net/miarma/contaminus/common/Host.java
Normal file
25
backend/src/main/java/net/miarma/contaminus/common/Host.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package net.miarma.contaminus.common;
|
||||
|
||||
public class Host {
|
||||
static ConfigManager configManager = ConfigManager.getInstance();
|
||||
static String host = configManager.getStringProperty("inet.host");
|
||||
static int apiPort = configManager.getIntProperty("api.port");
|
||||
static int webserverPort = configManager.getIntProperty("webserver.port");
|
||||
|
||||
public static String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public static int getApiPort() {
|
||||
return apiPort;
|
||||
}
|
||||
|
||||
public static int getWebserverPort() {
|
||||
return webserverPort;
|
||||
}
|
||||
|
||||
public static String getOrigin() {
|
||||
return "http://" + host + ":" + webserverPort;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package net.miarma.contaminus.common;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
|
||||
public class LocalDateTimeSerializer implements JsonSerializer<LocalDateTime>, JsonDeserializer<LocalDateTime> {
|
||||
|
||||
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(LocalDateTime src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
return new JsonPrimitive(src.format(FORMATTER));
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
return LocalDateTime.parse(json.getAsString(), FORMATTER);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package net.miarma.contaminus.common;
|
||||
|
||||
public enum OSType {
|
||||
LINUX, WINDOWS, INVALID_OS;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package net.miarma.contaminus.common;
|
||||
|
||||
public class SystemInfo {
|
||||
public static OSType getOS() {
|
||||
String envProperty = System.getProperty("os.name").toLowerCase();
|
||||
if(envProperty.contains("windows")) {
|
||||
return OSType.WINDOWS;
|
||||
} else if(envProperty.contains("linux")) {
|
||||
return OSType.LINUX;
|
||||
} else {
|
||||
return OSType.INVALID_OS;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package net.miarma.contaminus.database;
|
||||
|
||||
import io.vertx.core.Vertx;
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import io.vertx.jdbcclient.JDBCPool;
|
||||
import net.miarma.contaminus.common.ConfigManager;
|
||||
|
||||
public class DatabaseManager {
|
||||
private final JDBCPool pool;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public DatabaseManager(Vertx vertx) {
|
||||
ConfigManager config = ConfigManager.getInstance();
|
||||
|
||||
JsonObject dbConfig = new JsonObject()
|
||||
.put("url", config.getStringProperty("db.protocol") + "//" +
|
||||
config.getStringProperty("db.host") + ":" +
|
||||
config.getStringProperty("db.port") + "/" +
|
||||
config.getStringProperty("db.name"))
|
||||
.put("user", config.getStringProperty("db.user"))
|
||||
.put("password", config.getStringProperty("db.pwd"))
|
||||
.put("max_pool_size", config.getStringProperty("db.poolSize"));
|
||||
|
||||
pool = JDBCPool.pool(vertx, dbConfig);
|
||||
}
|
||||
|
||||
public JDBCPool getPool() {
|
||||
return pool;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
package net.miarma.contaminus.database;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
public class QueryBuilder {
|
||||
private StringBuilder query;
|
||||
private List<String> conditions;
|
||||
private String sort;
|
||||
private String order;
|
||||
private String limit;
|
||||
|
||||
public QueryBuilder() {
|
||||
this.query = new StringBuilder();
|
||||
this.conditions = new ArrayList<>();
|
||||
}
|
||||
|
||||
public static QueryBuilder select(String... columns) {
|
||||
QueryBuilder qb = new QueryBuilder();
|
||||
StringJoiner joiner = new StringJoiner(", ");
|
||||
for (String column : columns) {
|
||||
joiner.add(column);
|
||||
}
|
||||
qb.query.append("SELECT ").append(joiner).append(" ");
|
||||
return qb;
|
||||
}
|
||||
|
||||
public static QueryBuilder insert(String table, String... columns) {
|
||||
QueryBuilder qb = new QueryBuilder();
|
||||
StringJoiner joiner = new StringJoiner(", ");
|
||||
if (columns.length > 0) {
|
||||
for (String column : columns) {
|
||||
joiner.add(column);
|
||||
}
|
||||
qb.query.append("INSERT INTO ").append(table).append(" (").append(joiner).append(") ");
|
||||
} else {
|
||||
qb.query.append("INSERT INTO ").append(table).append(" ");
|
||||
}
|
||||
|
||||
return qb;
|
||||
}
|
||||
|
||||
public static QueryBuilder update(String table) {
|
||||
QueryBuilder qb = new QueryBuilder();
|
||||
qb.query.append("UPDATE ").append(table).append(" ");
|
||||
return qb;
|
||||
}
|
||||
|
||||
public QueryBuilder set(String column, Object value) {
|
||||
if(value instanceof String) {
|
||||
query.append("SET ").append(column).append(" = '").append(value).append("' ");
|
||||
} else {
|
||||
query.append("SET ").append(column).append(" = ").append(value).append(" ");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryBuilder values(Object... values) {
|
||||
StringJoiner joiner = new StringJoiner(", ", "VALUES (", ")");
|
||||
for (Object value : values) {
|
||||
if(value instanceof String) {
|
||||
joiner.add("'" + value + "'");
|
||||
} else if(value == null) {
|
||||
joiner.add("NULL");
|
||||
}
|
||||
else {
|
||||
joiner.add(value.toString());
|
||||
}
|
||||
}
|
||||
this.query.append(joiner).append(" ");
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryBuilder from(String table) {
|
||||
query.append("FROM ").append(table).append(" ");
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryBuilder where(String conditionsString, Object... values) {
|
||||
conditionsString = conditionsString.replaceAll("\\?", "%s");
|
||||
conditions.add(String.format(conditionsString, values));
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryBuilder orderBy(Optional<String> column, Optional<String> order) {
|
||||
if (column.isPresent()) {
|
||||
sort = "ORDER BY " + column.get() + " ";
|
||||
if (order.isPresent()) {
|
||||
sort += order.get().equalsIgnoreCase("asc") ? "ASC" : "DESC" + " ";
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryBuilder limit(Optional<Integer> limitParam) {
|
||||
limit = limitParam.isPresent() ? "LIMIT " + limitParam.get() + " " : "";
|
||||
return this;
|
||||
}
|
||||
|
||||
public String build() {
|
||||
if (!conditions.isEmpty()) {
|
||||
query.append("WHERE ");
|
||||
StringJoiner joiner = new StringJoiner(" AND ");
|
||||
for (String condition : conditions) {
|
||||
joiner.add(condition);
|
||||
}
|
||||
query.append(joiner).append(" ");
|
||||
}
|
||||
if (order != null && !order.isEmpty()) {
|
||||
query.append(order);
|
||||
}
|
||||
if (sort != null && !sort.isEmpty()) {
|
||||
query.append(sort);
|
||||
}
|
||||
if (limit != null && !limit.isEmpty()) {
|
||||
query.append(limit);
|
||||
}
|
||||
return query.toString().trim() + ";";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,359 @@
|
||||
package net.miarma.contaminus.server;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import io.vertx.core.AbstractVerticle;
|
||||
import io.vertx.core.Promise;
|
||||
import io.vertx.core.eventbus.Message;
|
||||
import io.vertx.core.http.HttpMethod;
|
||||
import io.vertx.core.json.JsonArray;
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import io.vertx.ext.web.Router;
|
||||
import io.vertx.ext.web.RoutingContext;
|
||||
import io.vertx.ext.web.handler.BodyHandler;
|
||||
import io.vertx.ext.web.handler.CorsHandler;
|
||||
import net.miarma.contaminus.common.Constants;
|
||||
import net.miarma.contaminus.common.Host;
|
||||
import net.miarma.contaminus.database.QueryBuilder;
|
||||
|
||||
public class ApiVerticle extends AbstractVerticle {
|
||||
|
||||
@Override
|
||||
public void start(Promise<Void> startPromise) {
|
||||
Constants.LOGGER.info("🟢 Iniciando ApiVerticle...");
|
||||
Router router = Router.router(vertx);
|
||||
|
||||
Set<HttpMethod> allowedMethods = new HashSet<>(Arrays.asList(HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT)); // Por ejemplo
|
||||
Set<String> allowedHeaders = new HashSet<>(Arrays.asList("Content-Type", "Authorization"));
|
||||
|
||||
router.route().handler(CorsHandler.create()
|
||||
.addOrigin(Host.getOrigin())
|
||||
.allowCredentials(true)
|
||||
.allowedHeaders(allowedHeaders)
|
||||
.allowedMethods(allowedMethods));
|
||||
router.route().handler(BodyHandler.create());
|
||||
|
||||
// Group Routes
|
||||
router.route(HttpMethod.GET, Constants.GET_GROUPS).handler(this::getGroupsHandler);
|
||||
router.route(HttpMethod.GET, Constants.GET_GROUP_BY_ID).handler(this::getGroupByIdHandler);
|
||||
router.route(HttpMethod.GET, Constants.GET_GROUP_DEVICES).handler(this::getGroupDevicesHandler);
|
||||
router.route(HttpMethod.POST, Constants.POST_GROUPS).handler(this::postGroupHandler);
|
||||
router.route(HttpMethod.PUT, Constants.PUT_GROUP_BY_ID).handler(this::putGroupByIdHandler);
|
||||
|
||||
// Device Routes
|
||||
router.route(HttpMethod.GET, Constants.GET_DEVICES).handler(this::getDevicesHandler);
|
||||
router.route(HttpMethod.GET, Constants.GET_DEVICE_BY_ID).handler(this::getDeviceByIdHandler);
|
||||
router.route(HttpMethod.GET, Constants.GET_DEVICE_SENSORS).handler(this::getDeviceSensorsHandler);
|
||||
router.route(HttpMethod.POST, Constants.POST_DEVICES).handler(this::postDeviceHandler);
|
||||
router.route(HttpMethod.PUT, Constants.PUT_DEVICE_BY_ID).handler(this::putDeviceByIdHandler);
|
||||
|
||||
// Sensor Routes
|
||||
router.route(HttpMethod.GET, Constants.GET_SENSORS).handler(this::getSensorsHandler);
|
||||
router.route(HttpMethod.GET, Constants.GET_SENSOR_BY_ID).handler(this::getSensorByIdHandler);
|
||||
router.route(HttpMethod.GET, Constants.GET_SENSOR_VALUES).handler(this::getSensorValuesHandler);
|
||||
router.route(HttpMethod.POST, Constants.POST_SENSORS).handler(this::postSensorHandler);
|
||||
router.route(HttpMethod.PUT, Constants.PUT_SENSOR_BY_ID).handler(this::putSensorByIdHandler);
|
||||
|
||||
// Actuator Routes
|
||||
router.route(HttpMethod.GET, Constants.GET_ACTUATORS).handler(this::getActuatorsHandler);
|
||||
router.route(HttpMethod.GET, Constants.GET_ACTUATOR_BY_ID).handler(this::getActuatorByIdHandler);
|
||||
router.route(HttpMethod.POST, Constants.POST_ACTUATORS).handler(this::postActuatorHandler);
|
||||
router.route(HttpMethod.PUT, Constants.PUT_ACTUATOR_BY_ID).handler(this::putActuatorByIdHandler);
|
||||
|
||||
vertx.createHttpServer()
|
||||
.requestHandler(router)
|
||||
.listen(
|
||||
Host.getApiPort(),
|
||||
Host.getHost(),
|
||||
result -> {
|
||||
if (result.succeeded()) {
|
||||
Constants.LOGGER.info(String.format(
|
||||
"📡 ApiVerticle desplegado. (http://%s:%d)", Host.getHost(), Host.getApiPort()
|
||||
));
|
||||
startPromise.complete();
|
||||
} else {
|
||||
Constants.LOGGER.error("❌ Error al desplegar ApiVerticle", result.cause());
|
||||
startPromise.fail(result.cause());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void sendQuery(String query, RoutingContext context) {
|
||||
vertx.eventBus().request("db.query", query, req -> {
|
||||
if (req.succeeded()) {
|
||||
Message<Object> msg = req.result();
|
||||
JsonArray jsonArray = new JsonArray(msg.body().toString());
|
||||
context.json(jsonArray);
|
||||
} else {
|
||||
context.fail(500, req.cause());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Group Handlers
|
||||
private void getGroupsHandler(RoutingContext context) {
|
||||
String query = QueryBuilder.select("*").from("groups").build();
|
||||
sendQuery(query, context);
|
||||
}
|
||||
|
||||
private void getGroupByIdHandler(RoutingContext context) {
|
||||
String groupId = context.request().getParam("groupId");
|
||||
String query = QueryBuilder
|
||||
.select("*")
|
||||
.from("groups")
|
||||
.where("groupId = ?", groupId)
|
||||
.build();
|
||||
sendQuery(query, context);
|
||||
}
|
||||
|
||||
private void getGroupDevicesHandler(RoutingContext context) {
|
||||
String groupId = context.request().getParam("groupId");
|
||||
String query = QueryBuilder
|
||||
.select("*")
|
||||
.from("devices")
|
||||
.where("groupId = ?", groupId)
|
||||
.build();
|
||||
sendQuery(query, context);
|
||||
}
|
||||
|
||||
private void postGroupHandler(RoutingContext context) {
|
||||
JsonObject body = context.body().asJsonObject();
|
||||
|
||||
if(body == null) {
|
||||
context.fail(400, new IllegalArgumentException("Bad request"));
|
||||
return;
|
||||
}
|
||||
|
||||
String groupName = body.getString("groupName");
|
||||
|
||||
String query = QueryBuilder
|
||||
.insert("groups", "groupName")
|
||||
.values(groupName)
|
||||
.build();
|
||||
|
||||
sendQuery(query, context);
|
||||
}
|
||||
|
||||
private void putGroupByIdHandler(RoutingContext context) {
|
||||
String groupId = context.request().getParam("groupId");
|
||||
JsonObject body = context.body().asJsonObject();
|
||||
|
||||
if(body == null) {
|
||||
context.fail(400, new IllegalArgumentException("Bad request"));
|
||||
return;
|
||||
}
|
||||
|
||||
String groupName = body.getString("groupName");
|
||||
|
||||
String query = QueryBuilder
|
||||
.update("groups")
|
||||
.set("groupName", groupName)
|
||||
.where("groupId = ?", groupId)
|
||||
.build();
|
||||
|
||||
sendQuery(query, context);
|
||||
}
|
||||
|
||||
// Device Handlers
|
||||
private void getDevicesHandler(RoutingContext context) {
|
||||
String query = QueryBuilder.select("*").from("devices").build();
|
||||
sendQuery(query, context);
|
||||
}
|
||||
|
||||
private void getDeviceByIdHandler(RoutingContext context) {
|
||||
String deviceId = context.request().getParam("deviceId");
|
||||
String query = QueryBuilder
|
||||
.select("*")
|
||||
.from("devices")
|
||||
.where("deviceId = ?", deviceId)
|
||||
.build();
|
||||
sendQuery(query, context);
|
||||
}
|
||||
|
||||
private void getDeviceSensorsHandler(RoutingContext context) {
|
||||
String deviceId = context.request().getParam("deviceId");
|
||||
String query = QueryBuilder
|
||||
.select("*")
|
||||
.from("sensors")
|
||||
.where("deviceId = ?", deviceId)
|
||||
.build();
|
||||
sendQuery(query, context);
|
||||
}
|
||||
|
||||
private void postDeviceHandler(RoutingContext context) {
|
||||
JsonObject body = context.body().asJsonObject();
|
||||
|
||||
if(body == null) {
|
||||
context.fail(400, new IllegalArgumentException("Bad request"));
|
||||
return;
|
||||
}
|
||||
|
||||
Integer groupId = body.getInteger("groupId");
|
||||
String deviceName = body.getString("groupName");
|
||||
|
||||
String query = QueryBuilder
|
||||
.insert("devices", "groupId", "deviceName")
|
||||
.values(groupId, deviceName)
|
||||
.build();
|
||||
|
||||
sendQuery(query, context);
|
||||
}
|
||||
|
||||
private void putDeviceByIdHandler(RoutingContext context) {
|
||||
String deviceId = context.request().getParam("deviceId");
|
||||
JsonObject body = context.body().asJsonObject();
|
||||
|
||||
if(body == null) {
|
||||
context.fail(400, new IllegalArgumentException("Bad request"));
|
||||
return;
|
||||
}
|
||||
|
||||
Integer groupId = body.getInteger("groupId");
|
||||
String deviceName = body.getString("deviceName");
|
||||
|
||||
String query = QueryBuilder
|
||||
.update("devices")
|
||||
.set("groupId", groupId)
|
||||
.set("deviceName", deviceName)
|
||||
.where("deviceId = ?", deviceId)
|
||||
.build();
|
||||
|
||||
sendQuery(query, context);
|
||||
}
|
||||
|
||||
// Sensor Handlers
|
||||
private void getSensorsHandler(RoutingContext context) {
|
||||
String query = QueryBuilder.select("*").from("sensors").build();
|
||||
sendQuery(query, context);
|
||||
}
|
||||
|
||||
private void getSensorByIdHandler(RoutingContext context) {
|
||||
String sensorId = context.request().getParam("sensorId");
|
||||
String query = QueryBuilder
|
||||
.select("*")
|
||||
.from("sensors")
|
||||
.where("sensorId = ?", sensorId)
|
||||
.build();
|
||||
sendQuery(query, context);
|
||||
}
|
||||
|
||||
private void getSensorValuesHandler(RoutingContext context) {
|
||||
String sensorId = context.request().getParam("sensorId");
|
||||
String query = QueryBuilder
|
||||
.select("*")
|
||||
.from("v_sensor_values")
|
||||
.where("sensorId = ?", sensorId)
|
||||
.build();
|
||||
sendQuery(query, context);
|
||||
}
|
||||
|
||||
private void postSensorHandler(RoutingContext context) {
|
||||
JsonObject body = context.body().asJsonObject();
|
||||
|
||||
if(body == null) {
|
||||
context.fail(400, new IllegalArgumentException("Bad request"));
|
||||
return;
|
||||
}
|
||||
|
||||
Integer deviceId = body.getInteger("deviceId");
|
||||
String sensorType = body.getString("sensorType");
|
||||
String unit = body.getString("unit");
|
||||
Integer status = body.getInteger("status");
|
||||
|
||||
String query = QueryBuilder
|
||||
.insert("sensors", "deviceId", "sensorType", "unit", "status")
|
||||
.values(deviceId, sensorType, unit, status)
|
||||
.build();
|
||||
|
||||
sendQuery(query, context);
|
||||
}
|
||||
|
||||
private void putSensorByIdHandler(RoutingContext context) {
|
||||
String sensorId = context.request().getParam("sensorId");
|
||||
JsonObject body = context.body().asJsonObject();
|
||||
|
||||
if(body == null) {
|
||||
context.fail(400, new IllegalArgumentException("Bad request"));
|
||||
return;
|
||||
}
|
||||
|
||||
Integer deviceId = body.getInteger("deviceId");
|
||||
String sensorType = body.getString("sensorType");
|
||||
String unit = body.getString("unit");
|
||||
Integer status = body.getInteger("status");
|
||||
|
||||
String query = QueryBuilder
|
||||
.update("sensors")
|
||||
.set("deviceId", deviceId)
|
||||
.set("sensorType", sensorType)
|
||||
.set("unit", unit)
|
||||
.set("status", status)
|
||||
.where("sensorId = ?", sensorId)
|
||||
.build();
|
||||
|
||||
sendQuery(query, context);
|
||||
}
|
||||
|
||||
// Actuator Handlers
|
||||
private void getActuatorsHandler(RoutingContext context) {
|
||||
String query = QueryBuilder.select("*").from("actuators").build();
|
||||
sendQuery(query, context);
|
||||
}
|
||||
|
||||
private void getActuatorByIdHandler(RoutingContext context) {
|
||||
String actuatorId = context.request().getParam("actuatorId");
|
||||
|
||||
String query = QueryBuilder
|
||||
.select("*")
|
||||
.from("actuators")
|
||||
.where("actuatorId = ?", actuatorId)
|
||||
.build();
|
||||
|
||||
sendQuery(query, context);
|
||||
}
|
||||
|
||||
private void postActuatorHandler(RoutingContext context) {
|
||||
JsonObject body = context.body().asJsonObject();
|
||||
|
||||
if(body == null) {
|
||||
context.fail(400, new IllegalArgumentException("Bad request"));
|
||||
return;
|
||||
}
|
||||
|
||||
Integer deviceId = body.getInteger("deviceId");
|
||||
Integer status = body.getInteger("status");
|
||||
|
||||
String query = QueryBuilder
|
||||
.insert("actuators", "deviceId", "status")
|
||||
.values(deviceId, status)
|
||||
.build();
|
||||
|
||||
sendQuery(query, context);
|
||||
}
|
||||
|
||||
private void putActuatorByIdHandler(RoutingContext context) {
|
||||
String actuatorId = context.request().getParam("actuatorId");
|
||||
JsonObject body = context.body().asJsonObject();
|
||||
|
||||
if(body == null) {
|
||||
context.fail(400, new IllegalArgumentException("Bad request"));
|
||||
return;
|
||||
}
|
||||
|
||||
Integer deviceId = body.getInteger("deviceId");
|
||||
Integer status = body.getInteger("status");
|
||||
|
||||
String query = QueryBuilder
|
||||
.update("actuators")
|
||||
.set("deviceId", deviceId)
|
||||
.set("status", status)
|
||||
.where("actuatorId = ?", actuatorId)
|
||||
.build();
|
||||
|
||||
sendQuery(query, context);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
package net.miarma.contaminus.server;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
import io.vertx.core.AbstractVerticle;
|
||||
import io.vertx.core.Promise;
|
||||
import io.vertx.core.eventbus.EventBus;
|
||||
import io.vertx.core.eventbus.Message;
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import io.vertx.jdbcclient.JDBCPool;
|
||||
import io.vertx.sqlclient.Row;
|
||||
import net.miarma.contaminus.common.Constants;
|
||||
import net.miarma.contaminus.common.LocalDateTimeSerializer;
|
||||
import net.miarma.contaminus.database.DatabaseManager;
|
||||
|
||||
public class DatabaseVerticle extends AbstractVerticle {
|
||||
private JDBCPool pool;
|
||||
private EventBus eventBus;
|
||||
private Gson gson = new GsonBuilder()
|
||||
.registerTypeAdapter(LocalDateTime.class, new LocalDateTimeSerializer())
|
||||
.create();;
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Override
|
||||
public void start(Promise<Void> startPromise) {
|
||||
Constants.LOGGER.info("🟢 Iniciando DatabaseVerticle...");
|
||||
|
||||
DatabaseManager dbManager = new DatabaseManager(vertx);
|
||||
pool = dbManager.getPool();
|
||||
eventBus = vertx.eventBus();
|
||||
|
||||
pool.query("SELECT 1")
|
||||
.execute()
|
||||
.onSuccess(_res -> {
|
||||
Constants.LOGGER.info("✅ Database connection ok");
|
||||
Constants.LOGGER.info("📡 DatabaseVerticle desplegado");
|
||||
startPromise.complete();
|
||||
})
|
||||
.onFailure(err -> {
|
||||
Constants.LOGGER.error("❌ Database connection failed");
|
||||
Constants.LOGGER.error("❌ Error al desplegar DatabaseVerticle", err);
|
||||
startPromise.fail(err);
|
||||
});
|
||||
|
||||
eventBus.consumer("db.query", this::handleDatabaseQuery);
|
||||
}
|
||||
|
||||
private void handleDatabaseQuery(Message<String> msg) {
|
||||
String query = msg.body();
|
||||
Constants.LOGGER.info("📥 Query: " + query);
|
||||
|
||||
if(query == null || query.isEmpty()) {
|
||||
msg.fail(400, "Empty query");
|
||||
return;
|
||||
}
|
||||
|
||||
if(query.startsWith("SELECT")) {
|
||||
handleSelectQuery(query, msg);
|
||||
} else if(query.startsWith("INSERT")) {
|
||||
handleInsertQuery(query, msg);
|
||||
} else if(query.startsWith("UPDATE")) {
|
||||
handleUpdateQuery(query, msg);
|
||||
} else {
|
||||
msg.fail(400, "Invalid operation");
|
||||
}
|
||||
}
|
||||
|
||||
private void handleSelectQuery(String query, Message<String> msg) {
|
||||
pool.query(query).execute()
|
||||
.onSuccess(res -> {
|
||||
List<Map<String, Object>> rowsList = new ArrayList<>();
|
||||
|
||||
for (Row row : res) {
|
||||
Map<String, Object> rowMap = new HashMap<>();
|
||||
for (int i = 0; i < row.size(); i++) {
|
||||
String columnName = res.columnsNames().get(i);
|
||||
Object columnValue = row.getValue(i);
|
||||
rowMap.put(columnName, columnValue);
|
||||
}
|
||||
rowsList.add(rowMap);
|
||||
}
|
||||
|
||||
String jsonResponse = gson.toJson(rowsList);
|
||||
msg.reply(jsonResponse);
|
||||
})
|
||||
.onFailure(err -> msg.fail(500, err.getMessage()));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private void handleInsertQuery(String query, Message<String> msg) {
|
||||
pool.query(query).execute()
|
||||
.onSuccess(_res -> {
|
||||
JsonObject response = new JsonObject();
|
||||
response.put("status", "success");
|
||||
String jsonResponse = gson.toJson(response);
|
||||
msg.reply(jsonResponse);
|
||||
})
|
||||
.onFailure(err -> msg.fail(500, err.getMessage()));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private void handleUpdateQuery(String query, Message<String> msg) {
|
||||
pool.query(query).execute()
|
||||
.onSuccess(_res -> {
|
||||
JsonObject response = new JsonObject();
|
||||
response.put("status", "updated");
|
||||
String jsonResponse = gson.toJson(response);
|
||||
msg.reply(jsonResponse);
|
||||
})
|
||||
.onFailure(err -> msg.fail(500, err.getMessage()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package net.miarma.contaminus.server;
|
||||
|
||||
import io.vertx.core.AbstractVerticle;
|
||||
import io.vertx.ext.web.Router;
|
||||
import io.vertx.ext.web.handler.StaticHandler;
|
||||
import net.miarma.contaminus.common.Constants;
|
||||
import net.miarma.contaminus.common.Host;
|
||||
|
||||
public class HttpServerVerticle extends AbstractVerticle {
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
Constants.LOGGER.info("🟢 Iniciando HttpServerVerticle...");
|
||||
Router router = Router.router(vertx);
|
||||
router.route("/*").handler(StaticHandler.create("webroot").setDefaultContentEncoding("UTF-8"));
|
||||
|
||||
vertx.createHttpServer().requestHandler(router).listen(
|
||||
Host.getWebserverPort(), Host.getHost(), result -> {
|
||||
if (result.succeeded()) {
|
||||
Constants.LOGGER.info(String.format("📡 HttpServerVerticle desplegado. (http://%s:%d)",
|
||||
Host.getHost(), Host.getWebserverPort())
|
||||
);
|
||||
} else {
|
||||
Constants.LOGGER.error("❌ Error al desplegar HttpServerVerticle", result.cause());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package net.miarma.contaminus.server;
|
||||
|
||||
import io.vertx.core.AbstractVerticle;
|
||||
import io.vertx.core.DeploymentOptions;
|
||||
import io.vertx.core.Promise;
|
||||
import io.vertx.core.ThreadingModel;
|
||||
|
||||
public class MainVerticle extends AbstractVerticle {
|
||||
|
||||
@Override
|
||||
public void start(Promise<Void> startPromise) {
|
||||
final DeploymentOptions options = new DeploymentOptions();
|
||||
options.setThreadingModel(ThreadingModel.WORKER);
|
||||
|
||||
getVertx().deployVerticle(new DatabaseVerticle(), options);
|
||||
getVertx().deployVerticle(new ApiVerticle(), options);
|
||||
getVertx().deployVerticle(new HttpServerVerticle());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop(Promise<Void> stopPromise) throws Exception {
|
||||
getVertx().deploymentIDs()
|
||||
.forEach(v -> getVertx().undeploy(v));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package net.miarma.contaminus.server;
|
||||
|
||||
import io.vertx.core.AbstractVerticle;
|
||||
|
||||
public class MqttVerticle extends AbstractVerticle {
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user