1
0

added some improved classes from my custom backend and introduced DAOs

This commit is contained in:
Jose
2025-05-09 20:48:45 +02:00
parent b6f13cfff8
commit 02a2a2ce07
53 changed files with 4462 additions and 3239 deletions

View File

@@ -1,98 +1,104 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.miarma</groupId>
<artifactId>contaminus</artifactId>
<version>1.0.0</version>
<name>ContaminUS</name>
<properties>
<maven.compiler.source>23</maven.compiler.source>
<maven.compiler.target>23</maven.compiler.target>
</properties>
<dependencies>
<!-- Vert.X Core -->
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-core</artifactId>
<version>4.5.13</version>
</dependency>
<!-- Vert.X Web -->
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web</artifactId>
<version>4.5.13</version>
</dependency>
<!-- Vert.X Web Client -->
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web-client</artifactId>
<version>4.5.13</version>
</dependency>
<!-- Vert.X MQTT -->
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-mqtt</artifactId>
<version>4.4.2</version>
</dependency>
<!-- Vert.X MariaDB/MySQL Client -->
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-jdbc-client</artifactId>
<version>4.5.13</version>
</dependency>
<!-- JDBC Driver -->
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>3.5.2</version>
</dependency>
<!-- Gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.12.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.quarkus/quarkus-agroal -->
<dependency>
<groupId>org.jboss.logmanager</groupId>
<artifactId>jboss-logmanager</artifactId>
<version>3.1.1.Final</version> <!-- O la versión más reciente -->
</dependency>
</dependencies>
<build>
<plugins>
<!-- Maven Shade Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>net.miarma.contaminus.server.MainVerticle</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.miarma</groupId>
<artifactId>contaminus</artifactId>
<version>1.0.0</version>
<name>ContaminUS</name>
<properties>
<maven.compiler.source>23</maven.compiler.source>
<maven.compiler.target>23</maven.compiler.target>
</properties>
<dependencies>
<!-- Vert.X Core -->
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-core</artifactId>
<version>4.5.13</version>
</dependency>
<!-- Vert.X MariaDB/MySQL Client -->
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-mysql-client</artifactId>
<version>4.5.13</version>
</dependency>
<!-- Vert.X Web -->
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web</artifactId>
<version>4.5.13</version>
</dependency>
<!-- Vert.X Web Client -->
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web-client</artifactId>
<version>4.5.13</version>
</dependency>
<!-- Vert.X MQTT -->
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-mqtt</artifactId>
<version>4.4.2</version>
</dependency>
<!-- Vert.X MariaDB/MySQL Client -->
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-jdbc-client</artifactId>
<version>4.5.13</version>
</dependency>
<!-- Gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.12.1</version>
</dependency>
<!-- SLF4J + Logback -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.12</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.5.13</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Maven Shade Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>net.miarma.contaminus.server.MainVerticle</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,113 @@
package net.miarma.contaminus.common;
import java.lang.reflect.Field;
import io.vertx.core.json.JsonObject;
import io.vertx.sqlclient.Row;
public abstract class AbstractEntity {
public AbstractEntity() {}
public AbstractEntity(Row row) {
populateFromRow(row);
}
private void populateFromRow(Row row) {
Field[] fields = this.getClass().getDeclaredFields();
for (Field field : fields) {
try {
field.setAccessible(true);
Class<?> type = field.getType();
String name = field.getName();
Object value;
if (type.isEnum()) {
Integer intValue = row.getInteger(name);
if (intValue != null) {
try {
var method = type.getMethod("fromInt", int.class);
value = method.invoke(null, intValue);
} catch (Exception e) {
value = null;
}
} else {
value = null;
}
} else {
value = switch (type.getSimpleName()) {
case "Integer" -> row.getInteger(name);
case "String" -> row.getString(name);
case "Double" -> row.getDouble(name);
case "Long" -> row.getLong(name);
case "Boolean" -> row.getBoolean(name);
case "int" -> row.getInteger(name);
case "double" -> row.getDouble(name);
case "long" -> row.getLong(name);
case "boolean" -> row.getBoolean(name);
case "LocalDateTime" -> row.getLocalDateTime(name);
case "BigDecimal" -> {
try {
var numeric = row.get(io.vertx.sqlclient.data.Numeric.class, row.getColumnIndex(name));
yield numeric != null ? numeric.bigDecimalValue() : null;
} catch (Exception e) {
yield null;
}
}
default -> {
System.err.println("Type not supported yet: " + type.getName() + " for field " + name);
yield null;
}
};
}
field.set(this, value);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public String encode() {
JsonObject json = new JsonObject();
Class<?> clazz = this.getClass();
while (clazz != null) {
for (Field field : clazz.getDeclaredFields()) {
field.setAccessible(true);
try {
Object value = field.get(this);
if (value instanceof ValuableEnum ve) {
json.put(field.getName(), ve.getValue());
} else {
json.put(field.getName(), value);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
clazz = clazz.getSuperclass();
}
return json.encode();
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(this.getClass().getSimpleName()).append(" [ ");
Field[] fields = this.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
try {
sb.append(field.getName()).append("= ").append(field.get(this)).append(", ");
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
sb.append("]");
return sb.toString();
}
}

View File

@@ -1,57 +1,42 @@
package net.miarma.contaminus.common;
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 RAW_API_PREFIX = "/api/raw/v1";
public static Logger LOGGER = LoggerFactory.getLogger(Constants.APP_NAME);
/* API Endpoints */
public static final String POST_PAYLOAD = RAW_API_PREFIX + "/device-payload";
public static final String GET_GROUPS = RAW_API_PREFIX + "/groups";
public static final String POST_GROUPS = RAW_API_PREFIX + "/groups";
public static final String PUT_GROUP_BY_ID = RAW_API_PREFIX + "/groups/:groupId";
public static final String GET_DEVICES = RAW_API_PREFIX + "/devices";
public static final String POST_DEVICES = RAW_API_PREFIX + "/devices";
public static final String PUT_DEVICE_BY_ID = RAW_API_PREFIX + "/devices/:deviceId";
public static final String GET_SENSORS = RAW_API_PREFIX + "/sensors";
public static final String POST_SENSORS = RAW_API_PREFIX + "/sensors";
public static final String PUT_SENSOR_BY_ID = RAW_API_PREFIX + "/sensors/:sensorId";
public static final String GET_ACTUATORS = RAW_API_PREFIX + "/actuators";
public static final String POST_ACTUATORS = RAW_API_PREFIX + "/actuators";
public static final String PUT_ACTUATOR_BY_ID = RAW_API_PREFIX + "/actuators/:actuatorId";
public static final String GET_CO_BY_DEVICE_VIEW = RAW_API_PREFIX + "/v_co_by_device";
public static final String GET_GPS_BY_DEVICE_VIEW = RAW_API_PREFIX + "/v_gps_by_device";
public static final String GET_LATEST_VALUES_VIEW = RAW_API_PREFIX + "/v_latest_values";
public static final String GET_POLLUTION_MAP_VIEW = RAW_API_PREFIX + "/v_pollution_map";
public static final String GET_SENSOR_HISTORY_BY_DEVICE_VIEW = RAW_API_PREFIX + "/v_sensor_history_by_device";
public static final String GET_SENSOR_VALUES_VIEW = RAW_API_PREFIX + "/v_sensor_values";
public static final String GET_WEATHER_BY_DEVICE_VIEW = RAW_API_PREFIX + "/v_weather_by_device";
/* 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.");
}
}
package net.miarma.contaminus.common;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Constants {
public static final String APP_NAME = "ContaminUS";
public static final String API_PREFIX = "/api/v1";
public static final String RAW_API_PREFIX = "/api/raw/v1";
public static final String CONTAMINUS_EB = "contaminus.eventbus";
public static Logger LOGGER = LoggerFactory.getLogger(Constants.APP_NAME);
/* API Endpoints */
public static final String GROUPS = RAW_API_PREFIX + "/groups";
public static final String GROUP = RAW_API_PREFIX + "/groups/:groupId";
public static final String DEVICES = RAW_API_PREFIX + "/groups/:groupId/devices";
public static final String DEVICE = RAW_API_PREFIX + "/groups/:groupId/devices/:deviceId";
public static final String LATEST_VALUES = API_PREFIX + "/groups/:groupId/devices/:deviceId/latest-values";
public static final String POLLUTION_MAP = API_PREFIX + "/groups/:groupId/devices/:deviceId/pollution-map";
public static final String HISTORY = API_PREFIX + "/groups/:groupId/devices/:deviceId/history";
public static final String SENSORS = RAW_API_PREFIX + "/groups/:groupId/devices/:deviceId/sensors";
public static final String SENSOR = RAW_API_PREFIX + "/groups/:groupId/devices/:deviceId/sensors/:sensorId";
public static final String SENSOR_VALUES = API_PREFIX + "/groups/:groupId/devices/:deviceId/sensors/:sensorId/values";
public static final String ACTUATORS = RAW_API_PREFIX + "/groups/:groupId/devices/:deviceId/actuators";
public static final String ACTUATOR = RAW_API_PREFIX + "/groups/:groupId/devices/:deviceId/actuators/:actuator_id";
public static final String ACTUATOR_STATUS = API_PREFIX + "/groups/:groupId/devices/:deviceId/actuators/:actuator_id/status";
public static final String VIEW_LATEST_VALUES = RAW_API_PREFIX + "/v_latest_values";
public static final String VIEW_POLLUTION_MAP = RAW_API_PREFIX + "/v_pollution_map";
public static final String VIEW_SENSOR_HISTORY = RAW_API_PREFIX + "/v_sensor_history_by_device";
public static final String VIEW_SENSOR_VALUES = RAW_API_PREFIX + "/v_sensor_values";
public static final String VIEW_CO_BY_DEVICE = RAW_API_PREFIX + "/v_co_by_device";
public static final String VIEW_GPS_BY_DEVICE = RAW_API_PREFIX + "/v_gps_by_device";
public static final String VIEW_WEATHER_BY_DEVICE = RAW_API_PREFIX + "/v_weather_by_device";
private Constants() {
throw new AssertionError("Utility class cannot be instantiated.");
}
}

View File

@@ -0,0 +1,5 @@
package net.miarma.contaminus.common;
public interface ValuableEnum {
int getValue();
}

View File

@@ -0,0 +1,129 @@
package net.miarma.contaminus.dao;
import java.util.List;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.sqlclient.Pool;
import net.miarma.contaminus.db.DataAccessObject;
import net.miarma.contaminus.db.DatabaseManager;
import net.miarma.contaminus.db.QueryBuilder;
import net.miarma.contaminus.entities.Actuator;
public class ActuatorDAO implements DataAccessObject<Actuator, Integer>{
private final DatabaseManager db;
public ActuatorDAO(Pool pool) {
this.db = DatabaseManager.getInstance(pool);
}
@Override
public Future<List<Actuator>> getAll() {
Promise<List<Actuator>> promise = Promise.promise();
String query = QueryBuilder.select(Actuator.class).build();
db.execute(query, Actuator.class,
list -> promise.complete(list.isEmpty() ? List.of() : list),
promise::fail
);
return promise.future();
}
public Future<List<Actuator>> getAllByDeviceId(String deviceId) {
Promise<List<Actuator>> promise = Promise.promise();
Actuator actuator = new Actuator();
actuator.setDeviceId(deviceId);
String query = QueryBuilder
.select(Actuator.class)
.where(actuator)
.build();
db.execute(query, Actuator.class,
list -> promise.complete(list.isEmpty() ? List.of() : list),
promise::fail
);
return promise.future();
}
@Override
public Future<Actuator> getById(Integer id) {
Promise<Actuator> promise = Promise.promise();
Actuator actuator = new Actuator();
actuator.setActuatorId(id);
String query = QueryBuilder
.select(Actuator.class)
.where(actuator)
.build();
db.execute(query, Actuator.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
public Future<Actuator> getByIdAndDeviceId(Integer actuatorId, String deviceId) {
Promise<Actuator> promise = Promise.promise();
Actuator actuator = new Actuator();
actuator.setDeviceId(deviceId);
actuator.setActuatorId(actuatorId);
String query = QueryBuilder
.select(Actuator.class)
.where(actuator)
.build();
db.execute(query, Actuator.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
@Override
public Future<Actuator> insert(Actuator t) {
Promise<Actuator> promise = Promise.promise();
String query = QueryBuilder.insert(t).build();
db.execute(query, Actuator.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
@Override
public Future<Actuator> update(Actuator t) {
Promise<Actuator> promise = Promise.promise();
String query = QueryBuilder.update(t).build();
db.execute(query, Actuator.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
@Override
public Future<Actuator> delete(Integer id) {
Promise<Actuator> promise = Promise.promise();
Actuator actuator = new Actuator();
actuator.setActuatorId(id);
String query = QueryBuilder.delete(actuator).build();
db.executeOne(query, Actuator.class,
_ -> promise.complete(actuator),
promise::fail
);
return promise.future();
}
}

View File

@@ -0,0 +1,82 @@
package net.miarma.contaminus.dao;
import java.util.List;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.sqlclient.Pool;
import net.miarma.contaminus.db.DataAccessObject;
import net.miarma.contaminus.db.DatabaseManager;
import net.miarma.contaminus.db.QueryBuilder;
import net.miarma.contaminus.entities.COValue;
public class COValueDAO implements DataAccessObject<COValue, Integer> {
private final DatabaseManager db;
public COValueDAO(Pool pool) {
this.db = DatabaseManager.getInstance(pool);
}
@Override
public Future<List<COValue>> getAll() {
Promise<List<COValue>> promise = Promise.promise();
String query = QueryBuilder.select(COValue.class).build();
db.execute(query, COValue.class,
list -> promise.complete(list.isEmpty() ? List.of() : list),
promise::fail
);
return promise.future();
}
@Override
public Future<COValue> getById(Integer id) {
Promise<COValue> promise = Promise.promise();
COValue coValue = new COValue();
coValue.setValueId(id);
String query = QueryBuilder
.select(COValue.class)
.where(coValue)
.build();
db.execute(query, COValue.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
@Override
public Future<COValue> insert(COValue t) {
Promise<COValue> promise = Promise.promise();
String query = QueryBuilder.insert(t).build();
db.execute(query, COValue.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
@Override
public Future<COValue> update(COValue t) {
Promise<COValue> promise = Promise.promise();
String query = QueryBuilder.update(t).build();
db.execute(query, COValue.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
@Override
public Future<COValue> delete(Integer id) {
throw new UnsupportedOperationException("Cannot delete samples");
}
}

View File

@@ -0,0 +1,128 @@
package net.miarma.contaminus.dao;
import java.util.List;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.sqlclient.Pool;
import net.miarma.contaminus.db.DataAccessObject;
import net.miarma.contaminus.db.DatabaseManager;
import net.miarma.contaminus.db.QueryBuilder;
import net.miarma.contaminus.entities.Device;
public class DeviceDAO implements DataAccessObject<Device, String> {
private final DatabaseManager db;
public DeviceDAO(Pool pool) {
this.db = DatabaseManager.getInstance(pool);
}
@Override
public Future<List<Device>> getAll() {
Promise<List<Device>> promise = Promise.promise();
String query = QueryBuilder.select(Device.class).build();
db.execute(query, Device.class,
list -> promise.complete(list.isEmpty() ? List.of() : list),
promise::fail
);
return promise.future();
}
public Future<List<Device>> getAllByGroupId(Integer groupId) {
Promise<List<Device>> promise = Promise.promise();
Device device = new Device();
device.setGroupId(groupId);
String query = QueryBuilder
.select(Device.class)
.where(device)
.build();
db.execute(query, Device.class,
list -> promise.complete(list.isEmpty() ? List.of() : list),
promise::fail
);
return promise.future();
}
@Override
public Future<Device> getById(String id) {
Promise<Device> promise = Promise.promise();
Device device = new Device();
device.setDeviceId(id);
String query = QueryBuilder
.select(Device.class)
.where(device)
.build();
db.execute(query, Device.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
public Future<Device> getByIdAndGroupId(String id, Integer groupId) {
Promise<Device> promise = Promise.promise();
Device device = new Device();
device.setDeviceId(id);
device.setGroupId(groupId);
String query = QueryBuilder
.select(Device.class)
.where(device)
.build();
db.execute(query, Device.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
@Override
public Future<Device> insert(Device t) {
Promise<Device> promise = Promise.promise();
String query = QueryBuilder.insert(t).build();
db.execute(query, Device.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
@Override
public Future<Device> update(Device t) {
Promise<Device> promise = Promise.promise();
String query = QueryBuilder.update(t).build();
db.execute(query, Device.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
@Override
public Future<Device> delete(String id) {
Promise<Device> promise = Promise.promise();
Device device = new Device();
device.setDeviceId(id);
String query = QueryBuilder.delete(device).build();
db.execute(query, Device.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
}

View File

@@ -0,0 +1,81 @@
package net.miarma.contaminus.dao;
import java.util.List;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.sqlclient.Pool;
import net.miarma.contaminus.db.DataAccessObject;
import net.miarma.contaminus.db.DatabaseManager;
import net.miarma.contaminus.db.QueryBuilder;
import net.miarma.contaminus.entities.GpsValue;
public class GpsValueDAO implements DataAccessObject<GpsValue, Integer> {
private final DatabaseManager db;
public GpsValueDAO(Pool pool) {
this.db = DatabaseManager.getInstance(pool);
}
@Override
public Future<List<GpsValue>> getAll() {
Promise<List<GpsValue>> promise = Promise.promise();
String query = QueryBuilder.select(GpsValue.class).build();
db.execute(query, GpsValue.class,
list -> promise.complete(list.isEmpty() ? List.of() : list),
promise::fail
);
return promise.future();
}
@Override
public Future<GpsValue> getById(Integer id) {
Promise<GpsValue> promise = Promise.promise();
GpsValue gpsValue = new GpsValue();
gpsValue.setValueId(id);
String query = QueryBuilder
.select(GpsValue.class)
.where(gpsValue)
.build();
db.execute(query, GpsValue.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
@Override
public Future<GpsValue> insert(GpsValue t) {
Promise<GpsValue> promise = Promise.promise();
String query = QueryBuilder.insert(t).build();
db.execute(query, GpsValue.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
@Override
public Future<GpsValue> update(GpsValue t) {
Promise<GpsValue> promise = Promise.promise();
String query = QueryBuilder.update(t).build();
db.execute(query, GpsValue.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
@Override
public Future<GpsValue> delete(Integer id) {
throw new UnsupportedOperationException("Cannot delete samples");
}
}

View File

@@ -0,0 +1,93 @@
package net.miarma.contaminus.dao;
import java.util.List;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.sqlclient.Pool;
import net.miarma.contaminus.db.DataAccessObject;
import net.miarma.contaminus.db.DatabaseManager;
import net.miarma.contaminus.db.QueryBuilder;
import net.miarma.contaminus.entities.Group;
public class GroupDAO implements DataAccessObject<Group, Integer> {
private final DatabaseManager db;
public GroupDAO(Pool pool) {
this.db = DatabaseManager.getInstance(pool);
}
@Override
public Future<List<Group>> getAll() {
Promise<List<Group>> promise = Promise.promise();
String query = QueryBuilder.select(Group.class).build();
db.execute(query, Group.class,
list -> promise.complete(list.isEmpty() ? List.of() : list),
promise::fail
);
return promise.future();
}
@Override
public Future<Group> getById(Integer id) {
Promise<Group> promise = Promise.promise();
Group group = new Group();
group.setGroupId(id);
String query = QueryBuilder
.select(Group.class)
.where(group)
.build();
db.execute(query, Group.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
@Override
public Future<Group> insert(Group t) {
Promise<Group> promise = Promise.promise();
String query = QueryBuilder.insert(t).build();
db.execute(query, Group.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
@Override
public Future<Group> update(Group t) {
Promise<Group> promise = Promise.promise();
String query = QueryBuilder.update(t).build();
db.execute(query, Group.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
@Override
public Future<Group> delete(Integer id) {
Promise<Group> promise = Promise.promise();
Group group = new Group();
group.setGroupId(id);
String query = QueryBuilder.delete(group).build();
db.execute(query, Group.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
}

View File

@@ -0,0 +1,130 @@
package net.miarma.contaminus.dao;
import java.util.List;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.sqlclient.Pool;
import net.miarma.contaminus.db.DataAccessObject;
import net.miarma.contaminus.db.DatabaseManager;
import net.miarma.contaminus.db.QueryBuilder;
import net.miarma.contaminus.entities.Sensor;
public class SensorDAO implements DataAccessObject<Sensor, Integer> {
private final DatabaseManager db;
public SensorDAO(Pool pool) {
this.db = DatabaseManager.getInstance(pool);
}
@Override
public Future<List<Sensor>> getAll() {
Promise<List<Sensor>> promise = Promise.promise();
String query = QueryBuilder.select(Sensor.class).build();
db.execute(query, Sensor.class,
list -> promise.complete(list.isEmpty() ? List.of() : list),
promise::fail
);
return promise.future();
}
public Future<List<Sensor>> getAllByDeviceId(String deviceId) {
Promise<List<Sensor>> promise = Promise.promise();
Sensor sensor = new Sensor();
sensor.setDeviceId(deviceId);
String query = QueryBuilder
.select(Sensor.class)
.where(sensor)
.build();
db.execute(query, Sensor.class,
list -> promise.complete(list.isEmpty() ? List.of() : list),
promise::fail
);
return promise.future();
}
@Override
public Future<Sensor> getById(Integer id) {
Promise<Sensor> promise = Promise.promise();
Sensor sensor = new Sensor();
sensor.setSensorId(id);
String query = QueryBuilder
.select(Sensor.class)
.where(sensor)
.build();
db.execute(query, Sensor.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
public Future<Sensor> getByIdAndDeviceId(Integer sensorId, String deviceId) {
Promise<Sensor> promise = Promise.promise();
Sensor sensor = new Sensor();
sensor.setDeviceId(deviceId);
sensor.setSensorId(sensorId);
String query = QueryBuilder
.select(Sensor.class)
.where(sensor)
.build();
db.execute(query, Sensor.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
@Override
public Future<Sensor> insert(Sensor t) {
Promise<Sensor> promise = Promise.promise();
String query = QueryBuilder.insert(t).build();
db.execute(query, Sensor.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
@Override
public Future<Sensor> update(Sensor t) {
Promise<Sensor> promise = Promise.promise();
String query = QueryBuilder.update(t).build();
db.execute(query, Sensor.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
@Override
public Future<Sensor> delete(Integer id) {
Promise<Sensor> promise = Promise.promise();
Sensor sensor = new Sensor();
sensor.setSensorId(id);
String query = QueryBuilder.delete(sensor).build();
db.execute(query, Sensor.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
}

View File

@@ -0,0 +1,81 @@
package net.miarma.contaminus.dao;
import java.util.List;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.sqlclient.Pool;
import net.miarma.contaminus.db.DataAccessObject;
import net.miarma.contaminus.db.DatabaseManager;
import net.miarma.contaminus.db.QueryBuilder;
import net.miarma.contaminus.entities.WeatherValue;
public class WeatherValueDAO implements DataAccessObject<WeatherValue, Integer> {
private final DatabaseManager db;
public WeatherValueDAO(Pool pool) {
this.db = DatabaseManager.getInstance(pool);
}
@Override
public Future<List<WeatherValue>> getAll() {
Promise<List<WeatherValue>> promise = Promise.promise();
String query = QueryBuilder.select(WeatherValue.class).build();
db.execute(query, WeatherValue.class,
list -> promise.complete(list.isEmpty() ? List.of() : list),
promise::fail
);
return promise.future();
}
@Override
public Future<WeatherValue> getById(Integer id) {
Promise<WeatherValue> promise = Promise.promise();
WeatherValue weatherValue = new WeatherValue();
weatherValue.setValueId(id);
String query = QueryBuilder
.select(WeatherValue.class)
.where(weatherValue)
.build();
db.execute(query, WeatherValue.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
@Override
public Future<WeatherValue> insert(WeatherValue t) {
Promise<WeatherValue> promise = Promise.promise();
String query = QueryBuilder.insert(t).build();
db.execute(query, WeatherValue.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
@Override
public Future<WeatherValue> update(WeatherValue t) {
Promise<WeatherValue> promise = Promise.promise();
String query = QueryBuilder.update(t).build();
db.execute(query, WeatherValue.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
@Override
public Future<WeatherValue> delete(Integer id) {
throw new UnsupportedOperationException("Cannot delete samples");
}
}

View File

@@ -0,0 +1,66 @@
package net.miarma.contaminus.dao.views;
import java.util.List;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.sqlclient.Pool;
import net.miarma.contaminus.db.DataAccessObject;
import net.miarma.contaminus.db.DatabaseManager;
import net.miarma.contaminus.db.QueryBuilder;
import net.miarma.contaminus.entities.ViewLatestValues;
public class ViewLatestValuesDAO implements DataAccessObject<ViewLatestValues, String> {
private final DatabaseManager db;
public ViewLatestValuesDAO(Pool pool) {
this.db = DatabaseManager.getInstance(pool);
}
@Override
public Future<List<ViewLatestValues>> getAll() {
Promise<List<ViewLatestValues>> promise = Promise.promise();
String query = QueryBuilder.select(ViewLatestValues.class).build();
db.execute(query, ViewLatestValues.class,
list -> promise.complete(list.isEmpty() ? List.of() : list),
promise::fail
);
return promise.future();
}
@Override
public Future<ViewLatestValues> getById(String id) {
Promise<ViewLatestValues> promise = Promise.promise();
ViewLatestValues view = new ViewLatestValues();
view.setDeviceId(id);
String query = QueryBuilder
.select(ViewLatestValues.class)
.where(view)
.build();
db.execute(query, ViewLatestValues.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
@Override
public Future<ViewLatestValues> insert(ViewLatestValues t) {
throw new UnsupportedOperationException("Insert not supported for views");
}
@Override
public Future<ViewLatestValues> update(ViewLatestValues t) {
throw new UnsupportedOperationException("Update not supported for views");
}
@Override
public Future<ViewLatestValues> delete(String id) {
throw new UnsupportedOperationException("Delete not supported for views");
}
}

View File

@@ -0,0 +1,66 @@
package net.miarma.contaminus.dao.views;
import java.util.List;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.sqlclient.Pool;
import net.miarma.contaminus.common.Table;
import net.miarma.contaminus.db.DataAccessObject;
import net.miarma.contaminus.db.DatabaseManager;
import net.miarma.contaminus.db.QueryBuilder;
import net.miarma.contaminus.entities.ViewPollutionMap;
@Table("v_pollution_map")
public class ViewPollutionMapDAO implements DataAccessObject<ViewPollutionMap, String> {
private final DatabaseManager db;
public ViewPollutionMapDAO(Pool pool) {
this.db = DatabaseManager.getInstance(pool);
}
@Override
public Future<List<ViewPollutionMap>> getAll() {
Promise<List<ViewPollutionMap>> promise = Promise.promise();
String query = QueryBuilder.select(ViewPollutionMap.class).build();
db.execute(query, ViewPollutionMap.class,
list -> promise.complete(list.isEmpty() ? List.of() : list),
promise::fail
);
return promise.future();
}
@Override
public Future<ViewPollutionMap> getById(String id) {
Promise<ViewPollutionMap> promise = Promise.promise();
ViewPollutionMap view = new ViewPollutionMap();
view.setDeviceId(id);
String query = QueryBuilder
.select(ViewPollutionMap.class)
.where(view)
.build();
db.execute(query, ViewPollutionMap.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
@Override
public Future<ViewPollutionMap> insert(ViewPollutionMap t) {
throw new UnsupportedOperationException("Insert not supported for views");
}
@Override
public Future<ViewPollutionMap> update(ViewPollutionMap t) {
throw new UnsupportedOperationException("Update not supported for views");
}
@Override
public Future<ViewPollutionMap> delete(String id) {
throw new UnsupportedOperationException("Delete not supported for views");
}
}

View File

@@ -0,0 +1,67 @@
package net.miarma.contaminus.dao.views;
import java.util.List;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.sqlclient.Pool;
import net.miarma.contaminus.db.DataAccessObject;
import net.miarma.contaminus.db.DatabaseManager;
import net.miarma.contaminus.db.QueryBuilder;
import net.miarma.contaminus.entities.ViewSensorHistory;
public class ViewSensorHistoryDAO implements DataAccessObject<ViewSensorHistory, String> {
private final DatabaseManager db;
public ViewSensorHistoryDAO(Pool pool) {
this.db = DatabaseManager.getInstance(pool);
}
@Override
public Future<List<ViewSensorHistory>> getAll() {
Promise<List<ViewSensorHistory>> promise = Promise.promise();
String query = QueryBuilder.select(ViewSensorHistory.class).build();
db.execute(query, ViewSensorHistory.class,
list -> promise.complete(list.isEmpty() ? List.of() : list),
promise::fail
);
return promise.future();
}
@Override
public Future<ViewSensorHistory> getById(String id) {
Promise<ViewSensorHistory> promise = Promise.promise();
ViewSensorHistory viewSensorHistory = new ViewSensorHistory();
viewSensorHistory.setDeviceId(id);
String query = QueryBuilder
.select(ViewSensorHistory.class)
.where(viewSensorHistory)
.build();
db.execute(query, ViewSensorHistory.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
@Override
public Future<ViewSensorHistory> insert(ViewSensorHistory t) {
throw new UnsupportedOperationException("Insert not supported for views");
}
@Override
public Future<ViewSensorHistory> update(ViewSensorHistory t) {
throw new UnsupportedOperationException("Update not supported for views");
}
@Override
public Future<ViewSensorHistory> delete(String id) {
throw new UnsupportedOperationException("Delete not supported for views");
}
}

View File

@@ -0,0 +1,66 @@
package net.miarma.contaminus.dao.views;
import java.util.List;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.sqlclient.Pool;
import net.miarma.contaminus.db.DataAccessObject;
import net.miarma.contaminus.db.DatabaseManager;
import net.miarma.contaminus.db.QueryBuilder;
import net.miarma.contaminus.entities.ViewSensorValue;
public class ViewSensorValueDAO implements DataAccessObject<ViewSensorValue, Integer> {
private final DatabaseManager db;
public ViewSensorValueDAO(Pool pool) {
this.db = DatabaseManager.getInstance(pool);
}
@Override
public Future<List<ViewSensorValue>> getAll() {
Promise<List<ViewSensorValue>> promise = Promise.promise();
String query = QueryBuilder.select(ViewSensorValue.class).build();
db.execute(query, ViewSensorValue.class,
list -> promise.complete(list.isEmpty() ? List.of() : list),
promise::fail
);
return promise.future();
}
@Override
public Future<ViewSensorValue> getById(Integer id) {
Promise<ViewSensorValue> promise = Promise.promise();
ViewSensorValue view = new ViewSensorValue();
view.setSensorId(id);
String query = QueryBuilder
.select(ViewSensorValue.class)
.where(view)
.build();
db.execute(query, ViewSensorValue.class,
list -> promise.complete(list.isEmpty() ? null : list.get(0)),
promise::fail
);
return promise.future();
}
@Override
public Future<ViewSensorValue> insert(ViewSensorValue t) {
throw new UnsupportedOperationException("Insert not supported for views");
}
@Override
public Future<ViewSensorValue> update(ViewSensorValue t) {
throw new UnsupportedOperationException("Update not supported for views");
}
@Override
public Future<ViewSensorValue> delete(Integer id) {
throw new UnsupportedOperationException("Delete not supported for views");
}
}

View File

@@ -1,58 +0,0 @@
package net.miarma.contaminus.database;
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 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;
}
public static synchronized DatabaseManager getInstance(JDBCPool pool) {
if (instance == null) {
instance = new DatabaseManager(pool);
}
return instance;
}
public Future<RowSet<Row>> testConnection() {
return pool.query("SELECT 1").execute();
}
public <T> Future<List<T>> execute(String query, Class<T> clazz,
Handler<List<T>> onSuccess, Handler<Throwable> onFailure) {
return pool.query(query).execute()
.map(rows -> {
List<T> results = new ArrayList<>();
for (Row row : rows) {
try {
Constructor<T> 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());
}
});
}
}

View File

@@ -1,196 +0,0 @@
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 String sort;
private String order;
private String limit;
public QueryBuilder() {
this.query = new StringBuilder();
}
private static <T> String getTableName(Class<T> clazz) {
if (clazz == null) {
throw new IllegalArgumentException("Class cannot be null");
}
if (clazz.isAnnotationPresent(Table.class)) {
Table annotation = clazz.getAnnotation(Table.class);
return annotation.value();
}
throw new IllegalArgumentException("Class does not have @Table annotation");
}
public String getQuery() {
return query.toString();
}
public static <T> QueryBuilder select(Class<T> clazz, String... columns) {
if (clazz == null) {
throw new IllegalArgumentException("Class cannot be null");
}
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) {
if (column != null) {
joiner.add(column);
}
}
qb.query.append(joiner).append(" ");
}
qb.query.append("FROM ").append(tableName).append(" ");
return qb;
}
public static <T> QueryBuilder where(QueryBuilder qb, T object) {
if (qb == null || object == null) {
throw new IllegalArgumentException("QueryBuilder and object cannot be null");
}
List<String> 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());
}
}
if (!conditions.isEmpty()) {
qb.query.append("WHERE ").append(String.join(" AND ", conditions)).append(" ");
}
return qb;
}
public static <T> QueryBuilder select(T object, String... columns) {
if (object == null) {
throw new IllegalArgumentException("Object cannot be null");
}
Class<?> clazz = object.getClass();
QueryBuilder qb = select(clazz, columns);
return where(qb, object);
}
public static <T> QueryBuilder insert(T object) {
if (object == null) {
throw new IllegalArgumentException("Object cannot be null");
}
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());
Object fieldValue = field.get(object);
if (fieldValue != null) {
if (fieldValue instanceof String) {
values.add("'" + fieldValue + "'");
} else {
values.add(fieldValue.toString());
}
} else {
values.add("NULL");
}
} 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 static <T> QueryBuilder update(T object) {
if (object == null) {
throw new IllegalArgumentException("Object cannot be null");
}
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 {
Object fieldValue = field.get(object);
if (fieldValue != null) {
if (fieldValue instanceof String) {
joiner.add(field.getName() + " = '" + fieldValue + "'");
} else {
joiner.add(field.getName() + " = " + fieldValue.toString());
}
} else {
joiner.add(field.getName() + " = NULL");
}
} catch (IllegalArgumentException | IllegalAccessException e) {
Constants.LOGGER.error("(REFLECTION) Error reading field: " + e.getMessage());
}
}
qb.query.append(joiner).append(" ");
return qb;
}
public QueryBuilder orderBy(Optional<String> column, Optional<String> order) {
column.ifPresent(c -> {
sort = "ORDER BY " + c + " ";
order.ifPresent(o -> {
sort += o.equalsIgnoreCase("asc") ? "ASC" : "DESC" + " ";
});
});
return this;
}
public QueryBuilder limit(Optional<Integer> limitParam) {
limitParam.ifPresent(param -> limit = "LIMIT " + param + " ");
return this;
}
public String build() {
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() + ";";
}
}

View File

@@ -1,67 +0,0 @@
package net.miarma.contaminus.database.entities;
import java.util.Objects;
import io.vertx.sqlclient.Row;
import net.miarma.contaminus.common.Table;
import net.miarma.contaminus.util.DateParser;
@Table("v_co_by_device")
public class DeviceCO {
private String deviceId;
private Float carbonMonoxide;
private Long timestamp;
public DeviceCO() {}
public DeviceCO(Row row) {
this.deviceId = row.getString("deviceId");
this.carbonMonoxide = row.getFloat("carbonMonoxide");
this.timestamp = DateParser.parseDate(row.getLocalDateTime("timestamp"));
}
public DeviceCO(String deviceId, Float carbonMonoxide, Long timestamp) {
super();
this.deviceId = deviceId;
this.carbonMonoxide = carbonMonoxide;
this.timestamp = timestamp;
}
public String getDeviceId() {
return deviceId;
}
public Float getCarbonMonoxide() {
return carbonMonoxide;
}
public Long getTimestamp() {
return timestamp;
}
@Override
public int hashCode() {
return Objects.hash(carbonMonoxide, deviceId, timestamp);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
DeviceCO other = (DeviceCO) obj;
return Objects.equals(carbonMonoxide, other.carbonMonoxide) && Objects.equals(deviceId, other.deviceId)
&& Objects.equals(timestamp, other.timestamp);
}
@Override
public String toString() {
return "DeviceCO [deviceId=" + deviceId + ", carbonMonoxide=" + carbonMonoxide + ", timestamp=" + timestamp
+ "]";
}
}

View File

@@ -1,72 +0,0 @@
package net.miarma.contaminus.database.entities;
import java.util.Objects;
import io.vertx.sqlclient.Row;
import net.miarma.contaminus.common.Table;
import net.miarma.contaminus.util.DateParser;
@Table("v_gps_by_device")
public class DeviceGPS {
private String deviceId;
private Float lat;
private Float lon;
private Long timestamp;
public DeviceGPS() {}
public DeviceGPS(Row row) {
this.deviceId = row.getString("deviceId");
this.lat = row.getFloat("lat");
this.lon = row.getFloat("lon");
this.timestamp = DateParser.parseDate(row.getLocalDateTime("timestamp"));
}
public DeviceGPS(String deviceId, Float lat, Float lon) {
super();
this.deviceId = deviceId;
this.lat = lat;
this.lon = lon;
}
public String getDeviceId() {
return deviceId;
}
public Float getLat() {
return lat;
}
public Float getLon() {
return lon;
}
public Long getTimestamp() {
return timestamp;
}
@Override
public int hashCode() {
return Objects.hash(deviceId, lat, lon, timestamp);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
DeviceGPS other = (DeviceGPS) obj;
return Objects.equals(deviceId, other.deviceId) && Objects.equals(lat, other.lat)
&& Objects.equals(lon, other.lon) && Objects.equals(timestamp, other.timestamp);
}
@Override
public String toString() {
return "DeviceGPS [deviceId=" + deviceId + ", lat=" + lat + ", lon=" + lon + ", timestamp=" + timestamp + "]";
}
}

View File

@@ -1,74 +0,0 @@
package net.miarma.contaminus.database.entities;
import java.util.Objects;
import io.vertx.sqlclient.Row;
import net.miarma.contaminus.common.Table;
import net.miarma.contaminus.util.DateParser;
@Table("v_weather_by_device")
public class DeviceWeather {
private String deviceId;
private Float temperature;
private Float humidity;
private Long timestamp;
public DeviceWeather() {}
public DeviceWeather(Row row) {
this.deviceId = row.getString("deviceId");
this.temperature = row.getFloat("temperature");
this.humidity = row.getFloat("humidity");
this.timestamp = DateParser.parseDate(row.getLocalDateTime("timestamp"));
}
public DeviceWeather(String deviceId, Float temperature, Float humidity, Long timestamp) {
super();
this.deviceId = deviceId;
this.temperature = temperature;
this.humidity = humidity;
this.timestamp = timestamp;
}
public String getDeviceId() {
return deviceId;
}
public Float getTemperature() {
return temperature;
}
public Float getHumidity() {
return humidity;
}
public Long getTimestamp() {
return timestamp;
}
@Override
public int hashCode() {
return Objects.hash(deviceId, humidity, temperature, timestamp);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
DeviceWeather other = (DeviceWeather) obj;
return Objects.equals(deviceId, other.deviceId) && Objects.equals(humidity, other.humidity)
&& Objects.equals(temperature, other.temperature) && Objects.equals(timestamp, other.timestamp);
}
@Override
public String toString() {
return "DeviceWeather [deviceId=" + deviceId + ", temperature=" + temperature + ", humidity=" + humidity
+ ", timestamp=" + timestamp + "]";
}
}

View File

@@ -0,0 +1,13 @@
package net.miarma.contaminus.db;
import java.util.List;
import io.vertx.core.Future;
public interface DataAccessObject<T, ID> {
Future<List<T>> getAll();
Future<T> getById(ID id);
Future<T> insert(T t);
Future<T> update(T t);
Future<T> delete(ID id);
}

View File

@@ -0,0 +1,82 @@
package net.miarma.contaminus.db;
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.sqlclient.Pool;
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 Pool pool;
private DatabaseManager(Pool pool) {
this.pool = pool;
}
public static synchronized DatabaseManager getInstance(Pool pool) {
if (instance == null) {
instance = new DatabaseManager(pool);
}
return instance;
}
public Pool getPool() {
return pool;
}
public Future<RowSet<Row>> testConnection() {
return pool.query("SELECT 1").execute();
}
public <T> Future<List<T>> execute(String query, Class<T> clazz, Handler<List<T>> onSuccess,
Handler<Throwable> onFailure) {
return pool.query(query).execute().map(rows -> {
List<T> results = new ArrayList<>();
for (Row row : rows) {
try {
Constructor<T> 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());
}
});
}
public <T> Future<T> executeOne(String query, Class<T> clazz, Handler<T> onSuccess, Handler<Throwable> onFailure) {
return pool.query(query).execute().map(rows -> {
for (Row row : rows) {
try {
Constructor<T> constructor = clazz.getConstructor(Row.class);
return constructor.newInstance(row);
} catch (Exception e) {
Constants.LOGGER.error("Error instantiating class: " + e.getMessage());
}
}
return null; // Si no hay filas
}).onComplete(ar -> {
if (ar.succeeded()) {
onSuccess.handle(ar.result());
} else {
onFailure.handle(ar.cause());
}
});
}
}

View File

@@ -0,0 +1,21 @@
package net.miarma.contaminus.db;
import io.vertx.core.Vertx;
import io.vertx.mysqlclient.MySQLConnectOptions;
import io.vertx.sqlclient.Pool;
import io.vertx.sqlclient.PoolOptions;
import net.miarma.contaminus.common.ConfigManager;
public class DatabaseProvider {
public static Pool createPool(Vertx vertx, ConfigManager config) {
MySQLConnectOptions connectOptions = new MySQLConnectOptions()
.setPort(config.getIntProperty("db.port"))
.setHost(config.getStringProperty("db.host"))
.setDatabase(config.getStringProperty("db.name"))
.setUser(config.getStringProperty("db.user"))
.setPassword(config.getStringProperty("db.password"));
PoolOptions poolOptions = new PoolOptions().setMaxSize(10);
return Pool.pool(vertx, connectOptions, poolOptions);
}
}

View File

@@ -0,0 +1,357 @@
package net.miarma.contaminus.db;
import java.lang.reflect.Field;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.StringJoiner;
import java.util.stream.Collectors;
import net.miarma.contaminus.common.Constants;
import net.miarma.contaminus.common.Table;
public class QueryBuilder {
private final StringBuilder query;
private String sort;
private String order;
private String limit;
private Class<?> entityClass;
public QueryBuilder() {
this.query = new StringBuilder();
}
private static <T> String getTableName(Class<T> clazz) {
if (clazz == null) {
throw new IllegalArgumentException("Class cannot be null");
}
if (clazz.isAnnotationPresent(Table.class)) {
Table annotation = clazz.getAnnotation(Table.class);
return annotation.value();
}
throw new IllegalArgumentException("Class does not have @Table annotation");
}
public String getQuery() {
return query.toString();
}
private static Object extractValue(Object fieldValue) {
if (fieldValue instanceof Enum<?>) {
try {
var method = fieldValue.getClass().getMethod("getValue");
return method.invoke(fieldValue);
} catch (Exception e) {
return ((Enum<?>) fieldValue).name();
}
}
return fieldValue;
}
public static <T> QueryBuilder select(Class<T> clazz, String... columns) {
if (clazz == null) {
throw new IllegalArgumentException("Class cannot be null");
}
QueryBuilder qb = new QueryBuilder();
qb.entityClass = clazz;
String tableName = getTableName(clazz);
qb.query.append("SELECT ");
if (columns.length == 0) {
qb.query.append("* ");
} else {
StringJoiner joiner = new StringJoiner(", ");
for (String column : columns) {
if (column != null) {
joiner.add(column);
}
}
qb.query.append(joiner).append(" ");
}
qb.query.append("FROM ").append(tableName).append(" ");
return qb;
}
public QueryBuilder where(Map<String, String> filters) {
if (filters == null || filters.isEmpty()) {
return this;
}
Set<String> validFields = entityClass != null
? Arrays.stream(entityClass.getDeclaredFields()).map(Field::getName).collect(Collectors.toSet())
: Collections.emptySet();
List<String> conditions = new ArrayList<>();
for (Map.Entry<String, String> entry : filters.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
if (!validFields.contains(key)) {
Constants.LOGGER.warn("[QueryBuilder] Ignorando campo invalido en WHERE: " + key);
continue;
}
if (value.startsWith("(") && value.endsWith(")")) {
conditions.add(key + " IN " + value);
} else if (value.matches("-?\\d+(\\.\\d+)?")) {
conditions.add(key + " = " + value);
} else {
conditions.add(key + " = '" + value + "'");
}
}
if (!conditions.isEmpty()) {
query.append("WHERE ").append(String.join(" AND ", conditions)).append(" ");
}
return this;
}
public <T> QueryBuilder where(T object) {
if (object == null) {
throw new IllegalArgumentException("Object cannot be null");
}
Set<String> validFields = entityClass != null
? Arrays.stream(entityClass.getDeclaredFields()).map(Field::getName).collect(Collectors.toSet())
: Collections.emptySet();
List<String> conditions = new ArrayList<>();
for (Field field : object.getClass().getDeclaredFields()) {
field.setAccessible(true);
try {
Object fieldValue = field.get(object);
if (fieldValue != null) {
String key = field.getName();
if (!validFields.contains(key)) {
Constants.LOGGER.warn("[QueryBuilder] Ignorando campo invalido en WHERE: " + key);
continue;
}
Object value = extractValue(fieldValue);
if (value instanceof String || value instanceof LocalDateTime) {
conditions.add(key + " = '" + value + "'");
} else {
conditions.add(key + " = " + value);
}
}
} catch (IllegalArgumentException | IllegalAccessException e) {
Constants.LOGGER.error("(REFLECTION) Error reading field: " + e.getMessage());
}
}
if (!conditions.isEmpty()) {
query.append("WHERE ").append(String.join(" AND ", conditions)).append(" ");
}
return this;
}
public static <T> QueryBuilder insert(T object) {
if (object == null) {
throw new IllegalArgumentException("Object cannot be null");
}
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());
Object fieldValue = field.get(object);
if (fieldValue != null) {
Object value = extractValue(fieldValue);
if (value instanceof String || value instanceof LocalDateTime) {
values.add("'" + value + "'");
} else {
values.add(value.toString());
}
} else {
values.add("NULL");
}
} 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(") RETURNING * ");
return qb;
}
public static <T> QueryBuilder update(T object) {
if (object == null) {
throw new IllegalArgumentException("Object cannot be null");
}
QueryBuilder qb = new QueryBuilder();
String table = getTableName(object.getClass());
qb.query.append("UPDATE ").append(table).append(" SET ");
StringJoiner setJoiner = new StringJoiner(", ");
StringJoiner whereJoiner = new StringJoiner(" AND ");
Field idField = null;
for (Field field : object.getClass().getDeclaredFields()) {
field.setAccessible(true);
try {
Object fieldValue = field.get(object);
if (fieldValue == null) continue;
String fieldName = field.getName();
Object value = extractValue(fieldValue);
if (fieldName.endsWith("_id")) {
idField = field;
whereJoiner.add(fieldName + " = " + (value instanceof String
|| value instanceof LocalDateTime ? "'" + value + "'" : value));
continue;
}
setJoiner.add(fieldName + " = " + (value instanceof String
|| value instanceof LocalDateTime ? "'" + value + "'" : value));
} catch (Exception e) {
Constants.LOGGER.error("(REFLECTION) Error reading field: " + e.getMessage());
}
}
if (idField == null) {
throw new IllegalArgumentException("No ID field (ending with _id) found for WHERE clause");
}
qb.query.append(setJoiner).append(" WHERE ").append(whereJoiner);
return qb;
}
public static <T> QueryBuilder updateWithNulls(T object) {
if (object == null) {
throw new IllegalArgumentException("Object cannot be null");
}
QueryBuilder qb = new QueryBuilder();
String table = getTableName(object.getClass());
qb.query.append("UPDATE ").append(table).append(" SET ");
StringJoiner setJoiner = new StringJoiner(", ");
StringJoiner whereJoiner = new StringJoiner(" AND ");
Field idField = null;
for (Field field : object.getClass().getDeclaredFields()) {
field.setAccessible(true);
try {
String fieldName = field.getName();
Object fieldValue = field.get(object);
if (fieldName.endsWith("_id")) {
idField = field;
Object value = extractValue(fieldValue);
whereJoiner.add(fieldName + " = " + (value instanceof String || value instanceof LocalDateTime ? "'" + value + "'" : value));
continue;
}
if (fieldValue == null) {
setJoiner.add(fieldName + " = NULL"); // ✅ esto lo borra en la BD
} else {
Object value = extractValue(fieldValue);
setJoiner.add(fieldName + " = " + (value instanceof String || value instanceof LocalDateTime ? "'" + value + "'" : value));
}
} catch (Exception e) {
Constants.LOGGER.error("(REFLECTION) Error reading field: " + e.getMessage());
}
}
if (idField == null) {
throw new IllegalArgumentException("No ID field (ending with _id) found for WHERE clause");
}
qb.query.append(setJoiner).append(" WHERE ").append(whereJoiner);
return qb;
}
public static <T> QueryBuilder delete(T object) {
if (object == null) throw new IllegalArgumentException("Object cannot be null");
QueryBuilder qb = new QueryBuilder();
String table = getTableName(object.getClass());
qb.query.append("DELETE FROM ").append(table).append(" WHERE ");
StringJoiner joiner = new StringJoiner(" AND ");
for (Field field : object.getClass().getDeclaredFields()) {
field.setAccessible(true);
try {
Object fieldValue = field.get(object);
if (fieldValue != null) {
Object value = extractValue(fieldValue);
joiner.add(field.getName() + " = " + (value instanceof String
|| value instanceof LocalDateTime ? "'" + value + "'" : value.toString()));
}
} catch (Exception e) {
Constants.LOGGER.error("(REFLECTION) Error reading field: " + e.getMessage());
}
}
qb.query.append(joiner).append(" ");
return qb;
}
public QueryBuilder orderBy(Optional<String> column, Optional<String> order) {
column.ifPresent(c -> {
if (entityClass != null) {
boolean isValid = Arrays.stream(entityClass.getDeclaredFields())
.map(Field::getName)
.anyMatch(f -> f.equals(c));
if (!isValid) {
Constants.LOGGER.warn("[QueryBuilder] Ignorando campo invalido en ORDER BY: " + c);
return;
}
}
sort = "ORDER BY " + c + " ";
order.ifPresent(o -> {
sort += o.equalsIgnoreCase("asc") ? "ASC" : "DESC" + " ";
});
});
return this;
}
public QueryBuilder limit(Optional<Integer> limitParam) {
limitParam.ifPresent(param -> limit = "LIMIT " + param + " ");
return this;
}
public QueryBuilder offset(Optional<Integer> offsetParam) {
offsetParam.ifPresent(param -> limit += "OFFSET " + param + " ");
return this;
}
public String build() {
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() + ";";
}
}

View File

@@ -1,92 +1,92 @@
package net.miarma.contaminus.database.entities;
import java.util.Objects;
import io.vertx.sqlclient.Row;
import net.miarma.contaminus.common.Table;
import net.miarma.contaminus.util.DateParser;
@Table("actuators")
public class Actuator {
private Integer actuatorId;
private String deviceId;
private Integer status;
private Long timestamp;
public Actuator() {}
public Actuator(Row row) {
this.actuatorId = row.getInteger("actuatorId");
this.deviceId = row.getString("deviceId");
this.status = row.getInteger("status");
this.timestamp = DateParser.parseDate(row.getLocalDateTime("timestamp"));
}
public Actuator(Integer actuatorId, String deviceId, Integer status, Long timestamp) {
super();
this.actuatorId = actuatorId;
this.deviceId = deviceId;
this.status = status;
this.timestamp = timestamp;
}
public Integer getActuatorId() {
return actuatorId;
}
public void setActuatorId(Integer actuatorId) {
this.actuatorId = actuatorId;
}
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer 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 + "]";
}
package net.miarma.contaminus.entities;
import java.util.Objects;
import io.vertx.sqlclient.Row;
import net.miarma.contaminus.common.Table;
import net.miarma.contaminus.util.DateParser;
@Table("actuators")
public class Actuator {
private Integer actuatorId;
private String deviceId;
private Integer status;
private Long timestamp;
public Actuator() {}
public Actuator(Row row) {
this.actuatorId = row.getInteger("actuatorId");
this.deviceId = row.getString("deviceId");
this.status = row.getInteger("status");
this.timestamp = DateParser.parseDate(row.getLocalDateTime("timestamp"));
}
public Actuator(Integer actuatorId, String deviceId, Integer status, Long timestamp) {
super();
this.actuatorId = actuatorId;
this.deviceId = deviceId;
this.status = status;
this.timestamp = timestamp;
}
public Integer getActuatorId() {
return actuatorId;
}
public void setActuatorId(Integer actuatorId) {
this.actuatorId = actuatorId;
}
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer 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 + "]";
}
}

View File

@@ -1,107 +1,107 @@
package net.miarma.contaminus.database.entities;
import java.util.Objects;
import io.vertx.sqlclient.Row;
import net.miarma.contaminus.common.Table;
import net.miarma.contaminus.util.DateParser;
@Table("co_values")
public class COValue {
private Integer valueId;
private String deviceId;
private Integer sensorId;
private Float value;
private Long timestamp;
public COValue() {}
public COValue(Row row) {
this.valueId = row.getInteger("valueId");
this.deviceId = row.getString("deviceId");
this.sensorId = row.getInteger("sensorId");
this.value = row.getFloat("value");
this.timestamp = DateParser.parseDate(row.getLocalDateTime("timestamp"));
}
public COValue(Integer valueId, String deviceId, Integer sensorId, Float value, Long timestamp) {
super();
this.valueId = valueId;
this.deviceId = deviceId;
this.sensorId = sensorId;
this.value = value;
this.timestamp = timestamp;
}
public Integer getValueId() {
return valueId;
}
public void setValueId(Integer valueId) {
this.valueId = valueId;
}
package net.miarma.contaminus.entities;
import java.util.Objects;
import io.vertx.sqlclient.Row;
import net.miarma.contaminus.common.Table;
import net.miarma.contaminus.util.DateParser;
@Table("co_values")
public class COValue {
private Integer valueId;
private String deviceId;
private Integer sensorId;
private Float value;
private Long timestamp;
public COValue() {}
public COValue(Row row) {
this.valueId = row.getInteger("valueId");
this.deviceId = row.getString("deviceId");
this.sensorId = row.getInteger("sensorId");
this.value = row.getFloat("value");
this.timestamp = DateParser.parseDate(row.getLocalDateTime("timestamp"));
}
public COValue(Integer valueId, String deviceId, Integer sensorId, Float value, Long timestamp) {
super();
this.valueId = valueId;
this.deviceId = deviceId;
this.sensorId = sensorId;
this.value = value;
this.timestamp = timestamp;
}
public Integer getValueId() {
return valueId;
}
public void setValueId(Integer valueId) {
this.valueId = valueId;
}
public String getDeviceId() {
return deviceId;
}
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public Integer getSensorId() {
return sensorId;
}
public void setSensorId(Integer 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(deviceId, 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 Objects.equals(deviceId, other.deviceId) && Objects.equals(sensorId, other.sensorId)
&& Objects.equals(timestamp, other.timestamp) && Objects.equals(value, other.value)
&& Objects.equals(valueId, other.valueId);
}
@Override
public String toString() {
return "COValue [valueId=" + valueId + ", deviceId=" + deviceId + ", sensorId=" + sensorId + ", value=" + value
+ ", timestamp=" + timestamp + "]";
}
}
public Integer getSensorId() {
return sensorId;
}
public void setSensorId(Integer 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(deviceId, 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 Objects.equals(deviceId, other.deviceId) && Objects.equals(sensorId, other.sensorId)
&& Objects.equals(timestamp, other.timestamp) && Objects.equals(value, other.value)
&& Objects.equals(valueId, other.valueId);
}
@Override
public String toString() {
return "COValue [valueId=" + valueId + ", deviceId=" + deviceId + ", sensorId=" + sensorId + ", value=" + value
+ ", timestamp=" + timestamp + "]";
}
public static COValue fromPayload(DevicePayload payload) {
return new COValue(null, payload.getDeviceId(), payload.getSensorId(), payload.getCarbonMonoxide(), payload.getTimestamp());
}
}
}

View File

@@ -1,57 +1,57 @@
package net.miarma.contaminus.database.entities;
import io.vertx.sqlclient.Row;
import net.miarma.contaminus.common.Table;
@Table("devices")
public class Device {
private String deviceId;
private Integer groupId;
private String deviceName;
public Device() {}
public Device(Row row) {
this.deviceId = row.getString("deviceId");
this.groupId = row.getInteger("groupId");
this.deviceName = row.getString("deviceName");
}
public Device(String deviceId, Integer groupId, String deviceName) {
super();
this.deviceId = deviceId;
this.groupId = groupId;
this.deviceName = deviceName;
}
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public Integer getGroupId() {
return groupId;
}
public void setGroupId(Integer groupId) {
this.groupId = groupId;
}
public String getDeviceName() {
return deviceName;
}
public void setDeviceName(String deviceName) {
this.deviceName = deviceName;
}
}
package net.miarma.contaminus.entities;
import io.vertx.sqlclient.Row;
import net.miarma.contaminus.common.Table;
@Table("devices")
public class Device {
private String deviceId;
private Integer groupId;
private String deviceName;
public Device() {}
public Device(Row row) {
this.deviceId = row.getString("deviceId");
this.groupId = row.getInteger("groupId");
this.deviceName = row.getString("deviceName");
}
public Device(String deviceId, Integer groupId, String deviceName) {
super();
this.deviceId = deviceId;
this.groupId = groupId;
this.deviceName = deviceName;
}
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public Integer getGroupId() {
return groupId;
}
public void setGroupId(Integer groupId) {
this.groupId = groupId;
}
public String getDeviceName() {
return deviceName;
}
public void setDeviceName(String deviceName) {
this.deviceName = deviceName;
}
}

View File

@@ -1,130 +1,130 @@
package net.miarma.contaminus.database.entities;
import java.util.Objects;
public class DevicePayload {
private String deviceId;
private Integer sensorId;
private Float temperature;
private Float humidity;
private Float pressure;
private Float carbonMonoxide;
private Float lat;
private Float lon;
private Long timestamp;
public DevicePayload() {}
package net.miarma.contaminus.entities;
import java.util.Objects;
public class DevicePayload {
private String deviceId;
private Integer sensorId;
private Float temperature;
private Float humidity;
private Float pressure;
private Float carbonMonoxide;
private Float lat;
private Float lon;
private Long timestamp;
public DevicePayload() {}
public DevicePayload(String deviceId, Integer sensorId, String sensorType, String unit, Integer sensorStatus,
Float temperature, Float humidity, Float pressure, Float carbonMonoxide, Float lat, Float lon, Long timestamp) {
super();
this.deviceId = deviceId;
this.sensorId = sensorId;
this.temperature = temperature;
this.humidity = humidity;
this.humidity = humidity;
this.pressure = pressure;
this.carbonMonoxide = carbonMonoxide;
this.lat = lat;
this.lon = lon;
this.timestamp = timestamp;
}
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public Integer getSensorId() {
return sensorId;
}
public void setSensorId(Integer 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 String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public Integer getSensorId() {
return sensorId;
}
public void setSensorId(Integer 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 Float getPressure() {
return pressure;
}
public Float getCarbonMonoxide() {
return carbonMonoxide;
}
public void setCarbonMonoxide(Float carbonMonoxide) {
this.carbonMonoxide = carbonMonoxide;
}
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(carbonMonoxide, deviceId, humidity, lat, lon, pressure, sensorId, temperature, timestamp);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
DevicePayload other = (DevicePayload) obj;
return Objects.equals(carbonMonoxide, other.carbonMonoxide) && Objects.equals(deviceId, other.deviceId)
&& Objects.equals(humidity, other.humidity) && Objects.equals(lat, other.lat)
&& Objects.equals(lon, other.lon) && Objects.equals(pressure, other.pressure)
&& Objects.equals(sensorId, other.sensorId) && Objects.equals(temperature, other.temperature)
&& Objects.equals(timestamp, other.timestamp);
}
@Override
public String toString() {
return "DevicePayload [deviceId=" + deviceId + ", sensorId=" + sensorId + ", temperature=" + temperature
+ ", humidity=" + humidity + ", pressure=" + pressure + ", carbonMonoxide=" + carbonMonoxide + ", lat="
+ lat + ", lon=" + lon + ", timestamp=" + timestamp + "]";
}
}
}
public Float getCarbonMonoxide() {
return carbonMonoxide;
}
public void setCarbonMonoxide(Float carbonMonoxide) {
this.carbonMonoxide = carbonMonoxide;
}
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(carbonMonoxide, deviceId, humidity, lat, lon, pressure, sensorId, temperature, timestamp);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
DevicePayload other = (DevicePayload) obj;
return Objects.equals(carbonMonoxide, other.carbonMonoxide) && Objects.equals(deviceId, other.deviceId)
&& Objects.equals(humidity, other.humidity) && Objects.equals(lat, other.lat)
&& Objects.equals(lon, other.lon) && Objects.equals(pressure, other.pressure)
&& Objects.equals(sensorId, other.sensorId) && Objects.equals(temperature, other.temperature)
&& Objects.equals(timestamp, other.timestamp);
}
@Override
public String toString() {
return "DevicePayload [deviceId=" + deviceId + ", sensorId=" + sensorId + ", temperature=" + temperature
+ ", humidity=" + humidity + ", pressure=" + pressure + ", carbonMonoxide=" + carbonMonoxide + ", lat="
+ lat + ", lon=" + lon + ", timestamp=" + timestamp + "]";
}
}

View File

@@ -1,118 +1,118 @@
package net.miarma.contaminus.database.entities;
import java.util.Objects;
import io.vertx.sqlclient.Row;
import net.miarma.contaminus.common.Table;
import net.miarma.contaminus.util.DateParser;
@Table("gps_values")
public class GpsValue {
private Integer valueId;
private String deviceId;
private Integer sensorId;
private Float lat;
private Float lon;
private Long timestamp;
public GpsValue() {}
public GpsValue(Row row) {
this.valueId = row.getInteger("valueId");
this.deviceId = row.getString("deviceId");
this.sensorId = row.getInteger("sensorId");
this.lat = row.getFloat("lat");
this.lon = row.getFloat("lon");
this.timestamp = DateParser.parseDate(row.getLocalDateTime("timestamp"));
}
public GpsValue(Integer valueId, String deviceId, Integer sensorId, Float lat, Float lon, Long timestamp) {
super();
this.valueId = valueId;
this.deviceId = deviceId;
this.sensorId = sensorId;
this.lat = lat;
this.lon = lon;
this.timestamp = timestamp;
}
public Integer getValueId() {
return valueId;
}
public void setValueId(Integer valueId) {
this.valueId = valueId;
}
package net.miarma.contaminus.entities;
import java.util.Objects;
import io.vertx.sqlclient.Row;
import net.miarma.contaminus.common.Table;
import net.miarma.contaminus.util.DateParser;
@Table("gps_values")
public class GpsValue {
private Integer valueId;
private String deviceId;
private Integer sensorId;
private Float lat;
private Float lon;
private Long timestamp;
public GpsValue() {}
public GpsValue(Row row) {
this.valueId = row.getInteger("valueId");
this.deviceId = row.getString("deviceId");
this.sensorId = row.getInteger("sensorId");
this.lat = row.getFloat("lat");
this.lon = row.getFloat("lon");
this.timestamp = DateParser.parseDate(row.getLocalDateTime("timestamp"));
}
public GpsValue(Integer valueId, String deviceId, Integer sensorId, Float lat, Float lon, Long timestamp) {
super();
this.valueId = valueId;
this.deviceId = deviceId;
this.sensorId = sensorId;
this.lat = lat;
this.lon = lon;
this.timestamp = timestamp;
}
public Integer getValueId() {
return valueId;
}
public void setValueId(Integer valueId) {
this.valueId = valueId;
}
public String getDeviceId() {
return deviceId;
}
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public Integer getSensorId() {
return sensorId;
}
public void setSensorId(Integer 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(deviceId, 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 Objects.equals(deviceId, other.deviceId) && Objects.equals(lat, other.lat)
&& Objects.equals(lon, other.lon) && Objects.equals(sensorId, other.sensorId)
&& Objects.equals(timestamp, other.timestamp) && Objects.equals(valueId, other.valueId);
}
@Override
public String toString() {
return "GpsValue [valueId=" + valueId + ", deviceId=" + deviceId + ", sensorId=" + sensorId + ", lat=" + lat
+ ", lon=" + lon + ", timestamp=" + timestamp + "]";
}
}
public Integer getSensorId() {
return sensorId;
}
public void setSensorId(Integer 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(deviceId, 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 Objects.equals(deviceId, other.deviceId) && Objects.equals(lat, other.lat)
&& Objects.equals(lon, other.lon) && Objects.equals(sensorId, other.sensorId)
&& Objects.equals(timestamp, other.timestamp) && Objects.equals(valueId, other.valueId);
}
@Override
public String toString() {
return "GpsValue [valueId=" + valueId + ", deviceId=" + deviceId + ", sensorId=" + sensorId + ", lat=" + lat
+ ", lon=" + lon + ", timestamp=" + timestamp + "]";
}
public static GpsValue fromPayload(DevicePayload payload) {
return new GpsValue(null, payload.getDeviceId(), payload.getSensorId(), payload.getLat(), payload.getLon(),
payload.getTimestamp());
}
}
}

View File

@@ -1,66 +1,66 @@
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 Integer groupId;
private String groupName;
public Group() {}
public Group(Row row) {
this.groupId = row.getInteger("groupId");
this.groupName = row.getString("groupName");
}
public Group(Integer groupId, String groupName) {
super();
this.groupId = groupId;
this.groupName = groupName;
}
public Integer getGroupId() {
return groupId;
}
public void setGroupId(Integer 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 Objects.equals(groupId, other.groupId) && Objects.equals(groupName, other.groupName);
}
@Override
public String toString() {
return "Group [groupId=" + groupId + ", groupName=" + groupName + "]";
}
package net.miarma.contaminus.entities;
import java.util.Objects;
import io.vertx.sqlclient.Row;
import net.miarma.contaminus.common.Table;
@Table("groups")
public class Group {
private Integer groupId;
private String groupName;
public Group() {}
public Group(Row row) {
this.groupId = row.getInteger("groupId");
this.groupName = row.getString("groupName");
}
public Group(Integer groupId, String groupName) {
super();
this.groupId = groupId;
this.groupName = groupName;
}
public Integer getGroupId() {
return groupId;
}
public void setGroupId(Integer 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 Objects.equals(groupId, other.groupId) && Objects.equals(groupName, other.groupName);
}
@Override
public String toString() {
return "Group [groupId=" + groupId + ", groupName=" + groupName + "]";
}
}

View File

@@ -1,114 +1,114 @@
package net.miarma.contaminus.database.entities;
import java.util.Objects;
import io.vertx.sqlclient.Row;
import net.miarma.contaminus.common.Table;
import net.miarma.contaminus.util.DateParser;
@Table("sensors")
public class Sensor {
private Integer sensorId;
private String deviceId;
private String sensorType;
private String unit;
private Integer status;
private Long timestamp;
public Sensor() {}
public Sensor(Row row) {
this.sensorId = row.getInteger("sensorId");
this.deviceId = row.getString("deviceId");
this.sensorType = row.getString("sensorType");
this.unit = row.getString("unit");
this.status = row.getInteger("status");
this.timestamp = DateParser.parseDate(row.getLocalDateTime("timestamp"));
}
public Sensor(Integer sensorId, String deviceId, String sensorType, String unit, Integer status, Long timestamp) {
super();
this.sensorId = sensorId;
this.deviceId = deviceId;
this.sensorType = sensorType;
this.unit = unit;
this.status = status;
this.timestamp = timestamp;
}
public Integer getSensorId() {
return sensorId;
}
public void setSensorId(Integer sensorId) {
this.sensorId = sensorId;
}
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String 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 Integer getStatus() {
return status;
}
public void setStatus(Integer 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 Objects.equals(deviceId, other.deviceId) && Objects.equals(sensorId, other.sensorId)
&& Objects.equals(sensorType, other.sensorType) && Objects.equals(status, other.status)
&& Objects.equals(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 + "]";
}
}
package net.miarma.contaminus.entities;
import java.util.Objects;
import io.vertx.sqlclient.Row;
import net.miarma.contaminus.common.Table;
import net.miarma.contaminus.util.DateParser;
@Table("sensors")
public class Sensor {
private Integer sensorId;
private String deviceId;
private String sensorType;
private String unit;
private Integer status;
private Long timestamp;
public Sensor() {}
public Sensor(Row row) {
this.sensorId = row.getInteger("sensorId");
this.deviceId = row.getString("deviceId");
this.sensorType = row.getString("sensorType");
this.unit = row.getString("unit");
this.status = row.getInteger("status");
this.timestamp = DateParser.parseDate(row.getLocalDateTime("timestamp"));
}
public Sensor(Integer sensorId, String deviceId, String sensorType, String unit, Integer status, Long timestamp) {
super();
this.sensorId = sensorId;
this.deviceId = deviceId;
this.sensorType = sensorType;
this.unit = unit;
this.status = status;
this.timestamp = timestamp;
}
public Integer getSensorId() {
return sensorId;
}
public void setSensorId(Integer sensorId) {
this.sensorId = sensorId;
}
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String 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 Integer getStatus() {
return status;
}
public void setStatus(Integer 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 Objects.equals(deviceId, other.deviceId) && Objects.equals(sensorId, other.sensorId)
&& Objects.equals(sensorType, other.sensorType) && Objects.equals(status, other.status)
&& Objects.equals(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 + "]";
}
}

View File

@@ -1,142 +1,201 @@
package net.miarma.contaminus.database.entities;
import java.util.Objects;
import io.vertx.sqlclient.Row;
import net.miarma.contaminus.common.Table;
import net.miarma.contaminus.util.DateParser;
@Table("v_latest_values")
public class DeviceLatestValuesView {
private String deviceId;
private Integer sensorId;
private String sensorType;
private String unit;
private Integer sensorStatus;
private Long sensorTimestamp;
private Float temperature;
private Float humidity;
private Float carbonMonoxide;
private Float lat;
private Float lon;
private Long airValuesTimestamp;
public DeviceLatestValuesView() {}
public DeviceLatestValuesView(Row row) {
this.deviceId = row.getString("deviceId");
this.sensorId = row.getInteger("sensorId");
this.sensorType = row.getString("sensorType");
this.unit = row.getString("unit");
this.sensorStatus = row.getInteger("sensorStatus");
this.sensorTimestamp = DateParser.parseDate(row.getLocalDateTime("sensorTimestamp"));
this.temperature = row.getFloat("temperature");
this.humidity = row.getFloat("humidity");
this.carbonMonoxide = row.getFloat("carbonMonoxide");
this.lat = row.getFloat("lat");
this.lon = row.getFloat("lon");
this.airValuesTimestamp = DateParser.parseDate(row.getLocalDateTime("airValuesTimestamp"));
}
public DeviceLatestValuesView(String deviceId, Integer sensorId, String sensorType, String unit, Integer sensorStatus,
Long sensorTimestamp, Float temperature, Float humidity, Float carbonMonoxide, Float lat, Float lon,
Long airValuesTimestamp) {
super();
this.deviceId = deviceId;
this.sensorId = sensorId;
this.sensorType = sensorType;
this.unit = unit;
this.sensorStatus = sensorStatus;
this.sensorTimestamp = sensorTimestamp;
this.temperature = temperature;
this.humidity = humidity;
this.carbonMonoxide = carbonMonoxide;
this.lat = lat;
this.lon = lon;
this.airValuesTimestamp = airValuesTimestamp;
}
public String getDeviceId() {
return deviceId;
}
public Integer getSensorId() {
return sensorId;
}
public String getSensorType() {
return sensorType;
}
public String getUnit() {
return unit;
}
public Integer getSensorStatus() {
return sensorStatus;
}
public Long getSensorTimestamp() {
return sensorTimestamp;
}
public Float getTemperature() {
return temperature;
}
public Float getHumidity() {
return humidity;
}
public Float getCarbonMonoxide() {
return carbonMonoxide;
}
public Float getLat() {
return lat;
}
public Float getLon() {
return lon;
}
public Long getAirValuesTimestamp() {
return airValuesTimestamp;
}
@Override
public int hashCode() {
return Objects.hash(airValuesTimestamp, carbonMonoxide, deviceId, humidity, lat, lon, sensorId, sensorStatus,
sensorTimestamp, sensorType, temperature, unit);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
DeviceLatestValuesView other = (DeviceLatestValuesView) obj;
return Objects.equals(airValuesTimestamp, other.airValuesTimestamp)
&& Objects.equals(carbonMonoxide, other.carbonMonoxide) && Objects.equals(deviceId, other.deviceId)
&& Objects.equals(humidity, other.humidity) && Objects.equals(lat, other.lat)
&& Objects.equals(lon, other.lon) && Objects.equals(sensorId, other.sensorId)
&& Objects.equals(sensorStatus, other.sensorStatus)
&& Objects.equals(sensorTimestamp, other.sensorTimestamp)
&& Objects.equals(sensorType, other.sensorType) && Objects.equals(temperature, other.temperature)
&& Objects.equals(unit, other.unit);
}
@Override
public String toString() {
return "DeviceLatestValuesView [deviceId=" + deviceId + ", sensorId=" + sensorId + ", sensorType=" + sensorType
+ ", unit=" + unit + ", sensorStatus=" + sensorStatus + ", sensorTimestamp=" + sensorTimestamp
+ ", temperature=" + temperature + ", humidity=" + humidity + ", carbonMonoxide=" + carbonMonoxide
+ ", lat=" + lat + ", lon=" + lon + ", airValuesTimestamp=" + airValuesTimestamp + "]";
}
}
package net.miarma.contaminus.entities;
import java.util.Objects;
import io.vertx.sqlclient.Row;
import net.miarma.contaminus.common.Table;
import net.miarma.contaminus.util.DateParser;
@Table("v_latest_values")
public class ViewLatestValues {
private String deviceId;
private Integer sensorId;
private String sensorType;
private String unit;
private Integer sensorStatus;
private Long sensorTimestamp;
private Float temperature;
private Float humidity;
private Float pressure;
private Float carbonMonoxide;
private Float lat;
private Float lon;
private Long airValuesTimestamp;
public ViewLatestValues() {}
public ViewLatestValues(Row row) {
this.deviceId = row.getString("deviceId");
this.sensorId = row.getInteger("sensorId");
this.sensorType = row.getString("sensorType");
this.unit = row.getString("unit");
this.sensorStatus = row.getInteger("sensorStatus");
this.sensorTimestamp = DateParser.parseDate(row.getLocalDateTime("sensorTimestamp"));
this.temperature = row.getFloat("temperature");
this.humidity = row.getFloat("humidity");
this.pressure = row.getFloat("pressure");
this.carbonMonoxide = row.getFloat("carbonMonoxide");
this.lat = row.getFloat("lat");
this.lon = row.getFloat("lon");
this.airValuesTimestamp = DateParser.parseDate(row.getLocalDateTime("airValuesTimestamp"));
}
public ViewLatestValues(String deviceId, Integer sensorId, String sensorType, String unit, Integer sensorStatus,
Long sensorTimestamp, Float temperature, Float humidity, Float pressure, Float carbonMonoxide, Float lat, Float lon,
Long airValuesTimestamp) {
super();
this.deviceId = deviceId;
this.sensorId = sensorId;
this.sensorType = sensorType;
this.unit = unit;
this.sensorStatus = sensorStatus;
this.sensorTimestamp = sensorTimestamp;
this.temperature = temperature;
this.humidity = humidity;
this.carbonMonoxide = carbonMonoxide;
this.lat = lat;
this.lon = lon;
this.airValuesTimestamp = airValuesTimestamp;
}
public String getDeviceId() {
return deviceId;
}
public Integer getSensorId() {
return sensorId;
}
public String getSensorType() {
return sensorType;
}
public String getUnit() {
return unit;
}
public Integer getSensorStatus() {
return sensorStatus;
}
public Long getSensorTimestamp() {
return sensorTimestamp;
}
public Float getTemperature() {
return temperature;
}
public Float getHumidity() {
return humidity;
}
public Float getPressure() {
return pressure;
}
public Float getCarbonMonoxide() {
return carbonMonoxide;
}
public Float getLat() {
return lat;
}
public Float getLon() {
return lon;
}
public Long getAirValuesTimestamp() {
return airValuesTimestamp;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public void setSensorId(Integer sensorId) {
this.sensorId = sensorId;
}
public void setSensorType(String sensorType) {
this.sensorType = sensorType;
}
public void setUnit(String unit) {
this.unit = unit;
}
public void setSensorStatus(Integer sensorStatus) {
this.sensorStatus = sensorStatus;
}
public void setSensorTimestamp(Long sensorTimestamp) {
this.sensorTimestamp = sensorTimestamp;
}
public void setTemperature(Float temperature) {
this.temperature = temperature;
}
public void setHumidity(Float humidity) {
this.humidity = humidity;
}
public void setPressure(Float pressure) {
this.pressure = pressure;
}
public void setCarbonMonoxide(Float carbonMonoxide) {
this.carbonMonoxide = carbonMonoxide;
}
public void setLat(Float lat) {
this.lat = lat;
}
public void setLon(Float lon) {
this.lon = lon;
}
public void setAirValuesTimestamp(Long airValuesTimestamp) {
this.airValuesTimestamp = airValuesTimestamp;
}
@Override
public int hashCode() {
return Objects.hash(airValuesTimestamp, carbonMonoxide, deviceId, humidity, lat, lon, pressure, sensorId,
sensorStatus, sensorTimestamp, sensorType, temperature, unit);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ViewLatestValues other = (ViewLatestValues) obj;
return Objects.equals(airValuesTimestamp, other.airValuesTimestamp)
&& Objects.equals(carbonMonoxide, other.carbonMonoxide) && Objects.equals(deviceId, other.deviceId)
&& Objects.equals(humidity, other.humidity) && Objects.equals(lat, other.lat)
&& Objects.equals(lon, other.lon) && Objects.equals(pressure, other.pressure)
&& Objects.equals(sensorId, other.sensorId) && Objects.equals(sensorStatus, other.sensorStatus)
&& Objects.equals(sensorTimestamp, other.sensorTimestamp)
&& Objects.equals(sensorType, other.sensorType) && Objects.equals(temperature, other.temperature)
&& Objects.equals(unit, other.unit);
}
@Override
public String toString() {
return "ViewLatestValues [deviceId=" + deviceId + ", sensorId=" + sensorId + ", sensorType=" + sensorType
+ ", unit=" + unit + ", sensorStatus=" + sensorStatus + ", sensorTimestamp=" + sensorTimestamp
+ ", temperature=" + temperature + ", humidity=" + humidity + ", pressure=" + pressure
+ ", carbonMonoxide=" + carbonMonoxide + ", lat=" + lat + ", lon=" + lon + ", airValuesTimestamp="
+ airValuesTimestamp + "]";
}
}

View File

@@ -1,90 +1,116 @@
package net.miarma.contaminus.database.entities;
import java.util.Objects;
import io.vertx.sqlclient.Row;
import net.miarma.contaminus.common.Table;
import net.miarma.contaminus.util.DateParser;
@Table("v_pollution_map")
public class DevicePollutionMap {
private String deviceId;
private String deviceName;
private Float lat;
private Float lon;
private Float carbonMonoxide;
private Long timestamp;
public DevicePollutionMap() {}
public DevicePollutionMap(Row row) {
this.deviceId = row.getString("deviceId");
this.deviceName = row.getString("deviceName");
this.lat = row.getFloat("lat");
this.lon = row.getFloat("lon");
this.carbonMonoxide = row.getFloat("carbonMonoxide");
this.timestamp = DateParser.parseDate(row.getLocalDateTime("timestamp"));
}
public DevicePollutionMap(String deviceId, String deviceName, Float lat, Float lon, Float carbonMonoxide,
Long timestamp) {
super();
this.deviceId = deviceId;
this.deviceName = deviceName;
this.lat = lat;
this.lon = lon;
this.carbonMonoxide = carbonMonoxide;
this.timestamp = timestamp;
}
public String getDeviceId() {
return deviceId;
}
public String getDeviceName() {
return deviceName;
}
public Float getLat() {
return lat;
}
public Float getLon() {
return lon;
}
public Float getCarbonMonoxide() {
return carbonMonoxide;
}
public Long getTimestamp() {
return timestamp;
}
@Override
public int hashCode() {
return Objects.hash(carbonMonoxide, deviceId, deviceName, lat, lon, timestamp);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
DevicePollutionMap other = (DevicePollutionMap) obj;
return Objects.equals(carbonMonoxide, other.carbonMonoxide) && Objects.equals(deviceId, other.deviceId)
&& Objects.equals(deviceName, other.deviceName) && Objects.equals(lat, other.lat)
&& Objects.equals(lon, other.lon) && Objects.equals(timestamp, other.timestamp);
}
@Override
public String toString() {
return "DevicePollutionMap [deviceId=" + deviceId + ", deviceName=" + deviceName + ", lat=" + lat + ", lon="
+ lon + ", carbonMonoxide=" + carbonMonoxide + ", timestamp=" + timestamp + "]";
}
package net.miarma.contaminus.entities;
import java.util.Objects;
import io.vertx.sqlclient.Row;
import net.miarma.contaminus.common.Table;
import net.miarma.contaminus.util.DateParser;
@Table("v_pollution_map")
public class ViewPollutionMap {
private String deviceId;
private String deviceName;
private Float lat;
private Float lon;
private Float carbonMonoxide;
private Long timestamp;
public ViewPollutionMap() {}
public ViewPollutionMap(Row row) {
this.deviceId = row.getString("deviceId");
this.deviceName = row.getString("deviceName");
this.lat = row.getFloat("lat");
this.lon = row.getFloat("lon");
this.carbonMonoxide = row.getFloat("carbonMonoxide");
this.timestamp = DateParser.parseDate(row.getLocalDateTime("timestamp"));
}
public ViewPollutionMap(String deviceId, String deviceName, Float lat, Float lon, Float carbonMonoxide,
Long timestamp) {
super();
this.deviceId = deviceId;
this.deviceName = deviceName;
this.lat = lat;
this.lon = lon;
this.carbonMonoxide = carbonMonoxide;
this.timestamp = timestamp;
}
public String getDeviceId() {
return deviceId;
}
public String getDeviceName() {
return deviceName;
}
public Float getLat() {
return lat;
}
public Float getLon() {
return lon;
}
public Float getCarbonMonoxide() {
return carbonMonoxide;
}
public Long getTimestamp() {
return timestamp;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public void setDeviceName(String deviceName) {
this.deviceName = deviceName;
}
public void setLat(Float lat) {
this.lat = lat;
}
public void setLon(Float lon) {
this.lon = lon;
}
public void setCarbonMonoxide(Float carbonMonoxide) {
this.carbonMonoxide = carbonMonoxide;
}
public void setTimestamp(Long timestamp) {
this.timestamp = timestamp;
}
@Override
public int hashCode() {
return Objects.hash(carbonMonoxide, deviceId, deviceName, lat, lon, timestamp);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ViewPollutionMap other = (ViewPollutionMap) obj;
return Objects.equals(carbonMonoxide, other.carbonMonoxide) && Objects.equals(deviceId, other.deviceId)
&& Objects.equals(deviceName, other.deviceName) && Objects.equals(lat, other.lat)
&& Objects.equals(lon, other.lon) && Objects.equals(timestamp, other.timestamp);
}
@Override
public String toString() {
return "DevicePollutionMap [deviceId=" + deviceId + ", deviceName=" + deviceName + ", lat=" + lat + ", lon="
+ lon + ", carbonMonoxide=" + carbonMonoxide + ", timestamp=" + timestamp + "]";
}
}

View File

@@ -1,82 +1,104 @@
package net.miarma.contaminus.database.entities;
import java.util.Objects;
import io.vertx.sqlclient.Row;
import net.miarma.contaminus.common.Table;
import net.miarma.contaminus.util.DateParser;
@Table("v_sensor_history_by_device")
public class DeviceSensorHistory {
private String deviceId;
private String deviceName;
private Float value;
private String valueType;
private Long timestamp;
public DeviceSensorHistory() {}
public DeviceSensorHistory(Row row) {
this.deviceId = row.getString("deviceId");
this.deviceName = row.getString("deviceName");
this.value = row.getFloat("value");
this.valueType = row.getString("valueType");
this.timestamp = DateParser.parseDate(row.getLocalDateTime("timestamp"));
}
public DeviceSensorHistory(String deviceId, String deviceName, Float value, String valueType, Long timestamp) {
super();
this.deviceId = deviceId;
this.deviceName = deviceName;
this.value = value;
this.valueType = valueType;
this.timestamp = timestamp;
}
public String getDeviceId() {
return deviceId;
}
public String getDeviceName() {
return deviceName;
}
public Float getValue() {
return value;
}
public String getValueType() {
return valueType;
}
public Long getTimestamp() {
return timestamp;
}
@Override
public int hashCode() {
return Objects.hash(deviceId, deviceName, timestamp, value, valueType);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
DeviceSensorHistory other = (DeviceSensorHistory) obj;
return Objects.equals(deviceId, other.deviceId) && Objects.equals(deviceName, other.deviceName)
&& Objects.equals(timestamp, other.timestamp) && Objects.equals(value, other.value)
&& Objects.equals(valueType, other.valueType);
}
@Override
public String toString() {
return "DeviceSensorHistory [deviceId=" + deviceId + ", deviceName=" + deviceName + ", value=" + value
+ ", valueType=" + valueType + ", timestamp=" + timestamp + "]";
}
}
package net.miarma.contaminus.entities;
import java.util.Objects;
import io.vertx.sqlclient.Row;
import net.miarma.contaminus.common.Table;
import net.miarma.contaminus.util.DateParser;
@Table("v_sensor_history_by_device")
public class ViewSensorHistory {
private String deviceId;
private String deviceName;
private Float value;
private String valueType;
private Long timestamp;
public ViewSensorHistory() {}
public ViewSensorHistory(Row row) {
this.deviceId = row.getString("deviceId");
this.deviceName = row.getString("deviceName");
this.value = row.getFloat("value");
this.valueType = row.getString("valueType");
this.timestamp = DateParser.parseDate(row.getLocalDateTime("timestamp"));
}
public ViewSensorHistory(String deviceId, String deviceName, Float value, String valueType, Long timestamp) {
super();
this.deviceId = deviceId;
this.deviceName = deviceName;
this.value = value;
this.valueType = valueType;
this.timestamp = timestamp;
}
public String getDeviceId() {
return deviceId;
}
public String getDeviceName() {
return deviceName;
}
public Float getValue() {
return value;
}
public String getValueType() {
return valueType;
}
public Long getTimestamp() {
return timestamp;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public void setDeviceName(String deviceName) {
this.deviceName = deviceName;
}
public void setValue(Float value) {
this.value = value;
}
public void setValueType(String valueType) {
this.valueType = valueType;
}
public void setTimestamp(Long timestamp) {
this.timestamp = timestamp;
}
@Override
public int hashCode() {
return Objects.hash(deviceId, deviceName, timestamp, value, valueType);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ViewSensorHistory other = (ViewSensorHistory) obj;
return Objects.equals(deviceId, other.deviceId) && Objects.equals(deviceName, other.deviceName)
&& Objects.equals(timestamp, other.timestamp) && Objects.equals(value, other.value)
&& Objects.equals(valueType, other.valueType);
}
@Override
public String toString() {
return "DeviceSensorHistory [deviceId=" + deviceId + ", deviceName=" + deviceName + ", value=" + value
+ ", valueType=" + valueType + ", timestamp=" + timestamp + "]";
}
}

View File

@@ -1,131 +1,189 @@
package net.miarma.contaminus.database.entities;
import java.util.Objects;
import io.vertx.sqlclient.Row;
import net.miarma.contaminus.common.Table;
import net.miarma.contaminus.util.DateParser;
@Table("v_sensor_values")
public class DeviceSensorValue {
private Integer sensorId;
private String deviceId;
private String sensorType;
private String unit;
private Integer sensorStatus;
private Float temperature;
private Float humidity;
private Float carbonMonoxide;
private Float lat;
private Float lon;
private Long timestamp;
public DeviceSensorValue() {}
public DeviceSensorValue(Row row) {
this.sensorId = row.getInteger("sensorId");
this.deviceId = row.getString("deviceId");
this.sensorType = row.getString("sensorType");
this.unit = row.getString("unit");
this.sensorStatus = row.getInteger("sensorStatus");
this.temperature = row.getFloat("temperature");
this.humidity = row.getFloat("humidity");
this.carbonMonoxide = row.getFloat("carbonMonoxide");
this.lat = row.getFloat("lat");
this.lon = row.getFloat("lon");
this.timestamp = DateParser.parseDate(row.getLocalDateTime("timestamp"));
}
public DeviceSensorValue(Integer sensorId, String deviceId, String sensorType, String unit, Integer sensorStatus,
Float temperature, Float humidity, Float carbonMonoxide, Float lat, Float lon, Long timestamp) {
super();
this.sensorId = sensorId;
this.deviceId = deviceId;
this.sensorType = sensorType;
this.unit = unit;
this.sensorStatus = sensorStatus;
this.temperature = temperature;
this.humidity = humidity;
this.carbonMonoxide = carbonMonoxide;
this.lat = lat;
this.lon = lon;
this.timestamp = timestamp;
}
public Integer getSensorId() {
return sensorId;
}
public String getDeviceId() {
return deviceId;
}
public String getSensorType() {
return sensorType;
}
public String getUnit() {
return unit;
}
public Integer getSensorStatus() {
return sensorStatus;
}
public Float getTemperature() {
return temperature;
}
public Float getHumidity() {
return humidity;
}
public Float getCarbonMonoxide() {
return carbonMonoxide;
}
public Float getLat() {
return lat;
}
public Float getLon() {
return lon;
}
public Long getTimestamp() {
return timestamp;
}
@Override
public int hashCode() {
return Objects.hash(carbonMonoxide, deviceId, humidity, lat, lon, sensorId, sensorStatus, sensorType,
temperature, timestamp, unit);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
DeviceSensorValue other = (DeviceSensorValue) obj;
return Objects.equals(carbonMonoxide, other.carbonMonoxide) && Objects.equals(deviceId, other.deviceId)
&& Objects.equals(humidity, other.humidity) && Objects.equals(lat, other.lat)
&& Objects.equals(lon, other.lon) && Objects.equals(sensorId, other.sensorId)
&& Objects.equals(sensorStatus, other.sensorStatus) && Objects.equals(sensorType, other.sensorType)
&& Objects.equals(temperature, other.temperature) && Objects.equals(timestamp, other.timestamp)
&& Objects.equals(unit, other.unit);
}
@Override
public String toString() {
return "DeviceSensorValue [sensorId=" + sensorId + ", deviceId=" + deviceId + ", sensorType=" + sensorType
+ ", unit=" + unit + ", sensorStatus=" + sensorStatus + ", temperature=" + temperature + ", humidity="
+ humidity + ", carbonMonoxide=" + carbonMonoxide + ", lat=" + lat + ", lon=" + lon + ", timestamp="
+ timestamp + "]";
}
}
package net.miarma.contaminus.entities;
import java.util.Objects;
import io.vertx.sqlclient.Row;
import net.miarma.contaminus.common.Table;
import net.miarma.contaminus.util.DateParser;
@Table("v_sensor_values")
public class ViewSensorValue {
private Integer sensorId;
private String deviceId;
private String sensorType;
private String unit;
private Integer sensorStatus;
private Float temperature;
private Float humidity;
private Float pressure;
private Float carbonMonoxide;
private Float lat;
private Float lon;
private Long timestamp;
public ViewSensorValue() {}
public ViewSensorValue(Row row) {
this.sensorId = row.getInteger("sensorId");
this.deviceId = row.getString("deviceId");
this.sensorType = row.getString("sensorType");
this.unit = row.getString("unit");
this.sensorStatus = row.getInteger("sensorStatus");
this.temperature = row.getFloat("temperature");
this.humidity = row.getFloat("humidity");
this.pressure = row.getFloat("pressure");
this.carbonMonoxide = row.getFloat("carbonMonoxide");
this.lat = row.getFloat("lat");
this.lon = row.getFloat("lon");
this.timestamp = DateParser.parseDate(row.getLocalDateTime("timestamp"));
}
public ViewSensorValue(Integer sensorId, String deviceId, String sensorType, String unit, Integer sensorStatus,
Float temperature, Float humidity, Float pressure, Float carbonMonoxide, Float lat, Float lon, Long timestamp) {
super();
this.sensorId = sensorId;
this.deviceId = deviceId;
this.sensorType = sensorType;
this.unit = unit;
this.sensorStatus = sensorStatus;
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
this.carbonMonoxide = carbonMonoxide;
this.lat = lat;
this.lon = lon;
this.timestamp = timestamp;
}
public Integer getSensorId() {
return sensorId;
}
public String getDeviceId() {
return deviceId;
}
public String getSensorType() {
return sensorType;
}
public String getUnit() {
return unit;
}
public Integer getSensorStatus() {
return sensorStatus;
}
public Float getTemperature() {
return temperature;
}
public Float getHumidity() {
return humidity;
}
public Float getPressure() {
return pressure;
}
public Float getCarbonMonoxide() {
return carbonMonoxide;
}
public Float getLat() {
return lat;
}
public Float getLon() {
return lon;
}
public Long getTimestamp() {
return timestamp;
}
public void setSensorId(Integer sensorId) {
this.sensorId = sensorId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public void setSensorType(String sensorType) {
this.sensorType = sensorType;
}
public void setUnit(String unit) {
this.unit = unit;
}
public void setSensorStatus(Integer sensorStatus) {
this.sensorStatus = sensorStatus;
}
public void setTemperature(Float temperature) {
this.temperature = temperature;
}
public void setHumidity(Float humidity) {
this.humidity = humidity;
}
public void setPressure(Float pressure) {
this.pressure = pressure;
}
public void setCarbonMonoxide(Float carbonMonoxide) {
this.carbonMonoxide = carbonMonoxide;
}
public void setLat(Float lat) {
this.lat = lat;
}
public void setLon(Float lon) {
this.lon = lon;
}
public void setTimestamp(Long timestamp) {
this.timestamp = timestamp;
}
@Override
public int hashCode() {
return Objects.hash(carbonMonoxide, deviceId, humidity, lat, lon, pressure, sensorId, sensorStatus, sensorType,
temperature, timestamp, unit);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ViewSensorValue other = (ViewSensorValue) obj;
return Objects.equals(carbonMonoxide, other.carbonMonoxide) && Objects.equals(deviceId, other.deviceId)
&& Objects.equals(humidity, other.humidity) && Objects.equals(lat, other.lat)
&& Objects.equals(lon, other.lon) && Objects.equals(pressure, other.pressure)
&& Objects.equals(sensorId, other.sensorId) && Objects.equals(sensorStatus, other.sensorStatus)
&& Objects.equals(sensorType, other.sensorType) && Objects.equals(temperature, other.temperature)
&& Objects.equals(timestamp, other.timestamp) && Objects.equals(unit, other.unit);
}
@Override
public String toString() {
return "ViewSensorValue [sensorId=" + sensorId + ", deviceId=" + deviceId + ", sensorType=" + sensorType
+ ", unit=" + unit + ", sensorStatus=" + sensorStatus + ", temperature=" + temperature + ", humidity="
+ humidity + ", pressure=" + pressure + ", carbonMonoxide=" + carbonMonoxide + ", lat=" + lat + ", lon="
+ lon + ", timestamp=" + timestamp + "]";
}
}

View File

@@ -1,131 +1,131 @@
package net.miarma.contaminus.database.entities;
import java.util.Objects;
import io.vertx.sqlclient.Row;
import net.miarma.contaminus.common.Table;
import net.miarma.contaminus.util.DateParser;
@Table("weather_values")
public class WeatherValue {
private Integer valueId;
private String deviceId;
private Integer sensorId;
private Float temperature;
private Float humidity;
private Float pressure;
private Long timestamp;
public WeatherValue() {}
public WeatherValue(Row row) {
this.valueId = row.getInteger("valueId");
this.deviceId = row.getString("deviceId");
this.sensorId = row.getInteger("sensorId");
this.temperature = row.getFloat("temperature");
this.humidity = row.getFloat("humidity");
this.pressure = row.getFloat("pressure");
this.timestamp = DateParser.parseDate(row.getLocalDateTime("timestamp"));
}
public WeatherValue(Integer valueId, String deviceId, Integer sensorId, Float temperature, Float humidity, Float pressure, Long timestamp) {
super();
this.valueId = valueId;
this.deviceId = deviceId;
this.sensorId = sensorId;
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
this.timestamp = timestamp;
}
public Integer getValueId() {
return valueId;
}
public void setValueId(Integer valueId) {
this.valueId = valueId;
}
package net.miarma.contaminus.entities;
import java.util.Objects;
import io.vertx.sqlclient.Row;
import net.miarma.contaminus.common.Table;
import net.miarma.contaminus.util.DateParser;
@Table("weather_values")
public class WeatherValue {
private Integer valueId;
private String deviceId;
private Integer sensorId;
private Float temperature;
private Float humidity;
private Float pressure;
private Long timestamp;
public WeatherValue() {}
public WeatherValue(Row row) {
this.valueId = row.getInteger("valueId");
this.deviceId = row.getString("deviceId");
this.sensorId = row.getInteger("sensorId");
this.temperature = row.getFloat("temperature");
this.humidity = row.getFloat("humidity");
this.pressure = row.getFloat("pressure");
this.timestamp = DateParser.parseDate(row.getLocalDateTime("timestamp"));
}
public WeatherValue(Integer valueId, String deviceId, Integer sensorId, Float temperature, Float humidity, Float pressure, Long timestamp) {
super();
this.valueId = valueId;
this.deviceId = deviceId;
this.sensorId = sensorId;
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
this.timestamp = timestamp;
}
public Integer getValueId() {
return valueId;
}
public void setValueId(Integer valueId) {
this.valueId = valueId;
}
public String getDeviceId() {
return deviceId;
}
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public Integer getSensorId() {
return sensorId;
}
public void setSensorId(Integer 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 Integer getSensorId() {
return sensorId;
}
public void setSensorId(Integer 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 Float getPressure() {
return pressure;
}
}
public void setPressure(Float pressure) {
this.pressure = pressure;
}
public Long getTimestamp() {
return timestamp;
}
public void setTimestamp(Long timestamp) {
this.timestamp = timestamp;
}
@Override
public int hashCode() {
return Objects.hash(deviceId, humidity, pressure, 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 Objects.equals(deviceId, other.deviceId) && Objects.equals(humidity, other.humidity)
&& Objects.equals(pressure, other.pressure) && Objects.equals(sensorId, other.sensorId)
&& Objects.equals(temperature, other.temperature) && Objects.equals(timestamp, other.timestamp)
&& Objects.equals(valueId, other.valueId);
}
@Override
public String toString() {
return "WeatherValue [valueId=" + valueId + ", deviceId=" + deviceId + ", sensorId=" + sensorId
+ ", temperature=" + temperature + ", humidity=" + humidity + ", pressure=" + pressure + ", timestamp="
+ timestamp + "]";
}
}
public Long getTimestamp() {
return timestamp;
}
public void setTimestamp(Long timestamp) {
this.timestamp = timestamp;
}
@Override
public int hashCode() {
return Objects.hash(deviceId, humidity, pressure, 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 Objects.equals(deviceId, other.deviceId) && Objects.equals(humidity, other.humidity)
&& Objects.equals(pressure, other.pressure) && Objects.equals(sensorId, other.sensorId)
&& Objects.equals(temperature, other.temperature) && Objects.equals(timestamp, other.timestamp)
&& Objects.equals(valueId, other.valueId);
}
@Override
public String toString() {
return "WeatherValue [valueId=" + valueId + ", deviceId=" + deviceId + ", sensorId=" + sensorId
+ ", temperature=" + temperature + ", humidity=" + humidity + ", pressure=" + pressure + ", timestamp="
+ timestamp + "]";
}
public static WeatherValue fromPayload(DevicePayload payload) {
return new WeatherValue(null, payload.getDeviceId(), payload.getSensorId(), payload.getTemperature(),
payload.getHumidity(), payload.getPressure(), payload.getTimestamp());
}
}
}

View File

@@ -1,529 +0,0 @@
package net.miarma.contaminus.server;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Promise;
import io.vertx.core.Vertx;
import io.vertx.core.http.HttpMethod;
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 io.vertx.jdbcclient.JDBCPool;
import net.miarma.contaminus.common.ConfigManager;
import net.miarma.contaminus.common.Constants;
import net.miarma.contaminus.common.SingleJsonResponse;
import net.miarma.contaminus.database.DatabaseManager;
import net.miarma.contaminus.database.QueryBuilder;
import net.miarma.contaminus.database.entities.Actuator;
import net.miarma.contaminus.database.entities.COValue;
import net.miarma.contaminus.database.entities.Device;
import net.miarma.contaminus.database.entities.DeviceLatestValuesView;
import net.miarma.contaminus.database.entities.DevicePayload;
import net.miarma.contaminus.database.entities.DevicePollutionMap;
import net.miarma.contaminus.database.entities.DeviceSensorHistory;
import net.miarma.contaminus.database.entities.DeviceSensorValue;
import net.miarma.contaminus.database.entities.GpsValue;
import net.miarma.contaminus.database.entities.Group;
import net.miarma.contaminus.database.entities.Sensor;
import net.miarma.contaminus.database.entities.WeatherValue;
/*
* This class is a Verticle that will handle the Data Layer API.
*/
@SuppressWarnings("unused")
public class DataLayerAPIVerticle extends AbstractVerticle {
private JDBCPool pool;
private DatabaseManager dbManager;
private ConfigManager configManager;
private final Gson gson = new GsonBuilder().serializeNulls().create();
@SuppressWarnings("deprecation")
public DataLayerAPIVerticle() {
this.configManager = ConfigManager.getInstance();
String jdbcUrl = configManager.getJdbcUrl();
String dbUser = configManager.getStringProperty("db.user");
String dbPwd = configManager.getStringProperty("db.pwd");
Integer poolSize = configManager.getIntProperty("db.poolSize");
JsonObject dbConfig = new JsonObject()
.put("url", jdbcUrl)
.put("user", dbUser)
.put("password", dbPwd)
.put("max_pool_size", poolSize != null ? poolSize : 10);
this.pool = JDBCPool.pool(Vertx.vertx(), dbConfig);
}
@Override
public void start(Promise<Void> startPromise) {
Constants.LOGGER.info("📡 Iniciando DataLayerAPIVerticle...");
dbManager = DatabaseManager.getInstance(pool);
Router router = Router.router(vertx);
Set<HttpMethod> allowedMethods = new HashSet<>(
Arrays.asList(HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT, HttpMethod.OPTIONS)); // Por ejemplo
Set<String> allowedHeaders = new HashSet<>(Arrays.asList("Content-Type", "Authorization"));
router.route().handler(CorsHandler.create()
.allowCredentials(true)
.allowedHeaders(allowedHeaders)
.allowedMethods(allowedMethods));
router.route().handler(BodyHandler.create());
// Payload
router.route(HttpMethod.POST, Constants.POST_PAYLOAD).handler(this::addDevicePayload);
// Group Routes
router.route(HttpMethod.GET, Constants.GET_GROUPS).handler(this::getAllGroups);
router.route(HttpMethod.GET, Constants.GET_GROUP_BY_ID).handler(this::getGroupById);
router.route(HttpMethod.POST, Constants.POST_GROUPS).handler(this::addGroup);
router.route(HttpMethod.PUT, Constants.PUT_GROUP_BY_ID).handler(this::updateGroup);
// Device Routes
router.route(HttpMethod.GET, Constants.GET_DEVICES).handler(this::getAllDevices);
router.route(HttpMethod.GET, Constants.GET_DEVICE_BY_ID).handler(this::getDeviceById);
router.route(HttpMethod.POST, Constants.POST_DEVICES).handler(this::addDevice);
router.route(HttpMethod.PUT, Constants.PUT_DEVICE_BY_ID).handler(this::updateDevice);
// Sensor Routes
router.route(HttpMethod.GET, Constants.GET_SENSORS).handler(this::getAllSensors);
router.route(HttpMethod.GET, Constants.GET_SENSOR_BY_ID).handler(this::getSensorById);
router.route(HttpMethod.POST, Constants.POST_SENSORS).handler(this::addSensor);
router.route(HttpMethod.PUT, Constants.PUT_SENSOR_BY_ID).handler(this::updateSensor);
// Actuator Routes
router.route(HttpMethod.GET, Constants.GET_ACTUATORS).handler(this::getAllActuators);
router.route(HttpMethod.GET, Constants.GET_ACTUATOR_BY_ID).handler(this::getActuatorById);
router.route(HttpMethod.POST, Constants.POST_ACTUATORS).handler(this::addActuator);
router.route(HttpMethod.PUT, Constants.PUT_ACTUATOR_BY_ID).handler(this::updateActuator);
// Views Routes
router.route(HttpMethod.GET, Constants.GET_LATEST_VALUES_VIEW).handler(this::getLatestValuesView);
router.route(HttpMethod.GET, Constants.GET_POLLUTION_MAP_VIEW).handler(this::getDevicePollutionMapView);
router.route(HttpMethod.GET, Constants.GET_SENSOR_VALUES_VIEW).handler(this::getSensorValuesView);
router.route(HttpMethod.GET, Constants.GET_SENSOR_HISTORY_BY_DEVICE_VIEW).handler(this::getSensorHistoryByDeviceView);
vertx.createHttpServer()
.requestHandler(router)
.listen(configManager.getDataApiPort(), configManager.getHost());
pool.query("SELECT 1").execute(ar -> {
if (ar.succeeded()) {
Constants.LOGGER.info("🟢 Connected to DB");
startPromise.complete();
} else {
Constants.LOGGER.error("🔴 Failed to connect to DB: " + ar.cause());
startPromise.fail(ar.cause());
}
});
}
private void addDevicePayload(RoutingContext context) {
JsonObject body = context.body().asJsonObject();
DevicePayload devicePayload = gson.fromJson(body.toString(), DevicePayload.class);
COValue coValue = COValue.fromPayload(devicePayload);
GpsValue gpsValue = GpsValue.fromPayload(devicePayload);
WeatherValue weatherValue = WeatherValue.fromPayload(devicePayload);
String coQuery = QueryBuilder
.insert(coValue)
.build();
String gpsQuery = QueryBuilder
.insert(gpsValue)
.build();
String weatherQuery = QueryBuilder
.insert(weatherValue)
.build();
dbManager.execute(coQuery, COValue.class,
onSuccess -> {
dbManager.execute(gpsQuery, GpsValue.class,
onSuccess2 -> {
dbManager.execute(weatherQuery, WeatherValue.class,
onSuccess3 -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(SingleJsonResponse.of("Payload added successfully")));
},
onFailure3 -> {
context.fail(500, onFailure3);
});
},
onFailure2 -> {
context.fail(500, onFailure2);
});
},
onFailure -> {
context.fail(500, onFailure);
});
}
private void getAllGroups(RoutingContext context) {
String query = QueryBuilder
.select(Group.class)
.build();
dbManager.execute(query, Group.class,
onSuccess -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(onSuccess));
},
onFailure -> {
context.fail(500, onFailure);
});
}
private void getGroupById(RoutingContext context) {
Integer groupId = Integer.parseInt(context.request().getParam("groupId"));
Group group = new Group(groupId, null);
String query = QueryBuilder
.select(group)
.build();
dbManager.execute(query, Group.class,
onSuccess -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(onSuccess));
},
onFailure -> {
context.fail(500, onFailure);
});
}
private void addGroup(RoutingContext context) {
JsonObject body = context.body().asJsonObject();
Group group = gson.fromJson(body.toString(), Group.class);
String query = QueryBuilder
.insert(group)
.build();
dbManager.execute(query, Group.class,
onSuccess -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(SingleJsonResponse.of("Group added successfully")));
},
onFailure -> {
context.fail(500, onFailure);
});
}
private void updateGroup(RoutingContext context) {
JsonObject body = context.body().asJsonObject();
Group group = gson.fromJson(body.toString(), Group.class);
String query = QueryBuilder
.update(group)
.build();
dbManager.execute(query, Group.class,
onSuccess -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(SingleJsonResponse.of("Group updated successfully")));
},
onFailure -> {
context.fail(500, onFailure);
});
}
private void getAllDevices(RoutingContext context) {
String query = QueryBuilder
.select(Device.class)
.build();
dbManager.execute(query, Device.class,
onSuccess -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(onSuccess));
},
onFailure -> {
context.fail(500, onFailure);
});
}
private void getDeviceById(RoutingContext context) {
String deviceId = context.request().getParam("deviceId");
Device device = new Device(deviceId, null, null);
String query = QueryBuilder
.select(device)
.build();
dbManager.execute(query, Device.class,
onSuccess -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(onSuccess));
},
onFailure -> {
context.fail(500, onFailure);
});
}
private void addDevice(RoutingContext context) {
JsonObject body = context.body().asJsonObject();
Device device = gson.fromJson(body.toString(), Device.class);
String query = QueryBuilder
.insert(device)
.build();
dbManager.execute(query, Device.class,
onSuccess -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(SingleJsonResponse.of("Device added successfully")));
},
onFailure -> {
context.fail(500, onFailure);
});
}
private void updateDevice(RoutingContext context) {
JsonObject body = context.body().asJsonObject();
Device device = gson.fromJson(body.toString(), Device.class);
String query = QueryBuilder
.update(device)
.build();
dbManager.execute(query, Device.class,
onSuccess -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(SingleJsonResponse.of("Device updated successfully")));
},
onFailure -> {
context.fail(500, onFailure);
});
}
private void getAllSensors(RoutingContext context) {
String query = QueryBuilder
.select(Sensor.class)
.build();
dbManager.execute(query, Sensor.class,
onSuccess -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(onSuccess));
},
onFailure -> {
context.fail(500, onFailure);
});
}
private void getSensorById(RoutingContext context) {
Integer sensorId = Integer.parseInt(context.request().getParam("sensorId"));
Sensor sensor = new Sensor(sensorId, null, null, null, null, null);
String query = QueryBuilder
.select(sensor)
.build();
dbManager.execute(query, Sensor.class,
onSuccess -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(onSuccess));
},
onFailure -> {
context.fail(500, onFailure);
});
}
private void addSensor(RoutingContext context) {
JsonObject body = context.body().asJsonObject();
Sensor sensor = gson.fromJson(body.toString(), Sensor.class);
String query = QueryBuilder
.insert(sensor)
.build();
dbManager.execute(query, Sensor.class,
onSuccess -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(SingleJsonResponse.of("Sensor added successfully")));
},
onFailure -> {
context.fail(500, onFailure);
});
}
private void updateSensor(RoutingContext context) {
JsonObject body = context.body().asJsonObject();
Sensor sensor = gson.fromJson(body.toString(), Sensor.class);
String query = QueryBuilder
.update(sensor)
.build();
dbManager.execute(query, Sensor.class,
onSuccess -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(SingleJsonResponse.of("Sensor updated successfully")));
},
onFailure -> {
context.fail(500, onFailure);
});
}
private void getAllActuators(RoutingContext context) {
String query = QueryBuilder
.select(Actuator.class)
.build();
dbManager.execute(query, Actuator.class,
onSuccess -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(onSuccess));
},
onFailure -> {
context.fail(500, onFailure);
});
}
private void getActuatorById(RoutingContext context) {
Integer actuatorId = Integer.parseInt(context.request().getParam("actuatorId"));
Actuator actuator = new Actuator(actuatorId, null, null, null);
String query = QueryBuilder
.select(actuator)
.build();
dbManager.execute(query, Actuator.class,
onSuccess -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(onSuccess));
},
onFailure -> {
context.fail(500, onFailure);
});
}
private void addActuator(RoutingContext context) {
JsonObject body = context.body().asJsonObject();
Actuator actuator = gson.fromJson(body.toString(), Actuator.class);
String query = QueryBuilder
.insert(actuator)
.build();
dbManager.execute(query, Actuator.class,
onSuccess -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(SingleJsonResponse.of("Actuator added successfully")));
},
onFailure -> {
context.fail(500, onFailure);
});
}
private void updateActuator(RoutingContext context) {
JsonObject body = context.body().asJsonObject();
Actuator actuator = gson.fromJson(body.toString(), Actuator.class);
String query = QueryBuilder
.update(actuator)
.build();
dbManager.execute(query, Actuator.class,
onSuccess -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(SingleJsonResponse.of("Actuator updated successfully")));
},
onFailure -> {
context.fail(500, onFailure);
});
}
private void getLatestValuesView(RoutingContext context) {
String query = QueryBuilder
.select(DeviceLatestValuesView.class)
.build();
dbManager.execute(query, DeviceLatestValuesView.class,
onSuccess -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(onSuccess));
},
onFailure -> {
context.fail(500, onFailure);
});
}
private void getDevicePollutionMapView(RoutingContext context) {
String query = QueryBuilder
.select(DevicePollutionMap.class)
.build();
dbManager.execute(query, DevicePollutionMap.class,
onSuccess -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(onSuccess));
},
onFailure -> {
context.fail(500, onFailure);
});
}
private void getSensorValuesView(RoutingContext context) {
String query = QueryBuilder
.select(DeviceSensorValue.class)
.build();
dbManager.execute(query, DeviceSensorValue.class,
onSuccess -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(onSuccess));
},
onFailure -> {
context.fail(500, onFailure);
});
}
private void getSensorHistoryByDeviceView(RoutingContext context) {
String query = QueryBuilder
.select(DeviceSensorHistory.class)
.build();
dbManager.execute(query, DeviceSensorHistory.class,
onSuccess -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(onSuccess));
},
onFailure -> {
context.fail(500, onFailure);
});
}
}

View File

@@ -1,225 +0,0 @@
package net.miarma.contaminus.server;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Promise;
import io.vertx.core.Vertx;
import io.vertx.core.http.HttpMethod;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.client.WebClient;
import io.vertx.ext.web.client.WebClientOptions;
import io.vertx.ext.web.handler.BodyHandler;
import io.vertx.ext.web.handler.CorsHandler;
import net.miarma.contaminus.common.ConfigManager;
import net.miarma.contaminus.common.Constants;
import net.miarma.contaminus.database.entities.Actuator;
import net.miarma.contaminus.database.entities.Device;
import net.miarma.contaminus.database.entities.DeviceLatestValuesView;
import net.miarma.contaminus.database.entities.DevicePollutionMap;
import net.miarma.contaminus.database.entities.DeviceSensorHistory;
import net.miarma.contaminus.database.entities.DeviceSensorValue;
import net.miarma.contaminus.database.entities.Sensor;
import net.miarma.contaminus.util.RestClientUtil;
public class LogicLayerAPIVerticle extends AbstractVerticle {
private ConfigManager configManager;
private final Gson gson = new GsonBuilder().serializeNulls().create();
private RestClientUtil restClient;
public LogicLayerAPIVerticle() {
this.configManager = ConfigManager.getInstance();
WebClientOptions options = new WebClientOptions()
.setUserAgent("ContaminUS");
this.restClient = new RestClientUtil(WebClient.create(Vertx.vertx(), options));
}
@Override
public void start(Promise<Void> startPromise) {
Constants.LOGGER.info("📡 Iniciando LogicApiVerticle...");
Router router = Router.router(vertx);
Set<HttpMethod> allowedMethods = new HashSet<>(
Arrays.asList(HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT, HttpMethod.OPTIONS)); // Por ejemplo
Set<String> allowedHeaders = new HashSet<>(Arrays.asList("Content-Type", "Authorization"));
router.route().handler(CorsHandler.create()
.allowCredentials(true)
.allowedHeaders(allowedHeaders)
.allowedMethods(allowedMethods));
router.route().handler(BodyHandler.create());
router.route(HttpMethod.GET, Constants.GET_GROUP_DEVICES).handler(this::getGroupDevices);
router.route(HttpMethod.GET, Constants.GET_DEVICE_SENSORS).handler(this::getDeviceSensors);
router.route(HttpMethod.GET, Constants.GET_DEVICE_ACTUATORS).handler(this::getDeviceActuators);
router.route(HttpMethod.GET, Constants.GET_DEVICE_LATEST_VALUES).handler(this::getDeviceLatestValues);
router.route(HttpMethod.GET, Constants.GET_DEVICE_POLLUTION_MAP).handler(this::getDevicePollutionMap);
router.route(HttpMethod.GET, Constants.GET_DEVICE_HISTORY).handler(this::getDeviceHistory);
router.route(HttpMethod.GET, Constants.GET_SENSOR_VALUES).handler(this::getSensorValues);
vertx.createHttpServer()
.requestHandler(router)
.listen(configManager.getLogicApiPort(), configManager.getHost());
startPromise.complete();
}
private void getGroupDevices(RoutingContext context) {
Integer groupId = Integer.parseInt(context.request().getParam("groupId"));
Promise<Device[]> resultList = Promise.promise();
resultList.future().onComplete(complete -> {
if(complete.succeeded()) {
List<Device> aux = Stream.of(complete.result())
.filter(d -> d.getGroupId() == groupId)
.toList();
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(aux));
} else {
context.fail(500, complete.cause());
}
});
this.restClient.getRequest(configManager.getDataApiPort(), "http://" + configManager.getHost(),
Constants.GET_DEVICES, Device[].class, resultList);
}
private void getDeviceSensors(RoutingContext context) {
String deviceId = context.request().getParam("deviceId");
Promise<Sensor[]> resultList = Promise.promise();
resultList.future().onComplete(result -> {
if (result.succeeded()) {
Sensor[] sensors = result.result();
List<Sensor> aux = Arrays.stream(sensors)
.filter(s -> s.getDeviceId() == deviceId)
.toList();
context.response().putHeader("Content-Type", "application/json").end(gson.toJson(aux));
} else {
context.response().setStatusCode(500).end(result.cause().getMessage());
}
});
restClient.getRequest(configManager.getDataApiPort(), "http://" + configManager.getHost(),
Constants.GET_SENSORS, Sensor[].class, resultList);
}
private void getDeviceActuators(RoutingContext context) {
String deviceId = context.request().getParam("deviceId");
Promise<Actuator[]> resultList = Promise.promise();
resultList.future().onComplete(result -> {
if (result.succeeded()) {
Actuator[] devices = result.result();
List<Actuator> aux = Arrays.stream(devices)
.filter(a -> a.getDeviceId() == deviceId)
.toList();
context.response().putHeader("Content-Type", "application/json").end(gson.toJson(aux));
} else {
context.response().setStatusCode(500).end(result.cause().getMessage());
}
});
restClient.getRequest(configManager.getDataApiPort(), "http://" + configManager.getHost(),
Constants.GET_ACTUATORS, Actuator[].class, resultList);
}
private void getDeviceLatestValues(RoutingContext context) {
String deviceId = context.request().getParam("deviceId");
Promise<DeviceLatestValuesView[]> resultList = Promise.promise();
resultList.future().onComplete(complete -> {
if (complete.succeeded()) {
List<DeviceLatestValuesView> aux = Stream.of(complete.result())
.filter(elem -> elem.getDeviceId() == deviceId)
.toList();
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(aux));
} else {
context.fail(500, complete.cause());
}
});
this.restClient.getRequest(configManager.getDataApiPort(), "http://" + configManager.getHost(),
Constants.GET_LATEST_VALUES_VIEW, DeviceLatestValuesView[].class, resultList);
}
private void getDevicePollutionMap(RoutingContext context) {
String deviceId = context.request().getParam("deviceId");
Promise<DevicePollutionMap[]> resultList = Promise.promise();
resultList.future().onComplete(complete -> {
if (complete.succeeded()) {
List<DevicePollutionMap> aux = Arrays.asList(complete.result()).stream()
.filter(elem -> elem.getDeviceId() == deviceId)
.toList();
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(aux));
} else {
context.fail(500, complete.cause());
}
});
this.restClient.getRequest(configManager.getDataApiPort(), "http://" + configManager.getHost(),
Constants.GET_POLLUTION_MAP_VIEW, DevicePollutionMap[].class, resultList);
}
private void getDeviceHistory(RoutingContext context) {
String deviceId = context.request().getParam("deviceId");
Promise<DeviceSensorHistory[]> resultList = Promise.promise();
resultList.future().onComplete(complete -> {
if (complete.succeeded()) {
List<DeviceSensorHistory> aux = Arrays.asList(complete.result()).stream()
.filter(elem -> elem.getDeviceId() == deviceId)
.toList();
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(aux));
} else {
context.fail(500, complete.cause());
}
});
this.restClient.getRequest(configManager.getDataApiPort(), "http://" + configManager.getHost(),
Constants.GET_SENSOR_HISTORY_BY_DEVICE_VIEW, DeviceSensorHistory[].class, resultList);
}
private void getSensorValues(RoutingContext context) {
Integer sensorId = Integer.parseInt(context.request().getParam("sensorId"));
Promise<DeviceSensorValue[]> resultList = Promise.promise();
resultList.future().onComplete(complete -> {
if (complete.succeeded()) {
List<DeviceSensorValue> aux = Arrays.asList(complete.result()).stream()
.filter(val -> val.getSensorId() == sensorId)
.toList();
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(aux));
} else {
context.fail(500, complete.cause());
}
});
this.restClient.getRequest(configManager.getDataApiPort(), "http://" + configManager.getHost(),
Constants.GET_SENSOR_VALUES_VIEW, DeviceSensorValue[].class, resultList);
}
}

View File

@@ -0,0 +1,479 @@
package net.miarma.contaminus.verticles;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.http.HttpMethod;
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 io.vertx.sqlclient.Pool;
import net.miarma.contaminus.common.ConfigManager;
import net.miarma.contaminus.common.Constants;
import net.miarma.contaminus.common.SingleJsonResponse;
import net.miarma.contaminus.dao.ActuatorDAO;
import net.miarma.contaminus.dao.COValueDAO;
import net.miarma.contaminus.dao.DeviceDAO;
import net.miarma.contaminus.dao.GpsValueDAO;
import net.miarma.contaminus.dao.GroupDAO;
import net.miarma.contaminus.dao.SensorDAO;
import net.miarma.contaminus.dao.WeatherValueDAO;
import net.miarma.contaminus.dao.views.ViewLatestValuesDAO;
import net.miarma.contaminus.dao.views.ViewPollutionMapDAO;
import net.miarma.contaminus.dao.views.ViewSensorHistoryDAO;
import net.miarma.contaminus.dao.views.ViewSensorValueDAO;
import net.miarma.contaminus.db.DatabaseManager;
import net.miarma.contaminus.db.DatabaseProvider;
import net.miarma.contaminus.db.QueryBuilder;
import net.miarma.contaminus.entities.Actuator;
import net.miarma.contaminus.entities.Device;
import net.miarma.contaminus.entities.Group;
import net.miarma.contaminus.entities.Sensor;
import net.miarma.contaminus.entities.ViewLatestValues;
import net.miarma.contaminus.entities.ViewPollutionMap;
import net.miarma.contaminus.entities.ViewSensorHistory;
import net.miarma.contaminus.entities.ViewSensorValue;
/*
* This class is a Verticle that will handle the Data Layer API.
*/
@SuppressWarnings("unused")
public class DataLayerAPIVerticle extends AbstractVerticle {
private DatabaseManager dbManager;
private ConfigManager configManager;
private final Gson gson = new GsonBuilder().serializeNulls().create();
private Pool pool;
private GroupDAO groupDAO;
private DeviceDAO deviceDAO;
private SensorDAO sensorDAO;
private ActuatorDAO actuatorDAO;
private COValueDAO coValueDAO;
private WeatherValueDAO weatherValueDAO;
private GpsValueDAO gpsValueDAO;
private ViewLatestValuesDAO viewLatestValuesDAO;
private ViewPollutionMapDAO viewPollutionMapDAO;
private ViewSensorHistoryDAO viewSensorHistoryDAO;
private ViewSensorValueDAO viewSensorValueDAO;
public DataLayerAPIVerticle() {
this.configManager = ConfigManager.getInstance();
}
@Override
public void start(Promise<Void> startPromise) {
Constants.LOGGER.info("📡 Iniciando DataLayerAPIVerticle...");
this.pool = DatabaseProvider.createPool(vertx, configManager);
this.dbManager = DatabaseManager.getInstance(pool);
this.groupDAO = new GroupDAO(pool);
this.deviceDAO = new DeviceDAO(pool);
this.sensorDAO = new SensorDAO(pool);
this.actuatorDAO = new ActuatorDAO(pool);
this.coValueDAO = new COValueDAO(pool);
this.weatherValueDAO = new WeatherValueDAO(pool);
this.gpsValueDAO = new GpsValueDAO(pool);
this.viewLatestValuesDAO = new ViewLatestValuesDAO(pool);
this.viewPollutionMapDAO = new ViewPollutionMapDAO(pool);
this.viewSensorHistoryDAO = new ViewSensorHistoryDAO(pool);
this.viewSensorValueDAO = new ViewSensorValueDAO(pool);
Router router = Router.router(vertx);
Set<HttpMethod> allowedMethods = new HashSet<>(
Arrays.asList(HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT, HttpMethod.OPTIONS)); // Por ejemplo
Set<String> 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.GROUPS).handler(this::getAllGroups);
router.route(HttpMethod.GET, Constants.GROUP).handler(this::getGroupById);
router.route(HttpMethod.POST, Constants.GROUPS).handler(this::addGroup);
router.route(HttpMethod.PUT, Constants.GROUP).handler(this::updateGroup);
// Device Routes
router.route(HttpMethod.GET, Constants.DEVICES).handler(this::getAllDevices);
router.route(HttpMethod.GET, Constants.DEVICE).handler(this::getDeviceById);
router.route(HttpMethod.POST, Constants.DEVICES).handler(this::addDevice);
router.route(HttpMethod.PUT, Constants.DEVICE).handler(this::updateDevice);
// Sensor Routes
router.route(HttpMethod.GET, Constants.SENSORS).handler(this::getAllSensors);
router.route(HttpMethod.GET, Constants.SENSOR).handler(this::getSensorById);
router.route(HttpMethod.POST, Constants.SENSORS).handler(this::addSensor);
router.route(HttpMethod.PUT, Constants.SENSOR).handler(this::updateSensor);
// Actuator Routes
router.route(HttpMethod.GET, Constants.ACTUATORS).handler(this::getAllActuators);
router.route(HttpMethod.GET, Constants.ACTUATOR).handler(this::getActuatorById);
router.route(HttpMethod.POST, Constants.ACTUATORS).handler(this::addActuator);
router.route(HttpMethod.PUT, Constants.ACTUATOR).handler(this::updateActuator);
// Views Routes
router.route(HttpMethod.GET, Constants.VIEW_LATEST_VALUES).handler(this::getLatestValuesView);
router.route(HttpMethod.GET, Constants.VIEW_POLLUTION_MAP).handler(this::getDevicePollutionMapView);
router.route(HttpMethod.GET, Constants.VIEW_SENSOR_VALUES).handler(this::getSensorValuesView);
router.route(HttpMethod.GET, Constants.VIEW_SENSOR_HISTORY).handler(this::getSensorHistoryByDeviceView);
vertx.createHttpServer()
.requestHandler(router)
.listen(configManager.getDataApiPort(), configManager.getHost());
pool.query("SELECT 1").execute(ar -> {
if (ar.succeeded()) {
Constants.LOGGER.info("🟢 Connected to DB");
startPromise.complete();
} else {
Constants.LOGGER.error("🔴 Failed to connect to DB: " + ar.cause());
startPromise.fail(ar.cause());
}
});
}
private void getAllGroups(RoutingContext context) {
groupDAO.getAll()
.onSuccess(groups -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(groups));
})
.onFailure(err -> {
context.fail(500, err);
});
}
private void getGroupById(RoutingContext context) {
Integer groupId = Integer.parseInt(context.request().getParam("groupId"));
groupDAO.getById(groupId)
.onSuccess(group -> {
if (group != null) {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(group));
} else {
context.response().setStatusCode(404).end();
}
})
.onFailure(err -> {
context.fail(500, err);
});
}
private void addGroup(RoutingContext context) {
JsonObject body = context.body().asJsonObject();
Group group = gson.fromJson(body.toString(), Group.class);
groupDAO.insert(group)
.onSuccess(result -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(SingleJsonResponse.of("Group added successfully")));
})
.onFailure(err -> {
context.fail(500, err);
});
}
private void updateGroup(RoutingContext context) {
JsonObject body = context.body().asJsonObject();
Group group = gson.fromJson(body.toString(), Group.class);
groupDAO.update(group)
.onSuccess(result -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(SingleJsonResponse.of("Group updated successfully")));
})
.onFailure(err -> {
context.fail(500, err);
});
}
private void getAllDevices(RoutingContext context) {
Integer groupId = Integer.parseInt(context.request().getParam("groupId"));
deviceDAO.getAllByGroupId(groupId)
.onSuccess(devices -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(devices));
})
.onFailure(err -> {
context.fail(500, err);
});
}
private void getDeviceById(RoutingContext context) {
Integer groupId = Integer.parseInt(context.request().getParam("groupId"));
String deviceId = context.request().getParam("deviceId");
deviceDAO.getByIdAndGroupId(deviceId, groupId)
.onSuccess(device -> {
if (device != null) {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(device));
} else {
context.response().setStatusCode(404).end();
}
})
.onFailure(err -> {
context.fail(500, err);
});
}
private void addDevice(RoutingContext context) {
JsonObject body = context.body().asJsonObject();
Device device = gson.fromJson(body.toString(), Device.class);
deviceDAO.insert(device)
.onSuccess(result -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(SingleJsonResponse.of("Device added successfully")));
})
.onFailure(err -> {
context.fail(500, err);
});
}
private void updateDevice(RoutingContext context) {
JsonObject body = context.body().asJsonObject();
Device device = gson.fromJson(body.toString(), Device.class);
deviceDAO.update(device)
.onSuccess(result -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(SingleJsonResponse.of("Device updated successfully")));
})
.onFailure(err -> {
context.fail(500, err);
});
}
private void getAllSensors(RoutingContext context) {
Integer groupId = Integer.parseInt(context.request().getParam("groupId"));
String deviceId = context.request().getParam("deviceId");
deviceDAO.getByIdAndGroupId(deviceId, groupId).compose(device -> {
if (device == null) {
return Future.succeededFuture(List.of());
}
return sensorDAO.getAllByDeviceId(device.getDeviceId());
}).onSuccess(sensors -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(sensors));
}).onFailure(err -> {
context.response().setStatusCode(500).end("Error: " + err.getMessage());
});
}
private void getSensorById(RoutingContext context) {
Integer sensorId = Integer.parseInt(context.request().getParam("sensorId"));
String deviceId = context.request().getParam("deviceId");
Integer groupId = Integer.parseInt(context.request().getParam("groupId"));
deviceDAO.getByIdAndGroupId(deviceId, groupId).compose(device -> {
if (device == null) {
return Future.succeededFuture(null);
}
return sensorDAO.getByIdAndDeviceId(sensorId, device.getDeviceId());
}).onSuccess(sensor -> {
if (sensor == null) {
context.response().setStatusCode(404).end("Sensor no encontrado");
return;
}
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(sensor));
}).onFailure(err -> {
context.response().setStatusCode(500).end("Error: " + err.getMessage());
});
}
private void addSensor(RoutingContext context) {
JsonObject body = context.body().asJsonObject();
Sensor sensor = gson.fromJson(body.toString(), Sensor.class);
sensorDAO.insert(sensor)
.onSuccess(result -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(SingleJsonResponse.of("Sensor added successfully")));
})
.onFailure(err -> {
context.fail(500, err);
});
}
private void updateSensor(RoutingContext context) {
JsonObject body = context.body().asJsonObject();
Sensor sensor = gson.fromJson(body.toString(), Sensor.class);
sensorDAO.update(sensor)
.onSuccess(result -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(SingleJsonResponse.of("Sensor updated successfully")));
})
.onFailure(err -> {
context.fail(500, err);
});
}
private void getAllActuators(RoutingContext context) {
Integer groupId = Integer.parseInt(context.request().getParam("groupId"));
String deviceId = context.request().getParam("deviceId");
deviceDAO.getByIdAndGroupId(deviceId, groupId).compose(device -> {
if (device == null) {
return Future.succeededFuture(List.of());
}
return actuatorDAO.getAllByDeviceId(device.getDeviceId());
}).onSuccess(actuators -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(actuators));
}).onFailure(err -> {
context.response().setStatusCode(500).end("Error: " + err.getMessage());
});
}
private void getActuatorById(RoutingContext context) {
Integer groupId = Integer.parseInt(context.request().getParam("groupId"));
String deviceId = context.request().getParam("deviceId");
Integer actuatorId = Integer.parseInt(context.request().getParam("actuatorId"));
deviceDAO.getByIdAndGroupId(deviceId, groupId).compose(device -> {
if (device == null) {
return Future.succeededFuture(null);
}
return actuatorDAO.getByIdAndDeviceId(actuatorId, device.getDeviceId());
}).onSuccess(actuator -> {
if (actuator == null) {
context.response().setStatusCode(404).end("Actuator no encontrado");
return;
}
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(actuator));
}).onFailure(err -> {
context.response().setStatusCode(500).end("Error: " + err.getMessage());
});
}
private void addActuator(RoutingContext context) {
JsonObject body = context.body().asJsonObject();
Actuator actuator = gson.fromJson(body.toString(), Actuator.class);
actuatorDAO.insert(actuator)
.onSuccess(result -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(SingleJsonResponse.of("Actuator added successfully")));
})
.onFailure(err -> {
context.fail(500, err);
});
}
private void updateActuator(RoutingContext context) {
JsonObject body = context.body().asJsonObject();
Actuator actuator = gson.fromJson(body.toString(), Actuator.class);
actuatorDAO.update(actuator)
.onSuccess(result -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(SingleJsonResponse.of("Actuator updated successfully")));
})
.onFailure(err -> {
context.fail(500, err);
});
}
private void getLatestValuesView(RoutingContext context) {
String query = QueryBuilder
.select(ViewLatestValues.class)
.build();
dbManager.execute(query, ViewLatestValues.class,
onSuccess -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(onSuccess));
},
onFailure -> {
context.fail(500, onFailure);
});
}
private void getDevicePollutionMapView(RoutingContext context) {
String query = QueryBuilder
.select(ViewPollutionMap.class)
.build();
dbManager.execute(query, ViewPollutionMap.class,
onSuccess -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(onSuccess));
},
onFailure -> {
context.fail(500, onFailure);
});
}
private void getSensorValuesView(RoutingContext context) {
String query = QueryBuilder
.select(ViewSensorValue.class)
.build();
dbManager.execute(query, ViewSensorValue.class,
onSuccess -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(onSuccess));
},
onFailure -> {
context.fail(500, onFailure);
});
}
private void getSensorHistoryByDeviceView(RoutingContext context) {
String query = QueryBuilder
.select(ViewSensorHistory.class)
.build();
dbManager.execute(query, ViewSensorHistory.class,
onSuccess -> {
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(onSuccess));
},
onFailure -> {
context.fail(500, onFailure);
});
}
}

View File

@@ -0,0 +1,160 @@
package net.miarma.contaminus.verticles;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Promise;
import io.vertx.core.Vertx;
import io.vertx.core.http.HttpMethod;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.client.WebClient;
import io.vertx.ext.web.client.WebClientOptions;
import io.vertx.ext.web.handler.BodyHandler;
import io.vertx.ext.web.handler.CorsHandler;
import net.miarma.contaminus.common.ConfigManager;
import net.miarma.contaminus.common.Constants;
import net.miarma.contaminus.entities.ViewLatestValues;
import net.miarma.contaminus.entities.ViewPollutionMap;
import net.miarma.contaminus.entities.ViewSensorHistory;
import net.miarma.contaminus.entities.ViewSensorValue;
import net.miarma.contaminus.util.RestClientUtil;
public class LogicLayerAPIVerticle extends AbstractVerticle {
private ConfigManager configManager;
private final Gson gson = new GsonBuilder().serializeNulls().create();
private RestClientUtil restClient;
public LogicLayerAPIVerticle() {
this.configManager = ConfigManager.getInstance();
WebClientOptions options = new WebClientOptions()
.setUserAgent("ContaminUS");
this.restClient = new RestClientUtil(WebClient.create(Vertx.vertx(), options));
}
@Override
public void start(Promise<Void> startPromise) {
Constants.LOGGER.info("📡 Iniciando LogicApiVerticle...");
Router router = Router.router(vertx);
Set<HttpMethod> allowedMethods = new HashSet<>(
Arrays.asList(HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT, HttpMethod.OPTIONS));
Set<String> allowedHeaders = new HashSet<>(Arrays.asList("Content-Type", "Authorization"));
router.route().handler(CorsHandler.create()
.allowCredentials(true)
.allowedHeaders(allowedHeaders)
.allowedMethods(allowedMethods));
router.route().handler(BodyHandler.create());
router.route(HttpMethod.GET, Constants.LATEST_VALUES).handler(this::getDeviceLatestValues);
router.route(HttpMethod.GET, Constants.POLLUTION_MAP).handler(this::getDevicePollutionMap);
router.route(HttpMethod.GET, Constants.HISTORY).handler(this::getDeviceHistory);
router.route(HttpMethod.GET, Constants.SENSOR_VALUES).handler(this::getSensorValues);
vertx.createHttpServer()
.requestHandler(router)
.listen(configManager.getLogicApiPort(), configManager.getHost());
startPromise.complete();
}
private void getDeviceLatestValues(RoutingContext context) {
String deviceId = context.request().getParam("deviceId");
Promise<ViewLatestValues[]> resultList = Promise.promise();
resultList.future().onComplete(complete -> {
if (complete.succeeded()) {
List<ViewLatestValues> aux = Stream.of(complete.result())
.filter(elem -> deviceId.equals(elem.getDeviceId()))
.toList();
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(aux));
} else {
context.fail(500, complete.cause());
}
});
this.restClient.getRequest(configManager.getDataApiPort(), "http://" + configManager.getHost(),
Constants.VIEW_LATEST_VALUES, ViewLatestValues[].class, resultList);
}
private void getDevicePollutionMap(RoutingContext context) {
String deviceId = context.request().getParam("deviceId");
Promise<ViewPollutionMap[]> resultList = Promise.promise();
resultList.future().onComplete(complete -> {
if (complete.succeeded()) {
List<ViewPollutionMap> aux = Arrays.asList(complete.result()).stream()
.filter(elem -> deviceId.equals(elem.getDeviceId()))
.toList();
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(aux));
} else {
context.fail(500, complete.cause());
}
});
this.restClient.getRequest(configManager.getDataApiPort(), "http://" + configManager.getHost(),
Constants.VIEW_POLLUTION_MAP, ViewPollutionMap[].class, resultList);
}
private void getDeviceHistory(RoutingContext context) {
String deviceId = context.request().getParam("deviceId");
Promise<ViewSensorHistory[]> resultList = Promise.promise();
resultList.future().onComplete(complete -> {
if (complete.succeeded()) {
List<ViewSensorHistory> aux = Arrays.asList(complete.result()).stream()
.filter(elem -> deviceId.equals(elem.getDeviceId()))
.toList();
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(aux));
} else {
context.fail(500, complete.cause());
}
});
this.restClient.getRequest(configManager.getDataApiPort(), "http://" + configManager.getHost(),
Constants.VIEW_SENSOR_HISTORY, ViewSensorHistory[].class, resultList);
}
private void getSensorValues(RoutingContext context) {
Integer sensorId = Integer.parseInt(context.request().getParam("sensorId"));
Promise<ViewSensorValue[]> resultList = Promise.promise();
resultList.future().onComplete(complete -> {
if (complete.succeeded()) {
List<ViewSensorValue> aux = Arrays.asList(complete.result()).stream()
.filter(val -> val.getSensorId() == sensorId)
.toList();
context.response()
.putHeader("content-type", "application/json; charset=utf-8")
.end(gson.toJson(aux));
} else {
context.fail(500, complete.cause());
}
});
this.restClient.getRequest(configManager.getDataApiPort(), "http://" + configManager.getHost(),
Constants.VIEW_SENSOR_VALUES, ViewSensorValue[].class, resultList);
}
}

View File

@@ -1,97 +1,96 @@
package net.miarma.contaminus.server;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.DeploymentOptions;
import io.vertx.core.Launcher;
import io.vertx.core.Promise;
import io.vertx.core.ThreadingModel;
import net.miarma.contaminus.common.ConfigManager;
import net.miarma.contaminus.common.Constants;
public class MainVerticle extends AbstractVerticle {
private ConfigManager configManager;
public static void main(String[] args) {
Launcher.executeCommand("run", MainVerticle.class.getName());
}
private void init() {
this.configManager = ConfigManager.getInstance();
initializeDirectories();
copyDefaultConfig();
}
private void initializeDirectories() {
File baseDir = new File(this.configManager.getBaseDir());
if (!baseDir.exists()) {
baseDir.mkdirs();
}
}
private void copyDefaultConfig() {
File configFile = new File(configManager.getConfigFile().getAbsolutePath());
if (!configFile.exists()) {
try (InputStream in = MainVerticle.class.getClassLoader().getResourceAsStream("default.properties")) {
if (in != null) {
Files.copy(in, configFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
} else {
Constants.LOGGER.error("🔴 Default config file not found in resources");
}
} catch (IOException e) {
Constants.LOGGER.error("🔴 Failed to copy default config file", e);
}
}
}
@Override
public void start(Promise<Void> startPromise) {
try {
System.setProperty("java.util.logging.manager", "org.jboss.logmanager.LogManager");
init();
deployVerticles(startPromise);
} catch (Exception e) {
Constants.LOGGER.error("🔴 Error starting the application: " + e);
startPromise.fail(e);
}
}
private void deployVerticles(Promise<Void> startPromise) {
final DeploymentOptions options = new DeploymentOptions();
options.setThreadingModel(ThreadingModel.WORKER);
vertx.deployVerticle(new DataLayerAPIVerticle(), options, result -> {
if (result.succeeded()) {
Constants.LOGGER.info("🟢 DatabaseVerticle desplegado");
Constants.LOGGER.info("\t🔗 API URL: " + configManager.getHost()
+ ":" + configManager.getDataApiPort());
} else {
Constants.LOGGER.error("🔴 Error deploying DataLayerAPIVerticle: " + result.cause());
}
});
vertx.deployVerticle(new LogicLayerAPIVerticle(), options, result -> {
if (result.succeeded()) {
Constants.LOGGER.info("🟢 LogicLayerAPIVerticle desplegado");
Constants.LOGGER.info("\t🔗 API URL: " + configManager.getHost()
+ ":" + configManager.getLogicApiPort());
} else {
Constants.LOGGER.error("🔴 Error deploying LogicLayerAPIVerticle: " + result.cause());
}
});
startPromise.complete();
}
@Override
public void stop(Promise<Void> stopPromise) throws Exception {
getVertx().deploymentIDs()
.forEach(v -> getVertx().undeploy(v));
}
}
package net.miarma.contaminus.verticles;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.DeploymentOptions;
import io.vertx.core.Launcher;
import io.vertx.core.Promise;
import io.vertx.core.ThreadingModel;
import net.miarma.contaminus.common.ConfigManager;
import net.miarma.contaminus.common.Constants;
public class MainVerticle extends AbstractVerticle {
private ConfigManager configManager;
public static void main(String[] args) {
Launcher.executeCommand("run", MainVerticle.class.getName());
}
private void init() {
this.configManager = ConfigManager.getInstance();
initializeDirectories();
copyDefaultConfig();
}
private void initializeDirectories() {
File baseDir = new File(this.configManager.getBaseDir());
if (!baseDir.exists()) {
baseDir.mkdirs();
}
}
private void copyDefaultConfig() {
File configFile = new File(configManager.getConfigFile().getAbsolutePath());
if (!configFile.exists()) {
try (InputStream in = MainVerticle.class.getClassLoader().getResourceAsStream("default.properties")) {
if (in != null) {
Files.copy(in, configFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
} else {
Constants.LOGGER.error("🔴 Default config file not found in resources");
}
} catch (IOException e) {
Constants.LOGGER.error("🔴 Failed to copy default config file", e);
}
}
}
@Override
public void start(Promise<Void> startPromise) {
try {
init();
deployVerticles(startPromise);
} catch (Exception e) {
Constants.LOGGER.error("🔴 Error starting the application: " + e);
startPromise.fail(e);
}
}
private void deployVerticles(Promise<Void> startPromise) {
final DeploymentOptions options = new DeploymentOptions();
options.setThreadingModel(ThreadingModel.WORKER);
vertx.deployVerticle(new DataLayerAPIVerticle(), options, result -> {
if (result.succeeded()) {
Constants.LOGGER.info("🟢 DatabaseVerticle desplegado");
Constants.LOGGER.info("\t🔗 API URL: " + configManager.getHost()
+ ":" + configManager.getDataApiPort());
} else {
Constants.LOGGER.error("🔴 Error deploying DataLayerAPIVerticle: " + result.cause());
}
});
vertx.deployVerticle(new LogicLayerAPIVerticle(), options, result -> {
if (result.succeeded()) {
Constants.LOGGER.info("🟢 LogicLayerAPIVerticle desplegado");
Constants.LOGGER.info("\t🔗 API URL: " + configManager.getHost()
+ ":" + configManager.getLogicApiPort());
} else {
Constants.LOGGER.error("🔴 Error deploying LogicLayerAPIVerticle: " + result.cause());
}
});
startPromise.complete();
}
@Override
public void stop(Promise<Void> stopPromise) throws Exception {
getVertx().deploymentIDs()
.forEach(v -> getVertx().undeploy(v));
}
}

View File

@@ -1,18 +1,18 @@
package net.miarma.contaminus.server;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Promise;
public class MqttVerticle extends AbstractVerticle {
@Override
public void start(Promise<Void> startPromise) {
}
@Override
public void stop(Promise<Void> startPromise) {
}
}
package net.miarma.contaminus.verticles;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Promise;
public class MqttVerticle extends AbstractVerticle {
@Override
public void start(Promise<Void> startPromise) {
}
@Override
public void stop(Promise<Void> startPromise) {
}
}

View File

@@ -1,14 +1,14 @@
# DB Configuration
db.protocol=jdbc:mariadb
db.host=localhost
db.port=3306
db.name=dad
db.user=root
db.pwd=root
dp.poolSize=5
# HTTP Server Configuration
inet.host=localhost
webserver.port=8080
data-api.port=8081
# DB Configuration
db.protocol=jdbc:mariadb
db.host=localhost
db.port=3306
db.name=dad
db.user=root
db.password=root
dp.poolSize=5
# HTTP Server Configuration
inet.host=localhost
webserver.port=8080
data-api.port=8081
logic-api.port=8082

View File

@@ -0,0 +1,20 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>
%cyan([%d{HH:mm:ss}]) %highlight(%-5level) %green(%logger{20}) - %msg%n
</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
<logger name="io.netty" level="WARN"/>
<logger name="io.vertx" level="INFO"/>
<logger name="io.vertx.core.impl.launcher" level="INFO"/>
<logger name="io.vertx.core.logging" level="INFO"/>
</configuration>