Refactored many things and removed unnecessary things like IDEA files and stuff
8
.idea/.gitignore
generated
vendored
@@ -1,8 +0,0 @@
|
|||||||
# Default ignored files
|
|
||||||
/shelf/
|
|
||||||
/workspace.xml
|
|
||||||
# Editor-based HTTP Client requests
|
|
||||||
/httpRequests/
|
|
||||||
# Datasource local storage ignored files
|
|
||||||
/dataSources/
|
|
||||||
/dataSources.local.xml
|
|
||||||
13
.idea/compiler.xml
generated
@@ -1,13 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="CompilerConfiguration">
|
|
||||||
<annotationProcessing>
|
|
||||||
<profile name="Maven default annotation processors profile" enabled="true">
|
|
||||||
<sourceOutputDir name="target/generated-sources/annotations" />
|
|
||||||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
|
||||||
<outputRelativeToContentRoot value="true" />
|
|
||||||
<module name="contaminus" />
|
|
||||||
</profile>
|
|
||||||
</annotationProcessing>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
20
.idea/jarRepositories.xml
generated
@@ -1,20 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="RemoteRepositoriesConfiguration">
|
|
||||||
<remote-repository>
|
|
||||||
<option name="id" value="central" />
|
|
||||||
<option name="name" value="Central Repository" />
|
|
||||||
<option name="url" value="https://repo.maven.apache.org/maven2" />
|
|
||||||
</remote-repository>
|
|
||||||
<remote-repository>
|
|
||||||
<option name="id" value="central" />
|
|
||||||
<option name="name" value="Maven Central repository" />
|
|
||||||
<option name="url" value="https://repo1.maven.org/maven2" />
|
|
||||||
</remote-repository>
|
|
||||||
<remote-repository>
|
|
||||||
<option name="id" value="jboss.community" />
|
|
||||||
<option name="name" value="JBoss Community repository" />
|
|
||||||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
|
||||||
</remote-repository>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
14
.idea/misc.xml
generated
@@ -1,14 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
|
||||||
<component name="MavenProjectsManager">
|
|
||||||
<option name="originalFiles">
|
|
||||||
<list>
|
|
||||||
<option value="$PROJECT_DIR$/backend/vertx/pom.xml" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_23" project-jdk-name="23" project-jdk-type="JavaSDK">
|
|
||||||
<output url="file://$PROJECT_DIR$/classes" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
8
.idea/modules.xml
generated
@@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectModuleManager">
|
|
||||||
<modules>
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/ContaminUS.iml" filepath="$PROJECT_DIR$/ContaminUS.iml" />
|
|
||||||
</modules>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
6
.idea/vcs.xml
generated
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="VcsDirectoryMappings">
|
|
||||||
<mapping directory="" vcs="Git" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
11
.project
@@ -1,11 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<projectDescription>
|
|
||||||
<name>ContaminUS</name>
|
|
||||||
<comment></comment>
|
|
||||||
<projects>
|
|
||||||
</projects>
|
|
||||||
<buildSpec>
|
|
||||||
</buildSpec>
|
|
||||||
<natures>
|
|
||||||
</natures>
|
|
||||||
</projectDescription>
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module type="JAVA_MODULE" version="4">
|
|
||||||
<component name="NewModuleRootManager">
|
|
||||||
<output url="file://$MODULE_DIR$/bin" />
|
|
||||||
<exclude-output />
|
|
||||||
<content url="file://$MODULE_DIR$" />
|
|
||||||
<orderEntry type="jdk" jdkName="23" jdkType="JavaSDK" />
|
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
|
||||||
</component>
|
|
||||||
</module>
|
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package net.miarma.contaminus.common;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import io.vertx.core.impl.logging.Logger;
|
||||||
|
import io.vertx.core.impl.logging.LoggerFactory;
|
||||||
|
|
||||||
|
public class Constants {
|
||||||
|
public static final String APP_NAME = "ContaminUS";
|
||||||
|
public static final String API_PREFIX = "/api/v1";
|
||||||
|
public static final String HOME_DIR = System.getProperty("user.home") + File.separator;
|
||||||
|
public static final String BASE_DIR = HOME_DIR +
|
||||||
|
(SystemInfo.getOS() == OSType.WINDOWS ? ".contaminus" :
|
||||||
|
SystemInfo.getOS() == OSType.LINUX ? ".config" + File.separator +
|
||||||
|
"contaminus" : null);
|
||||||
|
public static final String CONFIG_FILE = BASE_DIR + File.separator + "config.properties";
|
||||||
|
public static final Logger LOGGER = LoggerFactory.getLogger(APP_NAME);
|
||||||
|
|
||||||
|
public static final String GET_GROUPS = API_PREFIX + "/groups";
|
||||||
|
public static final String GET_GROUP_BY_ID = API_PREFIX + "/groups/:groupId";
|
||||||
|
public static final String GET_GROUP_DEVICES = API_PREFIX + "/groups/:groupId/devices";
|
||||||
|
public static final String POST_GROUPS = API_PREFIX + "/groups";
|
||||||
|
public static final String PUT_GROUP_BY_ID = API_PREFIX + "/groups/:groupId";
|
||||||
|
|
||||||
|
public static final String GET_DEVICES = API_PREFIX + "/devices";
|
||||||
|
public static final String GET_DEVICE_BY_ID = API_PREFIX + "/devices/:deviceId";
|
||||||
|
public static final String GET_DEVICE_SENSORS = API_PREFIX + "/devices/:deviceId/sensors";
|
||||||
|
public static final String POST_DEVICES = API_PREFIX + "/devices";
|
||||||
|
public static final String PUT_DEVICE_BY_ID = API_PREFIX + "/devices/:deviceId";
|
||||||
|
|
||||||
|
public static final String GET_SENSORS = API_PREFIX + "/sensors";
|
||||||
|
public static final String GET_SENSOR_BY_ID = API_PREFIX + "/sensors/:sensorId";
|
||||||
|
public static final String GET_SENSOR_VALUES = API_PREFIX + "/sensors/:sensorId/values";
|
||||||
|
public static final String POST_SENSORS = API_PREFIX + "/sensors";
|
||||||
|
public static final String PUT_SENSOR_BY_ID = API_PREFIX + "/sensors/:sensorId";
|
||||||
|
|
||||||
|
public static final String GET_ACTUATORS = API_PREFIX + "/actuators";
|
||||||
|
public static final String GET_ACTUATOR_BY_ID = API_PREFIX + "/actuators/:actuatorId";
|
||||||
|
public static final String POST_ACTUATORS = API_PREFIX + "/actuators";
|
||||||
|
public static final String PUT_ACTUATOR_BY_ID = API_PREFIX + "/actuators/:actuatorId";
|
||||||
|
|
||||||
|
public static final String GET_GPS_VALUES = API_PREFIX + "/gps-values";
|
||||||
|
public static final String GET_GPS_VALUE_BY_ID = API_PREFIX + "/gps-values/:valueId";
|
||||||
|
public static final String POST_GPS_VALUES = API_PREFIX + "/gps-values";
|
||||||
|
|
||||||
|
public static final String GET_AIR_VALUES = API_PREFIX + "/air-values";
|
||||||
|
public static final String GET_AIR_VALUE_BY_ID = API_PREFIX + "/air-values/:valueId";
|
||||||
|
public static final String POST_AIR_VALUES = API_PREFIX + "/air-values";
|
||||||
|
|
||||||
|
private Constants() {
|
||||||
|
throw new AssertionError("Utility class cannot be instantiated.");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package net.miarma.contaminus.common;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
|
import com.google.gson.JsonDeserializationContext;
|
||||||
|
import com.google.gson.JsonDeserializer;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
import com.google.gson.JsonPrimitive;
|
||||||
|
import com.google.gson.JsonSerializationContext;
|
||||||
|
import com.google.gson.JsonSerializer;
|
||||||
|
|
||||||
|
public class LocalDateTimeSerializer implements JsonSerializer<LocalDateTime>, JsonDeserializer<LocalDateTime> {
|
||||||
|
|
||||||
|
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonElement serialize(LocalDateTime src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
return new JsonPrimitive(src.format(FORMATTER));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LocalDateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||||
|
return LocalDateTime.parse(json.getAsString(), FORMATTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -42,6 +42,21 @@ public class QueryBuilder {
|
|||||||
return qb;
|
return qb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static QueryBuilder update(String table) {
|
||||||
|
QueryBuilder qb = new QueryBuilder();
|
||||||
|
qb.query.append("UPDATE ").append(table).append(" ");
|
||||||
|
return qb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public QueryBuilder set(String column, Object value) {
|
||||||
|
if(value instanceof String) {
|
||||||
|
query.append("SET ").append(column).append(" = '").append(value).append("' ");
|
||||||
|
} else {
|
||||||
|
query.append("SET ").append(column).append(" = ").append(value).append(" ");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public QueryBuilder values(Object... values) {
|
public QueryBuilder values(Object... values) {
|
||||||
StringJoiner joiner = new StringJoiner(", ", "VALUES (", ")");
|
StringJoiner joiner = new StringJoiner(", ", "VALUES (", ")");
|
||||||
for (Object value : values) {
|
for (Object value : values) {
|
||||||
@@ -83,7 +98,7 @@ public class QueryBuilder {
|
|||||||
limit = limitParam.isPresent() ? "LIMIT " + limitParam.get() + " " : "";
|
limit = limitParam.isPresent() ? "LIMIT " + limitParam.get() + " " : "";
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String build() {
|
public String build() {
|
||||||
if (!conditions.isEmpty()) {
|
if (!conditions.isEmpty()) {
|
||||||
query.append("WHERE ");
|
query.append("WHERE ");
|
||||||
@@ -104,4 +119,6 @@ public class QueryBuilder {
|
|||||||
}
|
}
|
||||||
return query.toString().trim() + ";";
|
return query.toString().trim() + ";";
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,359 @@
|
|||||||
|
package net.miarma.contaminus.server;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import io.vertx.core.AbstractVerticle;
|
||||||
|
import io.vertx.core.Promise;
|
||||||
|
import io.vertx.core.eventbus.Message;
|
||||||
|
import io.vertx.core.http.HttpMethod;
|
||||||
|
import io.vertx.core.json.JsonArray;
|
||||||
|
import io.vertx.core.json.JsonObject;
|
||||||
|
import io.vertx.ext.web.Router;
|
||||||
|
import io.vertx.ext.web.RoutingContext;
|
||||||
|
import io.vertx.ext.web.handler.BodyHandler;
|
||||||
|
import io.vertx.ext.web.handler.CorsHandler;
|
||||||
|
import net.miarma.contaminus.common.Constants;
|
||||||
|
import net.miarma.contaminus.common.Host;
|
||||||
|
import net.miarma.contaminus.database.QueryBuilder;
|
||||||
|
|
||||||
|
public class ApiVerticle extends AbstractVerticle {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start(Promise<Void> startPromise) {
|
||||||
|
Constants.LOGGER.info("🟢 Iniciando ApiVerticle...");
|
||||||
|
Router router = Router.router(vertx);
|
||||||
|
|
||||||
|
Set<HttpMethod> allowedMethods = new HashSet<>(Arrays.asList(HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT)); // Por ejemplo
|
||||||
|
Set<String> allowedHeaders = new HashSet<>(Arrays.asList("Content-Type", "Authorization"));
|
||||||
|
|
||||||
|
router.route().handler(CorsHandler.create()
|
||||||
|
.addOrigin(Host.getOrigin())
|
||||||
|
.allowCredentials(true)
|
||||||
|
.allowedHeaders(allowedHeaders)
|
||||||
|
.allowedMethods(allowedMethods));
|
||||||
|
router.route().handler(BodyHandler.create());
|
||||||
|
|
||||||
|
// Group Routes
|
||||||
|
router.route(HttpMethod.GET, Constants.GET_GROUPS).handler(this::getGroupsHandler);
|
||||||
|
router.route(HttpMethod.GET, Constants.GET_GROUP_BY_ID).handler(this::getGroupByIdHandler);
|
||||||
|
router.route(HttpMethod.GET, Constants.GET_GROUP_DEVICES).handler(this::getGroupDevicesHandler);
|
||||||
|
router.route(HttpMethod.POST, Constants.POST_GROUPS).handler(this::postGroupHandler);
|
||||||
|
router.route(HttpMethod.PUT, Constants.PUT_GROUP_BY_ID).handler(this::putGroupByIdHandler);
|
||||||
|
|
||||||
|
// Device Routes
|
||||||
|
router.route(HttpMethod.GET, Constants.GET_DEVICES).handler(this::getDevicesHandler);
|
||||||
|
router.route(HttpMethod.GET, Constants.GET_DEVICE_BY_ID).handler(this::getDeviceByIdHandler);
|
||||||
|
router.route(HttpMethod.GET, Constants.GET_DEVICE_SENSORS).handler(this::getDeviceSensorsHandler);
|
||||||
|
router.route(HttpMethod.POST, Constants.POST_DEVICES).handler(this::postDeviceHandler);
|
||||||
|
router.route(HttpMethod.PUT, Constants.PUT_DEVICE_BY_ID).handler(this::putDeviceByIdHandler);
|
||||||
|
|
||||||
|
// Sensor Routes
|
||||||
|
router.route(HttpMethod.GET, Constants.GET_SENSORS).handler(this::getSensorsHandler);
|
||||||
|
router.route(HttpMethod.GET, Constants.GET_SENSOR_BY_ID).handler(this::getSensorByIdHandler);
|
||||||
|
router.route(HttpMethod.GET, Constants.GET_SENSOR_VALUES).handler(this::getSensorValuesHandler);
|
||||||
|
router.route(HttpMethod.POST, Constants.POST_SENSORS).handler(this::postSensorHandler);
|
||||||
|
router.route(HttpMethod.PUT, Constants.PUT_SENSOR_BY_ID).handler(this::putSensorByIdHandler);
|
||||||
|
|
||||||
|
// Actuator Routes
|
||||||
|
router.route(HttpMethod.GET, Constants.GET_ACTUATORS).handler(this::getActuatorsHandler);
|
||||||
|
router.route(HttpMethod.GET, Constants.GET_ACTUATOR_BY_ID).handler(this::getActuatorByIdHandler);
|
||||||
|
router.route(HttpMethod.POST, Constants.POST_ACTUATORS).handler(this::postActuatorHandler);
|
||||||
|
router.route(HttpMethod.PUT, Constants.PUT_ACTUATOR_BY_ID).handler(this::putActuatorByIdHandler);
|
||||||
|
|
||||||
|
vertx.createHttpServer()
|
||||||
|
.requestHandler(router)
|
||||||
|
.listen(
|
||||||
|
Host.getApiPort(),
|
||||||
|
Host.getHost(),
|
||||||
|
result -> {
|
||||||
|
if (result.succeeded()) {
|
||||||
|
Constants.LOGGER.info(String.format(
|
||||||
|
"📡 ApiVerticle desplegado. (http://%s:%d)", Host.getHost(), Host.getApiPort()
|
||||||
|
));
|
||||||
|
startPromise.complete();
|
||||||
|
} else {
|
||||||
|
Constants.LOGGER.error("❌ Error al desplegar ApiVerticle", result.cause());
|
||||||
|
startPromise.fail(result.cause());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendQuery(String query, RoutingContext context) {
|
||||||
|
vertx.eventBus().request("db.query", query, req -> {
|
||||||
|
if (req.succeeded()) {
|
||||||
|
Message<Object> msg = req.result();
|
||||||
|
JsonArray jsonArray = new JsonArray(msg.body().toString());
|
||||||
|
context.json(jsonArray);
|
||||||
|
} else {
|
||||||
|
context.fail(500, req.cause());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Group Handlers
|
||||||
|
private void getGroupsHandler(RoutingContext context) {
|
||||||
|
String query = QueryBuilder.select("*").from("groups").build();
|
||||||
|
sendQuery(query, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getGroupByIdHandler(RoutingContext context) {
|
||||||
|
String groupId = context.request().getParam("groupId");
|
||||||
|
String query = QueryBuilder
|
||||||
|
.select("*")
|
||||||
|
.from("groups")
|
||||||
|
.where("groupId = ?", groupId)
|
||||||
|
.build();
|
||||||
|
sendQuery(query, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getGroupDevicesHandler(RoutingContext context) {
|
||||||
|
String groupId = context.request().getParam("groupId");
|
||||||
|
String query = QueryBuilder
|
||||||
|
.select("*")
|
||||||
|
.from("devices")
|
||||||
|
.where("groupId = ?", groupId)
|
||||||
|
.build();
|
||||||
|
sendQuery(query, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void postGroupHandler(RoutingContext context) {
|
||||||
|
JsonObject body = context.body().asJsonObject();
|
||||||
|
|
||||||
|
if(body == null) {
|
||||||
|
context.fail(400, new IllegalArgumentException("Bad request"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String groupName = body.getString("groupName");
|
||||||
|
|
||||||
|
String query = QueryBuilder
|
||||||
|
.insert("groups", "groupName")
|
||||||
|
.values(groupName)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
sendQuery(query, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void putGroupByIdHandler(RoutingContext context) {
|
||||||
|
String groupId = context.request().getParam("groupId");
|
||||||
|
JsonObject body = context.body().asJsonObject();
|
||||||
|
|
||||||
|
if(body == null) {
|
||||||
|
context.fail(400, new IllegalArgumentException("Bad request"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String groupName = body.getString("groupName");
|
||||||
|
|
||||||
|
String query = QueryBuilder
|
||||||
|
.update("groups")
|
||||||
|
.set("groupName", groupName)
|
||||||
|
.where("groupId = ?", groupId)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
sendQuery(query, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Device Handlers
|
||||||
|
private void getDevicesHandler(RoutingContext context) {
|
||||||
|
String query = QueryBuilder.select("*").from("devices").build();
|
||||||
|
sendQuery(query, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getDeviceByIdHandler(RoutingContext context) {
|
||||||
|
String deviceId = context.request().getParam("deviceId");
|
||||||
|
String query = QueryBuilder
|
||||||
|
.select("*")
|
||||||
|
.from("devices")
|
||||||
|
.where("deviceId = ?", deviceId)
|
||||||
|
.build();
|
||||||
|
sendQuery(query, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getDeviceSensorsHandler(RoutingContext context) {
|
||||||
|
String deviceId = context.request().getParam("deviceId");
|
||||||
|
String query = QueryBuilder
|
||||||
|
.select("*")
|
||||||
|
.from("sensors")
|
||||||
|
.where("deviceId = ?", deviceId)
|
||||||
|
.build();
|
||||||
|
sendQuery(query, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void postDeviceHandler(RoutingContext context) {
|
||||||
|
JsonObject body = context.body().asJsonObject();
|
||||||
|
|
||||||
|
if(body == null) {
|
||||||
|
context.fail(400, new IllegalArgumentException("Bad request"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer groupId = body.getInteger("groupId");
|
||||||
|
String deviceName = body.getString("groupName");
|
||||||
|
|
||||||
|
String query = QueryBuilder
|
||||||
|
.insert("devices", "groupId", "deviceName")
|
||||||
|
.values(groupId, deviceName)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
sendQuery(query, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void putDeviceByIdHandler(RoutingContext context) {
|
||||||
|
String deviceId = context.request().getParam("deviceId");
|
||||||
|
JsonObject body = context.body().asJsonObject();
|
||||||
|
|
||||||
|
if(body == null) {
|
||||||
|
context.fail(400, new IllegalArgumentException("Bad request"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer groupId = body.getInteger("groupId");
|
||||||
|
String deviceName = body.getString("deviceName");
|
||||||
|
|
||||||
|
String query = QueryBuilder
|
||||||
|
.update("devices")
|
||||||
|
.set("groupId", groupId)
|
||||||
|
.set("deviceName", deviceName)
|
||||||
|
.where("deviceId = ?", deviceId)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
sendQuery(query, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sensor Handlers
|
||||||
|
private void getSensorsHandler(RoutingContext context) {
|
||||||
|
String query = QueryBuilder.select("*").from("sensors").build();
|
||||||
|
sendQuery(query, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getSensorByIdHandler(RoutingContext context) {
|
||||||
|
String sensorId = context.request().getParam("sensorId");
|
||||||
|
String query = QueryBuilder
|
||||||
|
.select("*")
|
||||||
|
.from("sensors")
|
||||||
|
.where("sensorId = ?", sensorId)
|
||||||
|
.build();
|
||||||
|
sendQuery(query, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getSensorValuesHandler(RoutingContext context) {
|
||||||
|
String sensorId = context.request().getParam("sensorId");
|
||||||
|
String query = QueryBuilder
|
||||||
|
.select("*")
|
||||||
|
.from("v_sensor_values")
|
||||||
|
.where("sensorId = ?", sensorId)
|
||||||
|
.build();
|
||||||
|
sendQuery(query, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void postSensorHandler(RoutingContext context) {
|
||||||
|
JsonObject body = context.body().asJsonObject();
|
||||||
|
|
||||||
|
if(body == null) {
|
||||||
|
context.fail(400, new IllegalArgumentException("Bad request"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer deviceId = body.getInteger("deviceId");
|
||||||
|
String sensorType = body.getString("sensorType");
|
||||||
|
String unit = body.getString("unit");
|
||||||
|
Integer status = body.getInteger("status");
|
||||||
|
|
||||||
|
String query = QueryBuilder
|
||||||
|
.insert("sensors", "deviceId", "sensorType", "unit", "status")
|
||||||
|
.values(deviceId, sensorType, unit, status)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
sendQuery(query, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void putSensorByIdHandler(RoutingContext context) {
|
||||||
|
String sensorId = context.request().getParam("sensorId");
|
||||||
|
JsonObject body = context.body().asJsonObject();
|
||||||
|
|
||||||
|
if(body == null) {
|
||||||
|
context.fail(400, new IllegalArgumentException("Bad request"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer deviceId = body.getInteger("deviceId");
|
||||||
|
String sensorType = body.getString("sensorType");
|
||||||
|
String unit = body.getString("unit");
|
||||||
|
Integer status = body.getInteger("status");
|
||||||
|
|
||||||
|
String query = QueryBuilder
|
||||||
|
.update("sensors")
|
||||||
|
.set("deviceId", deviceId)
|
||||||
|
.set("sensorType", sensorType)
|
||||||
|
.set("unit", unit)
|
||||||
|
.set("status", status)
|
||||||
|
.where("sensorId = ?", sensorId)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
sendQuery(query, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actuator Handlers
|
||||||
|
private void getActuatorsHandler(RoutingContext context) {
|
||||||
|
String query = QueryBuilder.select("*").from("actuators").build();
|
||||||
|
sendQuery(query, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getActuatorByIdHandler(RoutingContext context) {
|
||||||
|
String actuatorId = context.request().getParam("actuatorId");
|
||||||
|
|
||||||
|
String query = QueryBuilder
|
||||||
|
.select("*")
|
||||||
|
.from("actuators")
|
||||||
|
.where("actuatorId = ?", actuatorId)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
sendQuery(query, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void postActuatorHandler(RoutingContext context) {
|
||||||
|
JsonObject body = context.body().asJsonObject();
|
||||||
|
|
||||||
|
if(body == null) {
|
||||||
|
context.fail(400, new IllegalArgumentException("Bad request"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer deviceId = body.getInteger("deviceId");
|
||||||
|
Integer status = body.getInteger("status");
|
||||||
|
|
||||||
|
String query = QueryBuilder
|
||||||
|
.insert("actuators", "deviceId", "status")
|
||||||
|
.values(deviceId, status)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
sendQuery(query, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void putActuatorByIdHandler(RoutingContext context) {
|
||||||
|
String actuatorId = context.request().getParam("actuatorId");
|
||||||
|
JsonObject body = context.body().asJsonObject();
|
||||||
|
|
||||||
|
if(body == null) {
|
||||||
|
context.fail(400, new IllegalArgumentException("Bad request"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer deviceId = body.getInteger("deviceId");
|
||||||
|
Integer status = body.getInteger("status");
|
||||||
|
|
||||||
|
String query = QueryBuilder
|
||||||
|
.update("actuators")
|
||||||
|
.set("deviceId", deviceId)
|
||||||
|
.set("status", status)
|
||||||
|
.where("actuatorId = ?", actuatorId)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
sendQuery(query, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
package net.miarma.contaminus.server;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
|
||||||
|
import io.vertx.core.AbstractVerticle;
|
||||||
|
import io.vertx.core.Promise;
|
||||||
|
import io.vertx.core.eventbus.EventBus;
|
||||||
|
import io.vertx.core.eventbus.Message;
|
||||||
|
import io.vertx.core.json.JsonObject;
|
||||||
|
import io.vertx.jdbcclient.JDBCPool;
|
||||||
|
import io.vertx.sqlclient.Row;
|
||||||
|
import net.miarma.contaminus.common.Constants;
|
||||||
|
import net.miarma.contaminus.common.LocalDateTimeSerializer;
|
||||||
|
import net.miarma.contaminus.database.DatabaseManager;
|
||||||
|
|
||||||
|
public class DatabaseVerticle extends AbstractVerticle {
|
||||||
|
private JDBCPool pool;
|
||||||
|
private EventBus eventBus;
|
||||||
|
private Gson gson = new GsonBuilder()
|
||||||
|
.registerTypeAdapter(LocalDateTime.class, new LocalDateTimeSerializer())
|
||||||
|
.create();;
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Override
|
||||||
|
public void start(Promise<Void> startPromise) {
|
||||||
|
Constants.LOGGER.info("🟢 Iniciando DatabaseVerticle...");
|
||||||
|
|
||||||
|
DatabaseManager dbManager = new DatabaseManager(vertx);
|
||||||
|
pool = dbManager.getPool();
|
||||||
|
eventBus = vertx.eventBus();
|
||||||
|
|
||||||
|
pool.query("SELECT 1")
|
||||||
|
.execute()
|
||||||
|
.onSuccess(_res -> {
|
||||||
|
Constants.LOGGER.info("✅ Database connection ok");
|
||||||
|
Constants.LOGGER.info("📡 DatabaseVerticle desplegado");
|
||||||
|
startPromise.complete();
|
||||||
|
})
|
||||||
|
.onFailure(err -> {
|
||||||
|
Constants.LOGGER.error("❌ Database connection failed");
|
||||||
|
Constants.LOGGER.error("❌ Error al desplegar DatabaseVerticle", err);
|
||||||
|
startPromise.fail(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
eventBus.consumer("db.query", this::handleDatabaseQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleDatabaseQuery(Message<String> msg) {
|
||||||
|
String query = msg.body();
|
||||||
|
Constants.LOGGER.info("📥 Query: " + query);
|
||||||
|
|
||||||
|
if(query == null || query.isEmpty()) {
|
||||||
|
msg.fail(400, "Empty query");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(query.startsWith("SELECT")) {
|
||||||
|
handleSelectQuery(query, msg);
|
||||||
|
} else if(query.startsWith("INSERT")) {
|
||||||
|
handleInsertQuery(query, msg);
|
||||||
|
} else if(query.startsWith("UPDATE")) {
|
||||||
|
handleUpdateQuery(query, msg);
|
||||||
|
} else {
|
||||||
|
msg.fail(400, "Invalid operation");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleSelectQuery(String query, Message<String> msg) {
|
||||||
|
pool.query(query).execute()
|
||||||
|
.onSuccess(res -> {
|
||||||
|
List<Map<String, Object>> rowsList = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Row row : res) {
|
||||||
|
Map<String, Object> rowMap = new HashMap<>();
|
||||||
|
for (int i = 0; i < row.size(); i++) {
|
||||||
|
String columnName = res.columnsNames().get(i);
|
||||||
|
Object columnValue = row.getValue(i);
|
||||||
|
rowMap.put(columnName, columnValue);
|
||||||
|
}
|
||||||
|
rowsList.add(rowMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
String jsonResponse = gson.toJson(rowsList);
|
||||||
|
msg.reply(jsonResponse);
|
||||||
|
})
|
||||||
|
.onFailure(err -> msg.fail(500, err.getMessage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private void handleInsertQuery(String query, Message<String> msg) {
|
||||||
|
pool.query(query).execute()
|
||||||
|
.onSuccess(_res -> {
|
||||||
|
JsonObject response = new JsonObject();
|
||||||
|
response.put("status", "success");
|
||||||
|
String jsonResponse = gson.toJson(response);
|
||||||
|
msg.reply(jsonResponse);
|
||||||
|
})
|
||||||
|
.onFailure(err -> msg.fail(500, err.getMessage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private void handleUpdateQuery(String query, Message<String> msg) {
|
||||||
|
pool.query(query).execute()
|
||||||
|
.onSuccess(_res -> {
|
||||||
|
JsonObject response = new JsonObject();
|
||||||
|
response.put("status", "updated");
|
||||||
|
String jsonResponse = gson.toJson(response);
|
||||||
|
msg.reply(jsonResponse);
|
||||||
|
})
|
||||||
|
.onFailure(err -> msg.fail(500, err.getMessage()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 412 KiB After Width: | Height: | Size: 412 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 412 KiB After Width: | Height: | Size: 412 KiB |
@@ -1,22 +0,0 @@
|
|||||||
package net.miarma.contaminus.common;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
import io.vertx.core.impl.logging.Logger;
|
|
||||||
import io.vertx.core.impl.logging.LoggerFactory;
|
|
||||||
|
|
||||||
public class Constants {
|
|
||||||
public static final String APP_NAME = "ContaminUS";
|
|
||||||
public static final String API_PREFIX = "/api/v1";
|
|
||||||
public static final String HOME_DIR = System.getProperty("user.home") + File.separator;
|
|
||||||
public static final String BASE_DIR = HOME_DIR +
|
|
||||||
(SystemInfo.getOS() == OSType.WINDOWS ? ".contaminus" :
|
|
||||||
SystemInfo.getOS() == OSType.LINUX ? ".config" + File.separator +
|
|
||||||
"contaminus" : null);
|
|
||||||
public static final String CONFIG_FILE = BASE_DIR + File.separator + "config.properties";
|
|
||||||
public static final Logger LOGGER = LoggerFactory.getLogger(APP_NAME);
|
|
||||||
|
|
||||||
private Constants() {
|
|
||||||
throw new AssertionError("Utility class cannot be instantiated.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
package net.miarma.contaminus.database.models;
|
|
||||||
|
|
||||||
import java.sql.Timestamp;
|
|
||||||
|
|
||||||
public class Sensor {
|
|
||||||
private int id;
|
|
||||||
private String sensorType;
|
|
||||||
private float value;
|
|
||||||
private float lat;
|
|
||||||
private float lon;
|
|
||||||
private Timestamp timestamp;
|
|
||||||
|
|
||||||
public Sensor() {}
|
|
||||||
|
|
||||||
public Sensor(int id, String sensorType, float value, float lat, float lon, Timestamp timestamp) {
|
|
||||||
this.id = id;
|
|
||||||
this.sensorType = sensorType;
|
|
||||||
this.value = value;
|
|
||||||
this.lat = lat;
|
|
||||||
this.lon = lon;
|
|
||||||
this.timestamp = timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(int id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSensorType() {
|
|
||||||
return sensorType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSensorType(String sensorType) {
|
|
||||||
this.sensorType = sensorType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValue(float value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 Timestamp getTimestamp() {
|
|
||||||
return timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTimestamp(Timestamp timestamp) {
|
|
||||||
this.timestamp = timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Sensor{" +
|
|
||||||
"id=" + id +
|
|
||||||
", sensorType='" + sensorType + '\'' +
|
|
||||||
", value=" + value +
|
|
||||||
", lat=" + lat +
|
|
||||||
", lon=" + lon +
|
|
||||||
", timestamp=" + timestamp +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,157 +0,0 @@
|
|||||||
package net.miarma.contaminus.server;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import io.vertx.core.AbstractVerticle;
|
|
||||||
import io.vertx.core.Promise;
|
|
||||||
import io.vertx.core.eventbus.Message;
|
|
||||||
import io.vertx.core.http.HttpMethod;
|
|
||||||
import io.vertx.core.json.JsonArray;
|
|
||||||
import io.vertx.core.json.JsonObject;
|
|
||||||
import io.vertx.ext.web.Router;
|
|
||||||
import io.vertx.ext.web.RoutingContext;
|
|
||||||
import io.vertx.ext.web.handler.BodyHandler;
|
|
||||||
import io.vertx.ext.web.handler.CorsHandler;
|
|
||||||
import net.miarma.contaminus.common.Constants;
|
|
||||||
import net.miarma.contaminus.common.Host;
|
|
||||||
import net.miarma.contaminus.database.QueryBuilder;
|
|
||||||
|
|
||||||
public class ApiVerticle extends AbstractVerticle {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void start(Promise<Void> startPromise) {
|
|
||||||
Constants.LOGGER.info("🟢 Iniciando ApiVerticle...");
|
|
||||||
Router router = Router.router(vertx);
|
|
||||||
|
|
||||||
Set<HttpMethod> allowedMethods = new HashSet<>(Arrays.asList(HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT)); // Por ejemplo
|
|
||||||
Set<String> allowedHeaders = new HashSet<>(Arrays.asList("Content-Type", "Authorization"));
|
|
||||||
|
|
||||||
router.route().handler(CorsHandler.create()
|
|
||||||
.addOrigin(Host.getOrigin())
|
|
||||||
.allowCredentials(true)
|
|
||||||
.allowedHeaders(allowedHeaders)
|
|
||||||
.allowedMethods(allowedMethods));
|
|
||||||
router.route().handler(BodyHandler.create());
|
|
||||||
router.get(Constants.API_PREFIX + "/devices").blockingHandler(this::getAllDevices);
|
|
||||||
router.get(Constants.API_PREFIX + "/devices/:id").blockingHandler(this::getDeviceById);
|
|
||||||
router.post(Constants.API_PREFIX + "/devices").blockingHandler(this::insertSensor);
|
|
||||||
router.get(Constants.API_PREFIX + "/status").handler(ctx -> ctx.json(new JsonObject().put("status", "OK")));
|
|
||||||
|
|
||||||
vertx.createHttpServer()
|
|
||||||
.requestHandler(router)
|
|
||||||
.listen(
|
|
||||||
Host.getApiPort(),
|
|
||||||
Host.getHost(),
|
|
||||||
result -> {
|
|
||||||
if (result.succeeded()) {
|
|
||||||
Constants.LOGGER.info(String.format(
|
|
||||||
"📡 ApiVerticle desplegado. (http://%s:%d)", Host.getHost(), Host.getApiPort()
|
|
||||||
));
|
|
||||||
startPromise.complete();
|
|
||||||
} else {
|
|
||||||
Constants.LOGGER.error("❌ Error al desplegar ApiVerticle", result.cause());
|
|
||||||
startPromise.fail(result.cause());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void getAllDevices(RoutingContext context) {
|
|
||||||
Optional<String> sort = Optional.ofNullable(context.request().getParam("_sort"));
|
|
||||||
Optional<String> order = Optional.ofNullable(context.request().getParam("_order"));
|
|
||||||
Optional<Integer> limit = Optional.ofNullable(context.request().getParam("_limit"))
|
|
||||||
.map(s -> {
|
|
||||||
try {
|
|
||||||
return Integer.parseInt(s);
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
String query = QueryBuilder
|
|
||||||
.select("*")
|
|
||||||
.from("v_DevicesMeasures")
|
|
||||||
.orderBy(sort, order)
|
|
||||||
.limit(limit)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
vertx.eventBus().request("db.query", query, req -> {
|
|
||||||
if (req.succeeded()) {
|
|
||||||
Message<Object> result = req.result();
|
|
||||||
JsonArray jsonArray = (JsonArray) result.body();
|
|
||||||
context.json(jsonArray);
|
|
||||||
} else {
|
|
||||||
context.fail(500, req.cause());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void getDeviceById(RoutingContext context) {
|
|
||||||
Optional<String> sort = Optional.ofNullable(context.request().getParam("_sort"));
|
|
||||||
Optional<String> order = Optional.ofNullable(context.request().getParam("_order"));
|
|
||||||
Optional<Integer> limit = Optional.ofNullable(context.request().getParam("_limit"))
|
|
||||||
.map(s -> {
|
|
||||||
try {
|
|
||||||
return Integer.parseInt(s);
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
String id = context.request().getParam("id");
|
|
||||||
String query = QueryBuilder
|
|
||||||
.select("*")
|
|
||||||
.from("v_DevicesMeasures")
|
|
||||||
.where("deviceId = ?", id)
|
|
||||||
.orderBy(sort, order)
|
|
||||||
.limit(limit)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
vertx.eventBus().request("db.query", query, req -> {
|
|
||||||
if (req.succeeded()) {
|
|
||||||
Message<Object> result = req.result();
|
|
||||||
JsonArray jsonArray = (JsonArray) result.body();
|
|
||||||
context.json(jsonArray);
|
|
||||||
} else {
|
|
||||||
context.fail(500, req.cause());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void insertSensor(RoutingContext context) {
|
|
||||||
JsonObject body = context.body().asJsonObject();
|
|
||||||
|
|
||||||
if (body == null) {
|
|
||||||
context.fail(400, new IllegalArgumentException("Body is missing or invalid"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Integer deviceId = body.getInteger("deviceId");
|
|
||||||
String sensorType = body.getString("sensorType");
|
|
||||||
Float lat = body.getFloat("lat");
|
|
||||||
Float lon = body.getFloat("lon");
|
|
||||||
Float value = body.getFloat("value");
|
|
||||||
|
|
||||||
if (sensorType == null || lat == null || lon == null || value == null) {
|
|
||||||
context.fail(400, new IllegalArgumentException("Missing required fields"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String query = QueryBuilder
|
|
||||||
.insert("measures", "deviceId", "sensorType", "lat", "lon", "value")
|
|
||||||
.values(deviceId, sensorType, lat, lon, value)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
vertx.eventBus().request("db.query", query, req -> {
|
|
||||||
if (req.succeeded()) {
|
|
||||||
context.json(new JsonObject().put("result", "OK"));
|
|
||||||
} else {
|
|
||||||
context.fail(500, req.cause());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
package net.miarma.contaminus.server;
|
|
||||||
|
|
||||||
import io.vertx.core.AbstractVerticle;
|
|
||||||
import io.vertx.core.Promise;
|
|
||||||
import io.vertx.core.eventbus.EventBus;
|
|
||||||
import io.vertx.core.eventbus.Message;
|
|
||||||
import io.vertx.core.json.JsonArray;
|
|
||||||
import io.vertx.core.json.JsonObject;
|
|
||||||
import io.vertx.jdbcclient.JDBCPool;
|
|
||||||
import io.vertx.sqlclient.Row;
|
|
||||||
import io.vertx.sqlclient.RowSet;
|
|
||||||
import net.miarma.contaminus.common.Constants;
|
|
||||||
import net.miarma.contaminus.database.DatabaseManager;
|
|
||||||
|
|
||||||
public class DatabaseVerticle extends AbstractVerticle {
|
|
||||||
private JDBCPool pool;
|
|
||||||
private EventBus eventBus;
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
@Override
|
|
||||||
public void start(Promise<Void> startPromise) {
|
|
||||||
Constants.LOGGER.info("🟢 Iniciando DatabaseVerticle...");
|
|
||||||
|
|
||||||
DatabaseManager dbManager = new DatabaseManager(vertx);
|
|
||||||
pool = dbManager.getPool();
|
|
||||||
eventBus = vertx.eventBus();
|
|
||||||
|
|
||||||
pool.query("SELECT 1")
|
|
||||||
.execute()
|
|
||||||
.onSuccess(_res -> {
|
|
||||||
Constants.LOGGER.info("✅ Database connection ok");
|
|
||||||
Constants.LOGGER.info("📡 DatabaseVerticle desplegado");
|
|
||||||
startPromise.complete();
|
|
||||||
})
|
|
||||||
.onFailure(err -> {
|
|
||||||
Constants.LOGGER.error("❌ Database connection failed");
|
|
||||||
Constants.LOGGER.error("❌ Error al desplegar DatabaseVerticle", err);
|
|
||||||
startPromise.fail(err);
|
|
||||||
});
|
|
||||||
|
|
||||||
eventBus.consumer("db.query", this::handleDatabaseQuery);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private void handleDatabaseQuery(Message<String> msg) {
|
|
||||||
String query = msg.body();
|
|
||||||
Constants.LOGGER.info("📥 Query: " + query);
|
|
||||||
|
|
||||||
if(query == null || query.isEmpty()) {
|
|
||||||
msg.fail(400, "Empty query");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(query.startsWith("SELECT")) {
|
|
||||||
pool.query(query).execute()
|
|
||||||
.onSuccess(res -> {
|
|
||||||
RowSet<Row> rows = res;
|
|
||||||
JsonArray jsonArray = new JsonArray();
|
|
||||||
for (Row row : rows) {
|
|
||||||
jsonArray.add(new JsonObject()
|
|
||||||
.put("deviceId", row.getInteger("deviceId"))
|
|
||||||
.put("deviceName", row.getString("deviceName"))
|
|
||||||
.put("measureId", row.getInteger("measureId"))
|
|
||||||
.put("sensorType", row.getString("sensorType"))
|
|
||||||
.put("lat", row.getFloat("lat"))
|
|
||||||
.put("lon", row.getFloat("lon"))
|
|
||||||
.put("value", row.getFloat("value"))
|
|
||||||
.put("timestamp", row.getLocalDateTime("timestamp").toString())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
msg.reply(jsonArray);
|
|
||||||
})
|
|
||||||
.onFailure(err -> msg.fail(500, err.getMessage()));
|
|
||||||
} else if(query.startsWith("INSERT")) {
|
|
||||||
pool.query(msg.body()).execute()
|
|
||||||
.onSuccess(_res -> msg.reply(new JsonObject().put("status", "success")))
|
|
||||||
.onFailure(err -> msg.fail(500, err.getMessage()));
|
|
||||||
} else {
|
|
||||||
msg.fail(400, "Invalid operation");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
6
package-lock.json
generated
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "ContaminUS",
|
|
||||||
"lockfileVersion": 3,
|
|
||||||
"requires": true,
|
|
||||||
"packages": {}
|
|
||||||
}
|
|
||||||