diff --git a/.idea/.gitignore b/.idea/.gitignore
deleted file mode 100644
index 13566b8..0000000
--- a/.idea/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
-# Editor-based HTTP Client requests
-/httpRequests/
-# Datasource local storage ignored files
-/dataSources/
-/dataSources.local.xml
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
deleted file mode 100644
index 170b576..0000000
--- a/.idea/compiler.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
deleted file mode 100644
index 712ab9d..0000000
--- a/.idea/jarRepositories.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
deleted file mode 100644
index dda4560..0000000
--- a/.idea/misc.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index f261d12..0000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 35eb1dd..0000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.project b/.project
deleted file mode 100644
index d532189..0000000
--- a/.project
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
- ContaminUS
-
-
-
-
-
-
-
-
diff --git a/ContaminUS.iml b/ContaminUS.iml
deleted file mode 100644
index 64f8ad0..0000000
--- a/ContaminUS.iml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/backend/vertx/.classpath b/backend/.classpath
similarity index 100%
rename from backend/vertx/.classpath
rename to backend/.classpath
diff --git a/backend/vertx/.project b/backend/.project
similarity index 100%
rename from backend/vertx/.project
rename to backend/.project
diff --git a/backend/vertx/.settings/org.eclipse.jdt.core.prefs b/backend/.settings/org.eclipse.jdt.core.prefs
similarity index 100%
rename from backend/vertx/.settings/org.eclipse.jdt.core.prefs
rename to backend/.settings/org.eclipse.jdt.core.prefs
diff --git a/backend/vertx/.settings/org.eclipse.m2e.core.prefs b/backend/.settings/org.eclipse.m2e.core.prefs
similarity index 100%
rename from backend/vertx/.settings/org.eclipse.m2e.core.prefs
rename to backend/.settings/org.eclipse.m2e.core.prefs
diff --git a/backend/vertx/pom.xml b/backend/pom.xml
similarity index 100%
rename from backend/vertx/pom.xml
rename to backend/pom.xml
diff --git a/backend/vertx/src/main/java/net/miarma/contaminus/clase/BroadcastVerticle.java b/backend/src/main/java/net/miarma/contaminus/clase/BroadcastVerticle.java
similarity index 100%
rename from backend/vertx/src/main/java/net/miarma/contaminus/clase/BroadcastVerticle.java
rename to backend/src/main/java/net/miarma/contaminus/clase/BroadcastVerticle.java
diff --git a/backend/vertx/src/main/java/net/miarma/contaminus/clase/ConsumerVerticle1.java b/backend/src/main/java/net/miarma/contaminus/clase/ConsumerVerticle1.java
similarity index 100%
rename from backend/vertx/src/main/java/net/miarma/contaminus/clase/ConsumerVerticle1.java
rename to backend/src/main/java/net/miarma/contaminus/clase/ConsumerVerticle1.java
diff --git a/backend/vertx/src/main/java/net/miarma/contaminus/clase/ConsumerVerticle2.java b/backend/src/main/java/net/miarma/contaminus/clase/ConsumerVerticle2.java
similarity index 100%
rename from backend/vertx/src/main/java/net/miarma/contaminus/clase/ConsumerVerticle2.java
rename to backend/src/main/java/net/miarma/contaminus/clase/ConsumerVerticle2.java
diff --git a/backend/vertx/src/main/java/net/miarma/contaminus/clase/MainVerticleClase.java b/backend/src/main/java/net/miarma/contaminus/clase/MainVerticleClase.java
similarity index 100%
rename from backend/vertx/src/main/java/net/miarma/contaminus/clase/MainVerticleClase.java
rename to backend/src/main/java/net/miarma/contaminus/clase/MainVerticleClase.java
diff --git a/backend/vertx/src/main/java/net/miarma/contaminus/common/ConfigManager.java b/backend/src/main/java/net/miarma/contaminus/common/ConfigManager.java
similarity index 100%
rename from backend/vertx/src/main/java/net/miarma/contaminus/common/ConfigManager.java
rename to backend/src/main/java/net/miarma/contaminus/common/ConfigManager.java
diff --git a/backend/src/main/java/net/miarma/contaminus/common/Constants.java b/backend/src/main/java/net/miarma/contaminus/common/Constants.java
new file mode 100644
index 0000000..c003e88
--- /dev/null
+++ b/backend/src/main/java/net/miarma/contaminus/common/Constants.java
@@ -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.");
+ }
+}
diff --git a/backend/vertx/src/main/java/net/miarma/contaminus/common/Host.java b/backend/src/main/java/net/miarma/contaminus/common/Host.java
similarity index 100%
rename from backend/vertx/src/main/java/net/miarma/contaminus/common/Host.java
rename to backend/src/main/java/net/miarma/contaminus/common/Host.java
diff --git a/backend/src/main/java/net/miarma/contaminus/common/LocalDateTimeSerializer.java b/backend/src/main/java/net/miarma/contaminus/common/LocalDateTimeSerializer.java
new file mode 100644
index 0000000..a042151
--- /dev/null
+++ b/backend/src/main/java/net/miarma/contaminus/common/LocalDateTimeSerializer.java
@@ -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, JsonDeserializer {
+
+ 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);
+ }
+
+}
diff --git a/backend/vertx/src/main/java/net/miarma/contaminus/common/OSType.java b/backend/src/main/java/net/miarma/contaminus/common/OSType.java
similarity index 100%
rename from backend/vertx/src/main/java/net/miarma/contaminus/common/OSType.java
rename to backend/src/main/java/net/miarma/contaminus/common/OSType.java
diff --git a/backend/vertx/src/main/java/net/miarma/contaminus/common/SystemInfo.java b/backend/src/main/java/net/miarma/contaminus/common/SystemInfo.java
similarity index 100%
rename from backend/vertx/src/main/java/net/miarma/contaminus/common/SystemInfo.java
rename to backend/src/main/java/net/miarma/contaminus/common/SystemInfo.java
diff --git a/backend/vertx/src/main/java/net/miarma/contaminus/database/DatabaseManager.java b/backend/src/main/java/net/miarma/contaminus/database/DatabaseManager.java
similarity index 100%
rename from backend/vertx/src/main/java/net/miarma/contaminus/database/DatabaseManager.java
rename to backend/src/main/java/net/miarma/contaminus/database/DatabaseManager.java
diff --git a/backend/vertx/src/main/java/net/miarma/contaminus/database/QueryBuilder.java b/backend/src/main/java/net/miarma/contaminus/database/QueryBuilder.java
similarity index 87%
rename from backend/vertx/src/main/java/net/miarma/contaminus/database/QueryBuilder.java
rename to backend/src/main/java/net/miarma/contaminus/database/QueryBuilder.java
index dca117a..3a75c85 100644
--- a/backend/vertx/src/main/java/net/miarma/contaminus/database/QueryBuilder.java
+++ b/backend/src/main/java/net/miarma/contaminus/database/QueryBuilder.java
@@ -42,6 +42,21 @@ public class QueryBuilder {
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) {
@@ -83,7 +98,7 @@ public class QueryBuilder {
limit = limitParam.isPresent() ? "LIMIT " + limitParam.get() + " " : "";
return this;
}
-
+
public String build() {
if (!conditions.isEmpty()) {
query.append("WHERE ");
@@ -104,4 +119,6 @@ public class QueryBuilder {
}
return query.toString().trim() + ";";
}
-}
\ No newline at end of file
+
+
+}
diff --git a/backend/src/main/java/net/miarma/contaminus/server/ApiVerticle.java b/backend/src/main/java/net/miarma/contaminus/server/ApiVerticle.java
new file mode 100644
index 0000000..b7974b5
--- /dev/null
+++ b/backend/src/main/java/net/miarma/contaminus/server/ApiVerticle.java
@@ -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 startPromise) {
+ Constants.LOGGER.info("🟢 Iniciando ApiVerticle...");
+ Router router = Router.router(vertx);
+
+ Set allowedMethods = new HashSet<>(Arrays.asList(HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT)); // Por ejemplo
+ Set 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