+ up
This commit is contained in:
@@ -53,16 +53,16 @@ services:
|
|||||||
container_name: iiko-app
|
container_name: iiko-app
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
ports:
|
||||||
- "7104:8080"
|
- "7104:7104"
|
||||||
depends_on:
|
depends_on:
|
||||||
- db
|
- db
|
||||||
- redis
|
- redis
|
||||||
environment:
|
environment:
|
||||||
DB_HOST: db
|
DATABASE__HOST: db
|
||||||
DB_PORT: 3306
|
DATABASE__PORT: 3306
|
||||||
DB_NAME: app_db
|
DATABASE__DATABASE: app_db
|
||||||
DB_USER: app_user
|
DATABASE__USER: app_user
|
||||||
DB_PASSWORD: app_pass
|
DATABASE__PASSWORD: app_pass
|
||||||
REDIS_HOST: redis
|
REDIS__HOST: redis
|
||||||
REDIS_PORT: 6379
|
REDIS__PORT: 6379
|
||||||
HTTP_PORT: 8080
|
SERVER__PORT: 7104
|
||||||
|
|||||||
@@ -1,61 +1,60 @@
|
|||||||
package su.xserver.iikocon;
|
package su.xserver.iikocon;
|
||||||
|
|
||||||
|
import io.vertx.config.ConfigRetriever;
|
||||||
|
import io.vertx.config.ConfigRetrieverOptions;
|
||||||
|
import io.vertx.config.ConfigStoreOptions;
|
||||||
import io.vertx.core.AbstractVerticle;
|
import io.vertx.core.AbstractVerticle;
|
||||||
import io.vertx.core.Promise;
|
import io.vertx.core.Promise;
|
||||||
|
import io.vertx.core.http.HttpServer;
|
||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
import io.vertx.ext.healthchecks.HealthChecks;
|
|
||||||
import io.vertx.ext.healthchecks.Status;
|
|
||||||
import io.vertx.ext.web.Router;
|
import io.vertx.ext.web.Router;
|
||||||
import io.vertx.ext.web.handler.BodyHandler;
|
import io.vertx.ext.web.handler.BodyHandler;
|
||||||
import io.vertx.ext.web.handler.SessionHandler;
|
import io.vertx.ext.web.handler.SessionHandler;
|
||||||
import io.vertx.ext.web.handler.StaticHandler;
|
import io.vertx.ext.web.handler.StaticHandler;
|
||||||
import io.vertx.ext.web.sstore.LocalSessionStore;
|
import io.vertx.ext.web.sstore.LocalSessionStore;
|
||||||
import io.vertx.ext.web.sstore.SessionStore;
|
import io.vertx.ext.web.sstore.SessionStore;
|
||||||
import io.vertx.ext.web.sstore.redis.RedisSessionStore;
|
|
||||||
import io.vertx.mysqlclient.MySQLConnectOptions;
|
|
||||||
import io.vertx.redis.client.Redis;
|
|
||||||
import io.vertx.redis.client.RedisAPI;
|
|
||||||
import io.vertx.redis.client.RedisOptions;
|
|
||||||
import io.vertx.sqlclient.Pool;
|
|
||||||
|
|
||||||
import io.vertx.sqlclient.PoolOptions;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import su.xserver.iikocon.config.AppConfig;
|
||||||
import java.util.Collections;
|
import su.xserver.iikocon.service.DataBaseService;
|
||||||
|
import su.xserver.iikocon.service.HealthCheckService;
|
||||||
|
import su.xserver.iikocon.service.RedisService;
|
||||||
|
|
||||||
public class MainVerticle extends AbstractVerticle {
|
public class MainVerticle extends AbstractVerticle {
|
||||||
private static final Logger log = LoggerFactory.getLogger(MainVerticle.class);
|
|
||||||
|
|
||||||
private Pool dbPool;
|
private final Logger log = LoggerFactory.getLogger("[MainVerticle]");
|
||||||
|
|
||||||
|
private DataBaseService db;
|
||||||
|
private RedisService redis;
|
||||||
|
private HttpServer httpServer;
|
||||||
|
private AppConfig config;
|
||||||
|
|
||||||
private UserService userService;
|
private UserService userService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start(Promise<Void> startPromise) {
|
public void start(Promise<Void> startPromise) {
|
||||||
// Конфигурация из переменных окружения
|
|
||||||
JsonObject config = new JsonObject()
|
|
||||||
.put("db_host", System.getenv().getOrDefault("DB_HOST", "localhost"))
|
|
||||||
.put("db_port", Integer.parseInt(System.getenv().getOrDefault("DB_PORT", "3306")))
|
|
||||||
.put("db_name", System.getenv().getOrDefault("DB_NAME", "admin_db"))
|
|
||||||
.put("db_user", System.getenv().getOrDefault("DB_USER", "admin_user"))
|
|
||||||
.put("db_password", System.getenv().getOrDefault("DB_PASSWORD", "admin_pass"))
|
|
||||||
.put("http_port", Integer.parseInt(System.getenv().getOrDefault("HTTP_PORT", "8080")));
|
|
||||||
|
|
||||||
log.info("Starting with config: {}", config.encodePrettily());
|
ConfigStoreOptions classpathStore = new ConfigStoreOptions()
|
||||||
|
.setType("file")
|
||||||
|
.setFormat("json")
|
||||||
|
.setConfig(new JsonObject().put("path", "config.json").put("hierarchical", true))
|
||||||
|
.setOptional(false);
|
||||||
|
|
||||||
// Подключение к MariaDB
|
ConfigRetrieverOptions options = new ConfigRetrieverOptions()
|
||||||
MySQLConnectOptions connectOptions = new MySQLConnectOptions()
|
.addStore(classpathStore);
|
||||||
.setHost(config.getString("db_host"))
|
|
||||||
.setPort(config.getInteger("db_port"))
|
|
||||||
.setDatabase(config.getString("db_name"))
|
|
||||||
.setUser(config.getString("db_user"))
|
|
||||||
.setPassword(config.getString("db_password"));
|
|
||||||
|
|
||||||
PoolOptions poolOptions = new PoolOptions().setMaxSize(5);
|
ConfigRetriever retriever = ConfigRetriever.create(vertx, options);
|
||||||
dbPool = Pool.pool(vertx, connectOptions, poolOptions);
|
|
||||||
|
retriever.getConfig()
|
||||||
|
.onSuccess(cfg -> {
|
||||||
|
config = AppConfig.from(cfg);
|
||||||
|
|
||||||
|
db = new DataBaseService(vertx, config.database);
|
||||||
|
redis = new RedisService(vertx, config.redis);
|
||||||
|
|
||||||
// Инициализация сервисов
|
// Инициализация сервисов
|
||||||
userService = new UserService(dbPool);
|
userService = new UserService(db.getPool());
|
||||||
|
|
||||||
// Инициализация БД (создание таблицы users)
|
// Инициализация БД (создание таблицы users)
|
||||||
userService.initDatabase()
|
userService.initDatabase()
|
||||||
@@ -66,6 +65,17 @@ public class MainVerticle extends AbstractVerticle {
|
|||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Router router = initRouter();
|
||||||
|
|
||||||
|
startHttp(router, startPromise);
|
||||||
|
|
||||||
|
})
|
||||||
|
.onFailure(startPromise::fail);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Router initRouter() {
|
||||||
|
|
||||||
// Настройка сессий (используем LocalSessionStore для простоты)
|
// Настройка сессий (используем LocalSessionStore для простоты)
|
||||||
SessionStore sessionStore = LocalSessionStore.create(vertx);
|
SessionStore sessionStore = LocalSessionStore.create(vertx);
|
||||||
SessionHandler sessionHandler = SessionHandler.create(sessionStore)
|
SessionHandler sessionHandler = SessionHandler.create(sessionStore)
|
||||||
@@ -95,27 +105,8 @@ public class MainVerticle extends AbstractVerticle {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Health Checks
|
// Health Checks
|
||||||
HealthChecks hc = HealthChecks.create(vertx);
|
HealthCheckService healthCheckService = new HealthCheckService(vertx, redis, db);
|
||||||
hc.register("database", promise ->
|
healthCheckService.registerHealthCheck(router);
|
||||||
dbPool.getConnection().onComplete(ar -> {
|
|
||||||
if (ar.succeeded()) {
|
|
||||||
ar.result().close();
|
|
||||||
promise.complete(Status.OK());
|
|
||||||
} else {
|
|
||||||
promise.fail(ar.cause());
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
router.get("/health").handler(rc ->
|
|
||||||
hc.checkStatus().onComplete(ar -> {
|
|
||||||
if (ar.succeeded()) {
|
|
||||||
rc.response().end(ar.result().toJson().encodePrettily());
|
|
||||||
} else {
|
|
||||||
rc.response().setStatusCode(503).end(ar.cause().getMessage());
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
// API маршруты
|
// API маршруты
|
||||||
AuthHandler authHandler = new AuthHandler(userService);
|
AuthHandler authHandler = new AuthHandler(userService);
|
||||||
@@ -169,26 +160,37 @@ public class MainVerticle extends AbstractVerticle {
|
|||||||
.setCachingEnabled(false)
|
.setCachingEnabled(false)
|
||||||
.setIndexPage("index.html"));
|
.setIndexPage("index.html"));
|
||||||
|
|
||||||
// Запуск HTTP сервера
|
return router;
|
||||||
int port = config.getInteger("http_port");
|
|
||||||
vertx.createHttpServer()
|
|
||||||
.requestHandler(router)
|
|
||||||
.listen(port).onComplete(http -> {
|
|
||||||
if (http.succeeded()) {
|
|
||||||
log.info("HTTP server started on port {}", port);
|
|
||||||
startPromise.complete();
|
|
||||||
} else {
|
|
||||||
log.error("Failed to start HTTP server", http.cause());
|
|
||||||
startPromise.fail(http.cause());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void startHttp(Router router, Promise<Void> startPromise) {
|
||||||
|
// Запуск HTTP-сервера
|
||||||
|
httpServer = vertx.createHttpServer();
|
||||||
|
httpServer.requestHandler(router).listen(config.server.port, config.server.host)
|
||||||
|
.onSuccess(server -> {
|
||||||
|
log.info("HTTP server started on port {}", server.actualPort());
|
||||||
|
startPromise.complete();
|
||||||
|
})
|
||||||
|
.onFailure(throwable -> {
|
||||||
|
log.error(throwable.getMessage());
|
||||||
|
startPromise.fail(throwable);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stop(Promise<Void> stopPromise) {
|
public void stop(Promise<Void> stopPromise) {
|
||||||
if (dbPool != null) {
|
this.httpServer.close()
|
||||||
dbPool.close();
|
.onSuccess(server -> {
|
||||||
}
|
log.info("Stop HTTP server");
|
||||||
|
this.db.disconnect();
|
||||||
|
this.redis.disconnect();
|
||||||
|
this.vertx.close()
|
||||||
|
.onSuccess(vertx -> {
|
||||||
|
log.info("Stop Vert.x");
|
||||||
stopPromise.complete();
|
stopPromise.complete();
|
||||||
|
})
|
||||||
|
.onFailure(throwable -> log.info(throwable.getMessage()));
|
||||||
|
})
|
||||||
|
.onFailure(throwable -> log.info(throwable.getMessage()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
105
src/main/java/su/xserver/iikocon/config/AppConfig.java
Normal file
105
src/main/java/su/xserver/iikocon/config/AppConfig.java
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
package su.xserver.iikocon.config;
|
||||||
|
|
||||||
|
import io.vertx.core.json.JsonObject;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class AppConfig {
|
||||||
|
|
||||||
|
public ServerConfig server;
|
||||||
|
public DatabaseConfig database;
|
||||||
|
public RedisConfig redis;
|
||||||
|
|
||||||
|
public static AppConfig from(JsonObject json) {
|
||||||
|
JsonObject resolved = json.copy();
|
||||||
|
applyEnvOverrides(resolved);
|
||||||
|
return resolved.mapTo(AppConfig.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void applyEnvOverrides(JsonObject config) {
|
||||||
|
Map<String, String> env = System.getenv();
|
||||||
|
|
||||||
|
env.forEach((key, value) -> {
|
||||||
|
String path = envKeyToPath(key);
|
||||||
|
|
||||||
|
if (path != null && exists(config, path)) {
|
||||||
|
setValue(config, path, value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SERVER__MAX_POOL_SIZE -> server.maxPoolSize
|
||||||
|
*/
|
||||||
|
private static String envKeyToPath(String envKey) {
|
||||||
|
if (!envKey.contains("__")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] levels = envKey.toLowerCase().split("__");
|
||||||
|
|
||||||
|
for (int i = 0; i < levels.length; i++) {
|
||||||
|
levels[i] = toCamelCase(levels[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return String.join(".", levels);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String toCamelCase(String value) {
|
||||||
|
String[] parts = value.split("_");
|
||||||
|
StringBuilder sb = new StringBuilder(parts[0]);
|
||||||
|
|
||||||
|
for (int i = 1; i < parts.length; i++) {
|
||||||
|
sb.append(Character.toUpperCase(parts[i].charAt(0)))
|
||||||
|
.append(parts[i].substring(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean exists(JsonObject json, String path) {
|
||||||
|
String[] parts = path.split("\\.");
|
||||||
|
JsonObject current = json;
|
||||||
|
|
||||||
|
for (int i = 0; i < parts.length - 1; i++) {
|
||||||
|
if (!current.containsKey(parts[i])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
current = current.getJsonObject(parts[i]);
|
||||||
|
}
|
||||||
|
return current.containsKey(parts[parts.length - 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setValue(JsonObject json, String path, String value) {
|
||||||
|
String[] parts = path.split("\\.");
|
||||||
|
JsonObject current = json;
|
||||||
|
|
||||||
|
for (int i = 0; i < parts.length - 1; i++) {
|
||||||
|
current = current.getJsonObject(parts[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
String key = parts[parts.length - 1];
|
||||||
|
Object oldValue = current.getValue(key);
|
||||||
|
current.put(key, cast(value, oldValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object cast(String value, Object oldValue) {
|
||||||
|
if (oldValue instanceof Integer) return Integer.parseInt(value);
|
||||||
|
if (oldValue instanceof Long) return Long.parseLong(value);
|
||||||
|
if (oldValue instanceof Boolean) return Boolean.parseBoolean(value);
|
||||||
|
if (oldValue == null) return value;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonObject json() {
|
||||||
|
return new JsonObject()
|
||||||
|
.put("server", server.json().getJsonObject("server"))
|
||||||
|
.put("database", database.json().getJsonObject("database"))
|
||||||
|
.put("redis", redis.json().getJsonObject("redis"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return json().encode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
26
src/main/java/su/xserver/iikocon/config/DatabaseConfig.java
Normal file
26
src/main/java/su/xserver/iikocon/config/DatabaseConfig.java
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package su.xserver.iikocon.config;
|
||||||
|
|
||||||
|
import io.vertx.core.json.JsonObject;
|
||||||
|
|
||||||
|
public class DatabaseConfig {
|
||||||
|
public String host;
|
||||||
|
public int port;
|
||||||
|
public String database;
|
||||||
|
public String user;
|
||||||
|
public String password;
|
||||||
|
public int connectionTimeout;
|
||||||
|
public int maxPoolSize;
|
||||||
|
|
||||||
|
public JsonObject json() {
|
||||||
|
return new JsonObject()
|
||||||
|
.put("database", new JsonObject()
|
||||||
|
.put("host", host)
|
||||||
|
.put("port", port)
|
||||||
|
.put("user", user)
|
||||||
|
.put("password", password)
|
||||||
|
.put("database", database)
|
||||||
|
.put("connectionTimeout", connectionTimeout)
|
||||||
|
.put("maxPoolSize", maxPoolSize)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
22
src/main/java/su/xserver/iikocon/config/RedisConfig.java
Normal file
22
src/main/java/su/xserver/iikocon/config/RedisConfig.java
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package su.xserver.iikocon.config;
|
||||||
|
|
||||||
|
import io.vertx.core.json.JsonObject;
|
||||||
|
|
||||||
|
public class RedisConfig {
|
||||||
|
public String host;
|
||||||
|
public int port;
|
||||||
|
public String password;
|
||||||
|
public int maxPoolSize;
|
||||||
|
public int maxWaitingHandlers;
|
||||||
|
|
||||||
|
public JsonObject json() {
|
||||||
|
return new JsonObject()
|
||||||
|
.put("redis", new JsonObject()
|
||||||
|
.put("host", host)
|
||||||
|
.put("port", port)
|
||||||
|
.put("password", password)
|
||||||
|
.put("maxPoolSize", maxPoolSize)
|
||||||
|
.put("maxWaitingHandlers", maxWaitingHandlers)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/main/java/su/xserver/iikocon/config/ServerConfig.java
Normal file
16
src/main/java/su/xserver/iikocon/config/ServerConfig.java
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package su.xserver.iikocon.config;
|
||||||
|
|
||||||
|
import io.vertx.core.json.JsonObject;
|
||||||
|
|
||||||
|
public class ServerConfig {
|
||||||
|
public int port;
|
||||||
|
public String host;
|
||||||
|
|
||||||
|
public JsonObject json() {
|
||||||
|
return new JsonObject()
|
||||||
|
.put("server", new JsonObject()
|
||||||
|
.put("port", port)
|
||||||
|
.put("host", host)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package su.xserver.iikocon.service;
|
||||||
|
|
||||||
|
import io.vertx.core.Vertx;
|
||||||
|
import io.vertx.mysqlclient.MySQLConnectOptions;
|
||||||
|
import io.vertx.sqlclient.Pool;
|
||||||
|
import io.vertx.sqlclient.PoolOptions;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import su.xserver.iikocon.config.DatabaseConfig;
|
||||||
|
|
||||||
|
public class DataBaseService {
|
||||||
|
private final Logger log = LoggerFactory.getLogger("[DataBaseService]");
|
||||||
|
private final DatabaseConfig config;
|
||||||
|
private final Pool pool;
|
||||||
|
|
||||||
|
public DataBaseService(Vertx vertx, DatabaseConfig config) {
|
||||||
|
log.info("Initialization");
|
||||||
|
this.config = config;
|
||||||
|
this.pool = Pool.pool(vertx, this.getMySQLConnectOptions(), this.getPoolOptions());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pool getPool() {
|
||||||
|
return this.pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disconnect() {
|
||||||
|
this.pool.close();
|
||||||
|
log.info("Connection is closed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
private MySQLConnectOptions getMySQLConnectOptions() {
|
||||||
|
return new MySQLConnectOptions()
|
||||||
|
.setHost(this.config.host)
|
||||||
|
.setPort(this.config.port)
|
||||||
|
.setDatabase(this.config.database)
|
||||||
|
.setUser(this.config.user)
|
||||||
|
.setPassword(this.config.password);
|
||||||
|
}
|
||||||
|
|
||||||
|
private PoolOptions getPoolOptions() {
|
||||||
|
return new PoolOptions()
|
||||||
|
.setMaxSize(this.config.maxPoolSize)
|
||||||
|
.setConnectionTimeout(this.config.connectionTimeout)
|
||||||
|
.setName(this.config.database);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package su.xserver.iikocon.service;
|
||||||
|
|
||||||
|
import io.vertx.core.Vertx;
|
||||||
|
import io.vertx.ext.healthchecks.Status;
|
||||||
|
import io.vertx.ext.web.Router;
|
||||||
|
import io.vertx.ext.web.healthchecks.HealthCheckHandler;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
public class HealthCheckService {
|
||||||
|
|
||||||
|
private final RedisService redisService;
|
||||||
|
private final DataBaseService dbService;
|
||||||
|
private final Vertx vertx;
|
||||||
|
|
||||||
|
public HealthCheckService(Vertx vertx, RedisService redisService, DataBaseService dbService) {
|
||||||
|
this.vertx = vertx;
|
||||||
|
this.redisService = redisService;
|
||||||
|
this.dbService = dbService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerHealthCheck(Router router) {
|
||||||
|
HealthCheckHandler healthCheckHandler = HealthCheckHandler.create(vertx);
|
||||||
|
|
||||||
|
// Redis check
|
||||||
|
healthCheckHandler.register("redis", future -> redisService.getRedisApi().ping(Collections.emptyList())
|
||||||
|
.onSuccess(response -> {
|
||||||
|
if ("PONG".equalsIgnoreCase(response.toString())) {
|
||||||
|
future.complete(Status.OK());
|
||||||
|
} else {
|
||||||
|
future.tryFail("Unexpected Redis response: " + response);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.onFailure(err -> future.tryFail("Redis ping failed: " + err.getMessage())));
|
||||||
|
|
||||||
|
// Database check
|
||||||
|
healthCheckHandler.register("database", future -> dbService.getPool().query("SELECT 1").execute()
|
||||||
|
.onSuccess(rs -> future.complete(Status.OK()))
|
||||||
|
.onFailure(t -> future.fail("Database is not reachable: " + t.getMessage())));
|
||||||
|
|
||||||
|
// Регистрируем endpoint /health
|
||||||
|
router.get("/health").handler(healthCheckHandler);
|
||||||
|
}
|
||||||
|
}
|
||||||
48
src/main/java/su/xserver/iikocon/service/RedisService.java
Normal file
48
src/main/java/su/xserver/iikocon/service/RedisService.java
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
package su.xserver.iikocon.service;
|
||||||
|
|
||||||
|
import io.vertx.core.Vertx;
|
||||||
|
import io.vertx.redis.client.Redis;
|
||||||
|
import io.vertx.redis.client.RedisAPI;
|
||||||
|
import io.vertx.redis.client.RedisOptions;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import su.xserver.iikocon.config.RedisConfig;
|
||||||
|
|
||||||
|
public class RedisService {
|
||||||
|
private final Logger log = LoggerFactory.getLogger("[RedisService]");
|
||||||
|
private final RedisConfig config;
|
||||||
|
private final Redis redis;
|
||||||
|
|
||||||
|
public RedisService(Vertx vertx, RedisConfig config) {
|
||||||
|
log.info("Initialization");
|
||||||
|
this.config = config;
|
||||||
|
this.redis = Redis.createClient(vertx, this.getRedisOptions());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Redis getRedis() {
|
||||||
|
return this.redis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RedisAPI getRedisApi() {
|
||||||
|
return RedisAPI.api(this.redis);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disconnect() {
|
||||||
|
this.redis.close();
|
||||||
|
log.info("Connection is closed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
private RedisOptions getRedisOptions() {
|
||||||
|
RedisOptions options = new RedisOptions()
|
||||||
|
.addConnectionString(String.format("redis://%s:%s",
|
||||||
|
this.config.host,
|
||||||
|
this.config.port))
|
||||||
|
.setMaxPoolSize(this.config.maxPoolSize)
|
||||||
|
.setMaxWaitingHandlers(this.config.maxWaitingHandlers);
|
||||||
|
|
||||||
|
if (this.config.password != null) {
|
||||||
|
options.setPassword(this.config.password);
|
||||||
|
}
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
}
|
||||||
22
src/main/resources/config.json
Normal file
22
src/main/resources/config.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"server": {
|
||||||
|
"port": 8080,
|
||||||
|
"host": "0.0.0.0"
|
||||||
|
},
|
||||||
|
"database": {
|
||||||
|
"host": "localhost",
|
||||||
|
"port": 3306,
|
||||||
|
"user": "user",
|
||||||
|
"password": "password",
|
||||||
|
"database": "database",
|
||||||
|
"connectionTimeout": 5000,
|
||||||
|
"maxPoolSize": 8
|
||||||
|
},
|
||||||
|
"redis": {
|
||||||
|
"host": "localhost",
|
||||||
|
"port": 6379,
|
||||||
|
"password": null,
|
||||||
|
"maxPoolSize": 6,
|
||||||
|
"maxWaitingHandlers": 6
|
||||||
|
}
|
||||||
|
}
|
||||||
48
src/main/resources/log4j2.xml
Normal file
48
src/main/resources/log4j2.xml
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Configuration status="WARN" monitorInterval="60">
|
||||||
|
<!-- Папка и имя приложения -->
|
||||||
|
<Properties>
|
||||||
|
<Property name="LOG_DIR">logs</Property>
|
||||||
|
<Property name="APP_NAME">iiko-app</Property>
|
||||||
|
</Properties>
|
||||||
|
|
||||||
|
<!-- Консоль -->
|
||||||
|
<Appenders>
|
||||||
|
<Console name="Console" target="SYSTEM_OUT">
|
||||||
|
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" charset="UTF-8"/>
|
||||||
|
</Console>
|
||||||
|
|
||||||
|
<!-- Основной rolling файл -->
|
||||||
|
<RollingFile name="File"
|
||||||
|
fileName="${LOG_DIR}/${APP_NAME}.log"
|
||||||
|
filePattern="${LOG_DIR}/${APP_NAME}.%d{yyyy-MM-dd}.log.gz">
|
||||||
|
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" charset="UTF-8"/>
|
||||||
|
<Policies>
|
||||||
|
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
|
||||||
|
</Policies>
|
||||||
|
<DefaultRolloverStrategy max="30" totalSizeCap="1GB"/>
|
||||||
|
</RollingFile>
|
||||||
|
|
||||||
|
<!-- Файл только для ошибок -->
|
||||||
|
<RollingFile name="ErrorFile"
|
||||||
|
fileName="${LOG_DIR}/${APP_NAME}-error.log"
|
||||||
|
filePattern="${LOG_DIR}/${APP_NAME}-error.%d{yyyy-MM-dd}.log.gz">
|
||||||
|
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" charset="UTF-8"/>
|
||||||
|
<Policies>
|
||||||
|
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
|
||||||
|
</Policies>
|
||||||
|
<Filters>
|
||||||
|
<ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
|
||||||
|
</Filters>
|
||||||
|
<DefaultRolloverStrategy max="30" totalSizeCap="500MB"/>
|
||||||
|
</RollingFile>
|
||||||
|
</Appenders>
|
||||||
|
|
||||||
|
<Loggers>
|
||||||
|
<Root level="info">
|
||||||
|
<AppenderRef ref="Console"/>
|
||||||
|
<AppenderRef ref="File"/>
|
||||||
|
<AppenderRef ref="ErrorFile"/>
|
||||||
|
</Root>
|
||||||
|
</Loggers>
|
||||||
|
</Configuration>
|
||||||
Reference in New Issue
Block a user