diff --git a/backend/pom.xml b/backend/pom.xml
index 848550d..fec773d 100644
--- a/backend/pom.xml
+++ b/backend/pom.xml
@@ -55,6 +55,13 @@
2.12.1
+
+
+ org.jboss.logmanager
+ jboss-logmanager
+ 3.1.1.Final
+
+
diff --git a/backend/src/main/java/net/miarma/contaminus/common/ConfigManager.java b/backend/src/main/java/net/miarma/contaminus/common/ConfigManager.java
index 98086bf..8277c21 100644
--- a/backend/src/main/java/net/miarma/contaminus/common/ConfigManager.java
+++ b/backend/src/main/java/net/miarma/contaminus/common/ConfigManager.java
@@ -4,49 +4,20 @@ import java.io.*;
import java.util.Properties;
public class ConfigManager {
- private static ConfigManager instance;
+ private static final ConfigManager INSTANCE = new ConfigManager();
private final File configFile;
private final Properties config;
+ private static final String CONFIG_FILE_NAME = "config.properties";
private ConfigManager() {
- this.configFile = new File(Constants.CONFIG_FILE);
+ String path = getBaseDir() + CONFIG_FILE_NAME;
+ this.configFile = new File(path);
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");
- }
- }
+ public static ConfigManager getInstance() {
+ return INSTANCE;
}
private void loadConfig() {
@@ -56,17 +27,71 @@ public class ConfigManager {
Constants.LOGGER.error("Error loading configuration file: ", e);
}
}
+
+ public File getConfigFile() {
+ return configFile;
+ }
+ public String getJdbcUrl() {
+ return String.format("%s://%s:%s/%s",
+ config.getProperty("db.protocol"),
+ config.getProperty("db.host"),
+ config.getProperty("db.port"),
+ config.getProperty("db.name"));
+ }
+
+ public String getHost() {
+ return this.getStringProperty("inet.host");
+ }
+
+ public int getDataApiPort() {
+ return this.getIntProperty("data-api.port");
+ }
+
+ public int getLogicApiPort() {
+ return this.getIntProperty("logic-api.port");
+ }
+
+ public int getWebserverPort() {
+ return this.getIntProperty("webserver.port");
+ }
+
+ public String getHomeDir() {
+ return getOS() == OSType.WINDOWS ?
+ "C:/Users/" + System.getProperty("user.name") + "/" :
+ System.getProperty("user.home").contains("root") ? "/root/" :
+ "/home/" + System.getProperty("user.name") + "/";
+ }
+
+ public String getBaseDir() {
+ return getHomeDir() +
+ (getOS() == OSType.WINDOWS ? ".contaminus/" :
+ getOS() == OSType.LINUX ? ".config/contaminus/" :
+ ".contaminus/");
+ }
+
+ public static OSType getOS() {
+ String os = System.getProperty("os.name").toLowerCase();
+ if (os.contains("win")) {
+ return OSType.WINDOWS;
+ } else if (os.contains("nix") || os.contains("nux")) {
+ return OSType.LINUX;
+ } else {
+ return OSType.INVALID_OS;
+ }
+ }
+
public String getStringProperty(String key) {
return config.getProperty(key);
}
public int getIntProperty(String key) {
- return Integer.parseInt(config.getProperty(key));
- }
+ String value = config.getProperty(key);
+ return value != null ? Integer.parseInt(value) : 10;
+ }
public boolean getBooleanProperty(String key) {
- return Boolean.parseBoolean(config.getProperty(key));
+ return Boolean.parseBoolean(config.getProperty(key));
}
public void setProperty(String key, String value) {
diff --git a/backend/src/main/java/net/miarma/contaminus/common/Constants.java b/backend/src/main/java/net/miarma/contaminus/common/Constants.java
index 9da4d47..c3d9b3f 100644
--- a/backend/src/main/java/net/miarma/contaminus/common/Constants.java
+++ b/backend/src/main/java/net/miarma/contaminus/common/Constants.java
@@ -6,44 +6,38 @@ 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 = SystemInfo.getOS() == OSType.WINDOWS ?
- "C:/Users/" + System.getProperty("user.name") + "/" :
- System.getProperty("user.home").contains("root") ? "/root/" :
- "/home/" + System.getProperty("user.name") + "/";
- public static final String BASE_DIR = HOME_DIR +
- (SystemInfo.getOS() == OSType.WINDOWS ? ".contaminus" :
- SystemInfo.getOS() == OSType.LINUX ? ".config" + "/" +
- "contaminus" : null);
- public static final String CONFIG_FILE = BASE_DIR + "/" + "config.properties";
- public static final Logger LOGGER = LoggerFactory.getLogger(APP_NAME);
+ public static Logger LOGGER = LoggerFactory.getLogger(Constants.APP_NAME);
+
+ /* API Endpoints */
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_DEVICE_ACTUATORS = API_PREFIX + "/devices/:deviceId/actuators";
- public static final String GET_DEVICE_LATEST_VALUES = API_PREFIX + "/devices/:deviceId/latest";
- public static final String GET_DEVICE_POLLUTION_MAP = API_PREFIX + "/devices/:deviceId/pollution-map";
- public static final String GET_DEVICE_HISTORY = API_PREFIX + "/devices/:deviceId/history";
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";
+ /* Bussiness Logic API */
+ 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 GET_DEVICE_BY_ID = API_PREFIX + "/devices/:deviceId";
+ public static final String GET_DEVICE_SENSORS = API_PREFIX + "/devices/:deviceId/sensors";
+ public static final String GET_DEVICE_ACTUATORS = API_PREFIX + "/devices/:deviceId/actuators";
+ public static final String GET_DEVICE_LATEST_VALUES = API_PREFIX + "/devices/:deviceId/latest";
+ public static final String GET_DEVICE_POLLUTION_MAP = API_PREFIX + "/devices/:deviceId/pollution-map";
+ public static final String GET_DEVICE_HISTORY = API_PREFIX + "/devices/:deviceId/history";
+ 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 GET_ACTUATOR_BY_ID = API_PREFIX + "/actuators/:actuatorId";
private Constants() {
throw new AssertionError("Utility class cannot be instantiated.");
diff --git a/backend/src/main/java/net/miarma/contaminus/common/Host.java b/backend/src/main/java/net/miarma/contaminus/common/Host.java
deleted file mode 100644
index ba1eeed..0000000
--- a/backend/src/main/java/net/miarma/contaminus/common/Host.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package net.miarma.contaminus.common;
-
-public class Host {
- static ConfigManager configManager = ConfigManager.getInstance();
- static String host = configManager.getStringProperty("inet.host");
- static String origin = configManager.getStringProperty("inet.origin");
- 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;
- }
-}
diff --git a/backend/src/main/java/net/miarma/contaminus/common/SystemInfo.java b/backend/src/main/java/net/miarma/contaminus/common/SystemInfo.java
deleted file mode 100644
index 72dc3a4..0000000
--- a/backend/src/main/java/net/miarma/contaminus/common/SystemInfo.java
+++ /dev/null
@@ -1,14 +0,0 @@
-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;
- }
- }
-}
diff --git a/backend/src/main/java/net/miarma/contaminus/common/Table.java b/backend/src/main/java/net/miarma/contaminus/common/Table.java
new file mode 100644
index 0000000..7754714
--- /dev/null
+++ b/backend/src/main/java/net/miarma/contaminus/common/Table.java
@@ -0,0 +1,12 @@
+package net.miarma.contaminus.common;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.TYPE) // aplica a clases/interfaces
+@Retention(RetentionPolicy.RUNTIME) // disponible en tiempo de ejecuciΓ³n
+public @interface Table {
+ String value();
+}
diff --git a/backend/src/main/java/net/miarma/contaminus/common/entities/Actuator.java b/backend/src/main/java/net/miarma/contaminus/common/entities/Actuator.java
deleted file mode 100644
index 05bc49f..0000000
--- a/backend/src/main/java/net/miarma/contaminus/common/entities/Actuator.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package net.miarma.contaminus.common.entities;
-
-public class Actuator {
-
-}
diff --git a/backend/src/main/java/net/miarma/contaminus/common/entities/COValue.java b/backend/src/main/java/net/miarma/contaminus/common/entities/COValue.java
deleted file mode 100644
index 7e1c521..0000000
--- a/backend/src/main/java/net/miarma/contaminus/common/entities/COValue.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package net.miarma.contaminus.common.entities;
-
-public class COValue {
-
-}
diff --git a/backend/src/main/java/net/miarma/contaminus/common/entities/Device.java b/backend/src/main/java/net/miarma/contaminus/common/entities/Device.java
deleted file mode 100644
index ed3fc0a..0000000
--- a/backend/src/main/java/net/miarma/contaminus/common/entities/Device.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package net.miarma.contaminus.common.entities;
-
-public class Device {
-
-}
diff --git a/backend/src/main/java/net/miarma/contaminus/common/entities/GpsValue.java b/backend/src/main/java/net/miarma/contaminus/common/entities/GpsValue.java
deleted file mode 100644
index ea46779..0000000
--- a/backend/src/main/java/net/miarma/contaminus/common/entities/GpsValue.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package net.miarma.contaminus.common.entities;
-
-public class GpsValue {
-
-}
diff --git a/backend/src/main/java/net/miarma/contaminus/common/entities/Group.java b/backend/src/main/java/net/miarma/contaminus/common/entities/Group.java
deleted file mode 100644
index 9b96951..0000000
--- a/backend/src/main/java/net/miarma/contaminus/common/entities/Group.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package net.miarma.contaminus.common.entities;
-
-public class Group {
-
-}
diff --git a/backend/src/main/java/net/miarma/contaminus/common/entities/Sensor.java b/backend/src/main/java/net/miarma/contaminus/common/entities/Sensor.java
deleted file mode 100644
index 1799081..0000000
--- a/backend/src/main/java/net/miarma/contaminus/common/entities/Sensor.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package net.miarma.contaminus.common.entities;
-
-public class Sensor {
-
-}
diff --git a/backend/src/main/java/net/miarma/contaminus/common/entities/WeatherValue.java b/backend/src/main/java/net/miarma/contaminus/common/entities/WeatherValue.java
deleted file mode 100644
index 8286952..0000000
--- a/backend/src/main/java/net/miarma/contaminus/common/entities/WeatherValue.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package net.miarma.contaminus.common.entities;
-
-public class WeatherValue {
-
-}
diff --git a/backend/src/main/java/net/miarma/contaminus/database/DatabaseManager.java b/backend/src/main/java/net/miarma/contaminus/database/DatabaseManager.java
index c40c9b7..9c1d350 100644
--- a/backend/src/main/java/net/miarma/contaminus/database/DatabaseManager.java
+++ b/backend/src/main/java/net/miarma/contaminus/database/DatabaseManager.java
@@ -1,30 +1,58 @@
package net.miarma.contaminus.database;
-import io.vertx.core.Vertx;
-import io.vertx.core.json.JsonObject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+
+import io.vertx.core.Future;
+import io.vertx.core.Handler;
import io.vertx.jdbcclient.JDBCPool;
-import net.miarma.contaminus.common.ConfigManager;
+import io.vertx.sqlclient.Row;
+import io.vertx.sqlclient.RowSet;
+import net.miarma.contaminus.common.Constants;
public class DatabaseManager {
+ private static DatabaseManager instance;
private final JDBCPool pool;
+
+ private DatabaseManager(JDBCPool pool) {
+ this.pool = 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 static synchronized DatabaseManager getInstance(JDBCPool pool) {
+ if (instance == null) {
+ instance = new DatabaseManager(pool);
+ }
+ return instance;
}
- public JDBCPool getPool() {
- return pool;
+ public Future> testConnection() {
+ return pool.query("SELECT 1").execute();
+ }
+
+ public Future> execute(String query, Class clazz,
+ Handler> onSuccess, Handler onFailure) {
+ return pool.query(query).execute()
+ .map(rows -> {
+ List results = new ArrayList<>();
+ for (Row row : rows) {
+ try {
+ Constructor constructor = clazz.getConstructor(Row.class);
+ results.add(constructor.newInstance(row));
+ } catch (NoSuchMethodException | InstantiationException |
+ IllegalAccessException | InvocationTargetException e) {
+ Constants.LOGGER.error("Error instantiating class: " + e.getMessage());
+ }
+ }
+ return results;
+ })
+ .onComplete(ar -> {
+ if (ar.succeeded()) {
+ onSuccess.handle(ar.result());
+ } else {
+ onFailure.handle(ar.cause());
+ }
+ });
}
}
diff --git a/backend/src/main/java/net/miarma/contaminus/database/QueryBuilder.java b/backend/src/main/java/net/miarma/contaminus/database/QueryBuilder.java
index 3a75c85..4b07395 100644
--- a/backend/src/main/java/net/miarma/contaminus/database/QueryBuilder.java
+++ b/backend/src/main/java/net/miarma/contaminus/database/QueryBuilder.java
@@ -1,87 +1,135 @@
package net.miarma.contaminus.database;
+import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.StringJoiner;
+import net.miarma.contaminus.common.Constants;
+import net.miarma.contaminus.common.Table;
+
public class QueryBuilder {
private StringBuilder query;
- private List 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);
+ private static String getTableName(Class clazz) {
+ if (clazz.isAnnotationPresent(Table.class)) {
+ Table annotation = clazz.getAnnotation(Table.class);
+ return annotation.value(); // lee el nombre de la tabla desde la annotation
}
- qb.query.append("SELECT ").append(joiner).append(" ");
+ throw new IllegalArgumentException("Clase no tiene la anotaciΓ³n @TableName");
+ }
+
+ public String getQuery() {
+ return query.toString();
+ }
+
+ public static QueryBuilder select(Class clazz, String... columns) {
+ QueryBuilder qb = new QueryBuilder();
+ String tableName = getTableName(clazz);
+
+ qb.query.append("SELECT ");
+
+ if (columns.length == 0) {
+ qb.query.append("* ");
+ } else {
+ StringJoiner joiner = new StringJoiner(", ");
+ for (String column : columns) {
+ joiner.add(column);
+ }
+ qb.query.append(joiner).append(" ");
+ }
+
+ qb.query.append("FROM ").append(tableName).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());
+ public static QueryBuilder where(QueryBuilder qb, T object) {
+ List conditions = new ArrayList<>();
+ Class> clazz = object.getClass();
+
+ for (Field field : clazz.getDeclaredFields()) {
+ field.setAccessible(true);
+ try {
+ Object value = field.get(object);
+ if (value != null) {
+ if (value instanceof String) {
+ conditions.add(field.getName() + " = '" + value + "'");
+ } else {
+ conditions.add(field.getName() + " = " + value);
+ }
+ }
+ } catch (IllegalAccessException e) {
+ Constants.LOGGER.error("(REFLECTION) Error reading field: " + e.getMessage());
}
}
- this.query.append(joiner).append(" ");
- return this;
+
+ if (!conditions.isEmpty()) {
+ qb.query.append("WHERE ").append(String.join(" AND ", conditions)).append(" ");
+ }
+
+ return qb;
}
- public QueryBuilder from(String table) {
- query.append("FROM ").append(table).append(" ");
- return this;
+ public static QueryBuilder select(T object, String... columns) {
+ Class> clazz = object.getClass();
+ QueryBuilder qb = select(clazz, columns);
+ return where(qb, object);
+ }
+
+
+ public static QueryBuilder insert(T object) {
+ QueryBuilder qb = new QueryBuilder();
+ String table = getTableName(object.getClass());
+ qb.query.append("INSERT INTO ").append(table).append(" ");
+ qb.query.append("(");
+ StringJoiner columns = new StringJoiner(", ");
+ StringJoiner values = new StringJoiner(", ");
+ for (Field field : object.getClass().getDeclaredFields()) {
+ field.setAccessible(true);
+ try {
+ columns.add(field.getName());
+ if(field.get(object) instanceof String) {
+ values.add("'" + field.get(object) + "'");
+ } else {
+ values.add(field.get(object).toString());
+ }
+ } catch (IllegalArgumentException | IllegalAccessException e) {
+ Constants.LOGGER.error("(REFLECTION) Error reading field: " + e.getMessage());
+ }
+ }
+ qb.query.append(columns).append(") ");
+ qb.query.append("VALUES (").append(values).append(") ");
+ return qb;
}
- public QueryBuilder where(String conditionsString, Object... values) {
- conditionsString = conditionsString.replaceAll("\\?", "%s");
- conditions.add(String.format(conditionsString, values));
- return this;
+ public static QueryBuilder update(T object) {
+ QueryBuilder qb = new QueryBuilder();
+ String table = getTableName(object.getClass());
+ qb.query.append("UPDATE ").append(table).append(" ");
+ qb.query.append("SET ");
+ StringJoiner joiner = new StringJoiner(", ");
+ for (Field field : object.getClass().getDeclaredFields()) {
+ field.setAccessible(true);
+ try {
+ if(field.get(object) instanceof String) {
+ joiner.add(field.getName() + " = '" + field.get(object) + "'");
+ } else {
+ joiner.add(field.getName() + " = " + field.get(object).toString());
+ }
+ } catch (IllegalArgumentException | IllegalAccessException e) {
+ Constants.LOGGER.error("(REFLECTION) Error reading field: " + e.getMessage());
+ }
+ }
+ qb.query.append(joiner).append(" ");
+ return qb;
}
public QueryBuilder orderBy(Optional column, Optional order) {
@@ -100,14 +148,6 @@ public class QueryBuilder {
}
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);
}
diff --git a/backend/src/main/java/net/miarma/contaminus/database/entities/Actuator.java b/backend/src/main/java/net/miarma/contaminus/database/entities/Actuator.java
new file mode 100644
index 0000000..9736302
--- /dev/null
+++ b/backend/src/main/java/net/miarma/contaminus/database/entities/Actuator.java
@@ -0,0 +1,91 @@
+package net.miarma.contaminus.database.entities;
+
+import java.util.Objects;
+
+import io.vertx.sqlclient.Row;
+import net.miarma.contaminus.common.Table;
+
+@Table("actuators")
+public class Actuator {
+
+ private int actuatorId;
+ private int deviceId;
+ private int status;
+ private long timestamp;
+
+ public Actuator() {}
+
+ public Actuator(Row row) {
+ this.actuatorId = row.getInteger("actuatorId");
+ this.deviceId = row.getInteger("deviceId");
+ this.status = row.getInteger("status");
+ this.timestamp = row.getLong("timestamp");
+ }
+
+ public Actuator(int actuatorId, int deviceId, int status, long timestamp) {
+ super();
+ this.actuatorId = actuatorId;
+ this.deviceId = deviceId;
+ this.status = status;
+ this.timestamp = timestamp;
+ }
+
+ public int getActuatorId() {
+ return actuatorId;
+ }
+
+ public void setActuatorId(int actuatorId) {
+ this.actuatorId = actuatorId;
+ }
+
+ public int getDeviceId() {
+ return deviceId;
+ }
+
+ public void setDeviceId(int deviceId) {
+ this.deviceId = deviceId;
+ }
+
+ public int getStatus() {
+ return status;
+ }
+
+ public void setStatus(int status) {
+ this.status = status;
+ }
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(long timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(actuatorId, deviceId, status, timestamp);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Actuator other = (Actuator) obj;
+ return actuatorId == other.actuatorId && deviceId == other.deviceId
+ && status == other.status && timestamp == other.timestamp;
+ }
+
+ @Override
+ public String toString() {
+ return "Actuator [actuatorId=" + actuatorId + ", deviceId=" + deviceId + ", status=" + status + ", timestamp="
+ + timestamp + "]";
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/backend/src/main/java/net/miarma/contaminus/database/entities/COValue.java b/backend/src/main/java/net/miarma/contaminus/database/entities/COValue.java
new file mode 100644
index 0000000..26fcc02
--- /dev/null
+++ b/backend/src/main/java/net/miarma/contaminus/database/entities/COValue.java
@@ -0,0 +1,91 @@
+package net.miarma.contaminus.database.entities;
+
+import java.util.Objects;
+
+import io.vertx.sqlclient.Row;
+import net.miarma.contaminus.common.Table;
+
+@Table("co_values")
+public class COValue {
+
+ private int valueId;
+ private int sensorId;
+ private float value;
+ private long timestamp;
+
+ public COValue() {}
+
+ public COValue(Row row) {
+ this.valueId = row.getInteger("valueId");
+ this.sensorId = row.getInteger("sensorId");
+ this.value = row.getFloat("value");
+ this.timestamp = row.getLong("timestamp");
+ }
+
+ public COValue(int valueId, int sensorId, float value, long timestamp) {
+ super();
+ this.valueId = valueId;
+ this.sensorId = sensorId;
+ this.value = value;
+ this.timestamp = timestamp;
+ }
+
+ public int getValueId() {
+ return valueId;
+ }
+
+ public void setValueId(int valueId) {
+ this.valueId = valueId;
+ }
+
+ public int getSensorId() {
+ return sensorId;
+ }
+
+ public void setSensorId(int sensorId) {
+ this.sensorId = sensorId;
+ }
+
+ public float getValue() {
+ return value;
+ }
+
+ public void setValue(float value) {
+ this.value = value;
+ }
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(long timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(sensorId, timestamp, value, valueId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ COValue other = (COValue) obj;
+ return sensorId == other.sensorId
+ && Objects.equals(timestamp, other.timestamp)
+ && Float.floatToIntBits(value) == Float.floatToIntBits(other.value) && valueId == other.valueId;
+ }
+
+ @Override
+ public String toString() {
+ return "COValue [valueId=" + valueId + ", sensorId=" + sensorId + ", value=" + value + ", timestamp="
+ + timestamp + "]";
+ }
+
+
+}
\ No newline at end of file
diff --git a/backend/src/main/java/net/miarma/contaminus/database/entities/Device.java b/backend/src/main/java/net/miarma/contaminus/database/entities/Device.java
new file mode 100644
index 0000000..db9f60e
--- /dev/null
+++ b/backend/src/main/java/net/miarma/contaminus/database/entities/Device.java
@@ -0,0 +1,81 @@
+package net.miarma.contaminus.database.entities;
+
+import java.util.Objects;
+
+import io.vertx.sqlclient.Row;
+import net.miarma.contaminus.common.Table;
+
+@Table("devices")
+public class Device {
+
+ private int deviceId;
+ private int groupId;
+ private String deviceName;
+
+ public Device() {}
+
+ public Device(Row row) {
+ this.deviceId = row.getInteger("deviceId");
+ this.groupId = row.getInteger("groupId");
+ this.deviceName = row.getString("deviceName");
+ }
+
+ public Device(int deviceId, int groupId, String deviceName) {
+ super();
+ this.deviceId = deviceId;
+ this.groupId = groupId;
+ this.deviceName = deviceName;
+ }
+
+ public int getDeviceId() {
+ return deviceId;
+ }
+
+ public void setDeviceId(int deviceId) {
+ this.deviceId = deviceId;
+ }
+
+ public int getGroupId() {
+ return groupId;
+ }
+
+ public void setGroupId(int groupId) {
+ this.groupId = groupId;
+ }
+
+ public String getDeviceName() {
+ return deviceName;
+ }
+
+ public void setDeviceName(String deviceName) {
+ this.deviceName = deviceName;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(deviceId, deviceName, groupId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Device other = (Device) obj;
+ return deviceId == other.deviceId
+ && Objects.equals(deviceName, other.deviceName)
+ && groupId == other.groupId;
+ }
+
+ @Override
+ public String toString() {
+ return "Device [deviceId=" + deviceId + ", groupId=" + groupId + ", deviceName=" + deviceName + "]";
+ }
+
+
+
+}
+
diff --git a/backend/src/main/java/net/miarma/contaminus/database/entities/GpsValue.java b/backend/src/main/java/net/miarma/contaminus/database/entities/GpsValue.java
new file mode 100644
index 0000000..b0db81b
--- /dev/null
+++ b/backend/src/main/java/net/miarma/contaminus/database/entities/GpsValue.java
@@ -0,0 +1,103 @@
+package net.miarma.contaminus.database.entities;
+
+import java.util.Objects;
+
+import io.vertx.sqlclient.Row;
+import net.miarma.contaminus.common.Table;
+
+@Table("gps_values")
+public class GpsValue {
+
+ private int valueId;
+ private int sensorId;
+ private float lat;
+ private float lon;
+ private long timestamp;
+
+ public GpsValue() {}
+
+ public GpsValue(Row row) {
+ this.valueId = row.getInteger("valueId");
+ this.sensorId = row.getInteger("sensorId");
+ this.lat = row.getFloat("lat");
+ this.lon = row.getFloat("lon");
+ this.timestamp = row.getLong("timestamp");
+ }
+
+ public GpsValue(int valueId, int sensorId, float lat, float lon, long timestamp) {
+ super();
+ this.valueId = valueId;
+ this.sensorId = sensorId;
+ this.lat = lat;
+ this.lon = lon;
+ this.timestamp = timestamp;
+ }
+
+ public int getValueId() {
+ return valueId;
+ }
+
+ public void setValueId(int valueId) {
+ this.valueId = valueId;
+ }
+
+ public int getSensorId() {
+ return sensorId;
+ }
+
+ public void setSensorId(int sensorId) {
+ this.sensorId = sensorId;
+ }
+
+ public float getLat() {
+ return lat;
+ }
+
+ public void setLat(float lat) {
+ this.lat = lat;
+ }
+
+ public float getLon() {
+ return lon;
+ }
+
+ public void setLon(float lon) {
+ this.lon = lon;
+ }
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(long timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(lat, lon, sensorId, timestamp, valueId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ GpsValue other = (GpsValue) obj;
+ return Float.floatToIntBits(lat) == Float.floatToIntBits(other.lat)
+ && Float.floatToIntBits(lon) == Float.floatToIntBits(other.lon)
+ && sensorId == other.sensorId && timestamp == other.timestamp && valueId == other.valueId;
+ }
+
+ @Override
+ public String toString() {
+ return "GpsValue [valueId=" + valueId + ", sensorId=" + sensorId + ", lat=" + lat + ", lon=" + lon
+ + ", timestamp=" + timestamp + "]";
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/backend/src/main/java/net/miarma/contaminus/database/entities/Group.java b/backend/src/main/java/net/miarma/contaminus/database/entities/Group.java
new file mode 100644
index 0000000..58f1e2a
--- /dev/null
+++ b/backend/src/main/java/net/miarma/contaminus/database/entities/Group.java
@@ -0,0 +1,67 @@
+package net.miarma.contaminus.database.entities;
+
+import java.util.Objects;
+
+import io.vertx.sqlclient.Row;
+import net.miarma.contaminus.common.Table;
+
+@Table("groups")
+public class Group {
+
+ private int groupId;
+ private String groupName;
+
+ public Group() {}
+
+ public Group(Row row) {
+ this.groupId = row.getInteger("groupId");
+ this.groupName = row.getString("groupName");
+ }
+
+ public Group(int groupId, String groupName) {
+ super();
+ this.groupId = groupId;
+ this.groupName = groupName;
+ }
+
+ public int getGroupId() {
+ return groupId;
+ }
+
+ public void setGroupId(int groupId) {
+ this.groupId = groupId;
+ }
+
+ public String getGroupName() {
+ return groupName;
+ }
+
+ public void setGroupName(String groupName) {
+ this.groupName = groupName;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(groupId, groupName);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Group other = (Group) obj;
+ return groupId == other.groupId
+ && Objects.equals(groupName, other.groupName);
+ }
+
+ @Override
+ public String toString() {
+ return "Group [groupId=" + groupId + ", groupName=" + groupName + "]";
+ }
+
+
+}
\ No newline at end of file
diff --git a/backend/src/main/java/net/miarma/contaminus/database/entities/Sensor.java b/backend/src/main/java/net/miarma/contaminus/database/entities/Sensor.java
new file mode 100644
index 0000000..9000a20
--- /dev/null
+++ b/backend/src/main/java/net/miarma/contaminus/database/entities/Sensor.java
@@ -0,0 +1,112 @@
+package net.miarma.contaminus.database.entities;
+
+import java.util.Objects;
+
+import io.vertx.sqlclient.Row;
+import net.miarma.contaminus.common.Table;
+
+@Table("sensors")
+public class Sensor {
+
+ private int sensorId;
+ private int deviceId;
+ private String sensorType;
+ private String unit;
+ private int status;
+ private long timestamp;
+
+ public Sensor() {}
+
+ public Sensor(Row row) {
+ this.sensorId = row.getInteger("sensorId");
+ this.deviceId = row.getInteger("deviceId");
+ this.sensorType = row.getString("sensorType");
+ this.unit = row.getString("unit");
+ this.status = row.getInteger("status");
+ this.timestamp = row.getLong("timestamp");
+ }
+
+ public Sensor(int sensorId, int deviceId, String sensorType, String unit, int status, long timestamp) {
+ super();
+ this.sensorId = sensorId;
+ this.deviceId = deviceId;
+ this.sensorType = sensorType;
+ this.unit = unit;
+ this.status = status;
+ this.timestamp = timestamp;
+ }
+
+ public int getSensorId() {
+ return sensorId;
+ }
+
+ public void setSensorId(int sensorId) {
+ this.sensorId = sensorId;
+ }
+
+ public int getDeviceId() {
+ return deviceId;
+ }
+
+ public void setDeviceId(int deviceId) {
+ this.deviceId = deviceId;
+ }
+
+ public String getSensorType() {
+ return sensorType;
+ }
+
+ public void setSensorType(String sensorType) {
+ this.sensorType = sensorType;
+ }
+
+ public String getUnit() {
+ return unit;
+ }
+
+ public void setUnit(String unit) {
+ this.unit = unit;
+ }
+
+ public int getStatus() {
+ return status;
+ }
+
+ public void setStatus(int status) {
+ this.status = status;
+ }
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(long timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(deviceId, sensorId, sensorType, status, timestamp, unit);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Sensor other = (Sensor) obj;
+ return deviceId == other.deviceId && sensorId == other.sensorId && Objects.equals(sensorType, other.sensorType)
+ && status == other.status && timestamp == other.timestamp && Objects.equals(unit, other.unit);
+ }
+
+ @Override
+ public String toString() {
+ return "Sensor [sensorId=" + sensorId + ", deviceId=" + deviceId + ", sensorType=" + sensorType + ", unit="
+ + unit + ", status=" + status + ", timestamp=" + timestamp + "]";
+ }
+
+
+}
diff --git a/backend/src/main/java/net/miarma/contaminus/database/entities/WeatherValue.java b/backend/src/main/java/net/miarma/contaminus/database/entities/WeatherValue.java
new file mode 100644
index 0000000..e69f485
--- /dev/null
+++ b/backend/src/main/java/net/miarma/contaminus/database/entities/WeatherValue.java
@@ -0,0 +1,103 @@
+package net.miarma.contaminus.database.entities;
+
+import java.util.Objects;
+
+import io.vertx.sqlclient.Row;
+import net.miarma.contaminus.common.Table;
+
+@Table("weather_values")
+public class WeatherValue {
+
+ private int valueId;
+ private int sensorId;
+ private float temperature;
+ private float humidity;
+ private long timestamp;
+
+ public WeatherValue() {}
+
+ public WeatherValue(Row row) {
+ this.valueId = row.getInteger("valueId");
+ this.sensorId = row.getInteger("sensorId");
+ this.temperature = row.getFloat("temperature");
+ this.humidity = row.getFloat("humidity");
+ this.timestamp = row.getLong("timestamp");
+ }
+
+ public WeatherValue(int valueId, int sensorId, float temperature, float humidity, long timestamp) {
+ super();
+ this.valueId = valueId;
+ this.sensorId = sensorId;
+ this.temperature = temperature;
+ this.humidity = humidity;
+ this.timestamp = timestamp;
+ }
+
+ public int getValueId() {
+ return valueId;
+ }
+
+ public void setValueId(int valueId) {
+ this.valueId = valueId;
+ }
+
+ public int getSensorId() {
+ return sensorId;
+ }
+
+ public void setSensorId(int sensorId) {
+ this.sensorId = sensorId;
+ }
+
+ public float getTemperature() {
+ return temperature;
+ }
+
+ public void setTemperature(float temperature) {
+ this.temperature = temperature;
+ }
+
+ public float getHumidity() {
+ return humidity;
+ }
+
+ public void setHumidity(float humidity) {
+ this.humidity = humidity;
+ }
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(long timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(humidity, sensorId, temperature, timestamp, valueId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ WeatherValue other = (WeatherValue) obj;
+ return Float.floatToIntBits(humidity) == Float.floatToIntBits(other.humidity) && sensorId == other.sensorId
+ && Float.floatToIntBits(temperature) == Float.floatToIntBits(other.temperature)
+ && timestamp == other.timestamp && valueId == other.valueId;
+ }
+
+ @Override
+ public String toString() {
+ return "WeatherValue [valueId=" + valueId + ", sensorId=" + sensorId + ", temperature=" + temperature
+ + ", humidity=" + humidity + ", timestamp=" + timestamp + "]";
+ }
+
+
+
+}
\ 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
deleted file mode 100644
index 596b5a4..0000000
--- a/backend/src/main/java/net/miarma/contaminus/server/ApiVerticle.java
+++ /dev/null
@@ -1,403 +0,0 @@
-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, HttpMethod.OPTIONS)); // Por ejemplo
- Set allowedHeaders = new HashSet<>(Arrays.asList("Content-Type", "Authorization"));
-
- router.route().handler(CorsHandler.create()
- .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.GET, Constants.GET_DEVICE_ACTUATORS).handler(this::getDeviceActuatorsHandler);
- router.route(HttpMethod.GET, Constants.GET_DEVICE_LATEST_VALUES).handler(this::getDeviceLatestValuesHandler);
- router.route(HttpMethod.POST, Constants.POST_DEVICES).handler(this::postDeviceHandler);
- router.route(HttpMethod.PUT, Constants.PUT_DEVICE_BY_ID).handler(this::putDeviceByIdHandler);
- router.route(HttpMethod.GET, Constants.GET_DEVICE_POLLUTION_MAP).handler(this::getPollutionMapHandler);
- router.route(HttpMethod.GET, Constants.GET_DEVICE_HISTORY).handler(this::getDeviceHistoryHandler);
-
- // 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