Add springdoc

This commit is contained in:
2025-06-30 07:22:30 +05:00
parent c6eab9ee7d
commit 0a4c1948b0
10 changed files with 310 additions and 29 deletions

View File

@ -11,7 +11,7 @@ issuer:
spring: spring:
application: application:
name: org_ccalm_dbms name: org-ccalm-dbms
datasource: datasource:
url: jdbc:postgresql://91.201.214.156:5432/CCALM?ApplicationName=org_ccalm_dbms&ssl=true&sslmode=require&connectTimeout=10000&socketTimeout=10000 url: jdbc:postgresql://91.201.214.156:5432/CCALM?ApplicationName=org_ccalm_dbms&ssl=true&sslmode=require&connectTimeout=10000&socketTimeout=10000
username: postgres username: postgres
@ -41,7 +41,6 @@ access:
refresh: refresh:
time: 43200 time: 43200
mail: mail:
host: smtp.yandex.ru host: smtp.yandex.ru
port: 465 port: 465

24
pom.xml
View File

@ -10,7 +10,7 @@
</parent> </parent>
<groupId>org.ccalm</groupId> <groupId>org.ccalm</groupId>
<artifactId>dbms</artifactId> <artifactId>dbms</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>1.0.1</version>
<name>dbms</name> <name>dbms</name>
<description>Database management system</description> <description>Database management system</description>
<url/> <url/>
@ -100,9 +100,29 @@
<artifactId>commons-io</artifactId> <artifactId>commons-io</artifactId>
<version>2.16.1</version> <version>2.16.1</version>
</dependency> </dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.8.4</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.36</version>
<scope>provided</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>
<finalName>org-ccalm-dbms</finalName>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
@ -121,7 +141,7 @@
<version>2.22.2</version> <version>2.22.2</version>
<configuration> <configuration>
<systemPropertyVariables> <systemPropertyVariables>
<spring.config.location>file:kz_mcp_dbms.properties</spring.config.location> <spring.config.location>file:org_ccalm_dbms.yml</spring.config.location>
</systemPropertyVariables> </systemPropertyVariables>
</configuration> </configuration>
</plugin> </plugin>

View File

@ -0,0 +1,18 @@
package logging;
import dbms.DBMSRecords;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class JavaLogger implements logging.Logger {
private final Logger logger;
public JavaLogger(Class<?> clazz) {
this.logger = LogManager.getLogger(clazz);
}
public void debug(String msg) { this.logger.debug(msg); }
public void info(String msg) { this.logger.info(msg); }
public void warn(String msg) { this.logger.warn(msg); }
public void error(String msg) { this.logger.error(msg); }
}

View File

@ -0,0 +1,12 @@
package logging;
public interface Logger {
void debug(String msg);
void info(String msg);
void warn(String msg);
void error(String msg);
static Logger getLogger(Class<?> clazz) {
return LoggerFactory.createLogger(clazz); // Подменяется реализацией
}
}

View File

@ -0,0 +1,14 @@
package logging;
import org.apache.logging.slf4j.SLF4JLogger;
public class LoggerFactory {
public static Logger createLogger(Class<?> clazz) {
// Тут выбираешь реализацию по флагу/условию
//if (isAndroid()) {
// return new AndroidLogger(clazz);
//} else {
return new JavaLogger(clazz);
//}
}
}

View File

@ -0,0 +1,113 @@
package models;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
@Schema(
description = "Error API response",
example = "{ \"error_code\": 10000, \"error_message\": [\"Internal_Server_Error\",\"Please_log_in\"], \"error_setting\": [\"99;day\",\"1;2\"], \"error_marker\": \"2a449883-c7c6-468e-b3ae-5f73fc96627d\" }"
)
public class ErrorResponseModel {
@JsonIgnore
private int httpCode;
@Schema(description = "Error code", example = "10000")
@JsonProperty("error_code")
private int errorCode;
@Schema(description = "List of error descriptions", example = "[\"Internal_Server_Error\",\"Please_log_in\"]")
@JsonProperty("error_message")
private List<String> errorMessage;
@Schema(description = "Options for translated text", example = "[\"99;day\",\"1;2\"]")
@JsonProperty("error_setting")
private List<String> errorSetting;
@Schema(description = "Unique identifier for searching in the database", example = "4260aad8-f7ee-4be4-b52c-15d56ec83232")
@JsonProperty("error_marker")
private String errorMarker;
public ErrorResponseModel(int httpCode, int errorCode) {
this.httpCode = httpCode;
this.errorCode = errorCode;
this.errorMessage = null;
this.errorSetting = null;
this.errorMarker = UUID.randomUUID().toString();
}
public ErrorResponseModel(int httpCode, int errorCode, List<String> errorMessage, String errorMarker) {
this.httpCode = httpCode;
this.errorCode = errorCode;
this.errorMessage = errorMessage;
this.errorMarker = errorMarker;
}
public ErrorResponseModel(int httpCode, int errorCode, String errorMessage, String errorMarker) {
this.httpCode = httpCode;
this.errorCode = errorCode;
this.errorMessage = Collections.singletonList(errorMessage);
this.errorMarker = errorMarker;
}
public ErrorResponseModel(int httpCode, int errorCode, String errorMessage, String errorSetting, String errorMarker) {
this.httpCode = httpCode;
this.errorCode = errorCode;
this.errorMessage = Collections.singletonList(errorMessage);
this.errorSetting = Collections.singletonList(errorSetting);
this.errorMarker = errorMarker;
}
public ErrorResponseModel(int httpCode, int errorCode, List<String> errorMessage, List<String> errorSetting, String errorMarker) {
this.httpCode = httpCode;
this.errorCode = errorCode;
this.errorMessage = errorMessage;
this.errorSetting = errorSetting;
this.errorMarker = errorMarker;
}
public int getHttp_code() {
return httpCode;
}
public void setHttp_code(int errorCode) {
this.httpCode = httpCode;
}
public int getError_code() {
return errorCode;
}
public void setError_code(int errorCode) {
this.errorCode = errorCode;
}
public List<String> getError_message() {
return errorMessage;
}
public void setError_message(List<String> errorMessage) {
this.errorMessage = errorMessage;
}
public void setError_setting(List<String> errorSetting) {
this.errorSetting = errorSetting;
}
public List<String> getError_setting() {
return errorSetting;
}
public void setError_marker(String errorMarker) {
this.errorMarker = errorMarker;
}
public String getError_marker() {
return errorMarker;
}
}

View File

@ -1,28 +1,37 @@
package org.ccalm.dbms; package org.ccalm.dbms;
import com.zaxxer.hikari.HikariDataSource; import com.zaxxer.hikari.HikariDataSource;
import models.ErrorResponseModel;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MarkerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import java.io.InputStream; import java.io.InputStream;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Controller @Controller
public class MainController { public class MainController {
private static final Logger logger = LoggerFactory.getLogger(MainController.class);
private final NamedParameterJdbcTemplate jdbcTemplate;
private final Environment environment;
private HikariDataSource dataSource; private HikariDataSource dataSource;
@Value("${spring.application.name}") @Value("${spring.application.name}")
@ -32,36 +41,46 @@ public class MainController {
public void DatabaseService(HikariDataSource dataSource) { public void DatabaseService(HikariDataSource dataSource) {
this.dataSource = dataSource; this.dataSource = dataSource;
} }
//---------------------------------------------------------------------------
@Autowired
public MainController(NamedParameterJdbcTemplate jdbcTemplate, HikariDataSource dataSource, Environment environment) {
this.jdbcTemplate = jdbcTemplate;
this.environment = environment;
this.dataSource = dataSource;
}
//---------------------------------------------------------------------------
@RequestMapping(value = "/",method = {RequestMethod.POST,RequestMethod.GET},produces = "application/json;charset=utf-8") @RequestMapping(value = "/",method = {RequestMethod.POST,RequestMethod.GET},produces = "application/json;charset=utf-8")
@ResponseBody @ResponseBody
public ResponseEntity<String> index() { public ResponseEntity<Object> index(
JSONObject json = new JSONObject(); @CookieValue(value = "lng", defaultValue = "1") String language_id
) {
Translation trt = new Translation(language_id,jdbcTemplate);
try { try {
JSONObject json = new JSONObject();
json.put("error_code",0); json.put("error_code",0);
json.put("error_message",""); json.put("error_message","");
json.put("error_marker",(String)null); json.put("error_marker",(String)null);
String buildDate=""; String buildDate="";
//String buildVersion=""; String buildVersion="";
try { try {
InputStream inputStream = MainController.class.getClassLoader().getResourceAsStream("META-INF/build-info.properties"); InputStream inputStream = MainController.class.getClassLoader().getResourceAsStream("META-INF/build-info.properties");
if (inputStream != null) { if (inputStream != null) {
Properties properties = new Properties(); Properties properties = new Properties();
properties.load(inputStream); properties.load(inputStream);
buildDate = properties.getProperty("build.time"); buildDate = properties.getProperty("build.time");
//buildVersion = properties.getProperty("build.version"); buildVersion = properties.getProperty("build.version");
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
json.put("build_date",buildDate); json.put("build_date",buildDate);
//json.put("build_version",buildVersion); json.put("version",buildVersion);
json.put("name",application_name); json.put("name",application_name);
//json.put("active_connections",dataSource.getHikariPoolMXBean().getActiveConnections()); //json.put("active_connections",dataSource.getHikariPoolMXBean().getActiveConnections());
//json.put("idle_connections",dataSource.getHikariPoolMXBean().getIdleConnections()); //json.put("idle_connections",dataSource.getHikariPoolMXBean().getIdleConnections());
// Вывод всех зарегистрированных маршрутов в системе // Вывод всех зарегистрированных маршрутов в системе
ApplicationContext context = SpringContext.getApplicationContext(); /*ApplicationContext context = SpringContext.getApplicationContext();
if (context != null) { if (context != null) {
RequestMappingHandlerMapping mapping = context.getBean(RequestMappingHandlerMapping.class); RequestMappingHandlerMapping mapping = context.getBean(RequestMappingHandlerMapping.class);
Set<String> endpoints = mapping.getHandlerMethods().keySet().stream() Set<String> endpoints = mapping.getHandlerMethods().keySet().stream()
@ -69,12 +88,14 @@ public class MainController {
.collect(Collectors.toSet()); .collect(Collectors.toSet());
System.out.println("=== Registered API endpoints ==="); System.out.println("=== Registered API endpoints ===");
endpoints.forEach(System.out::println); endpoints.forEach(System.out::println);
} }*/
} catch (JSONException e) { return new ResponseEntity<>(json.toString(), HttpStatus.OK);
throw new RuntimeException(e); } catch (Exception e) {
String uuid = UUID.randomUUID().toString();
logger.error(MarkerFactory.getMarker(uuid), e.getMessage());
return new ResponseEntity<>(new ErrorResponseModel(500, 10000, trt.trt(false, "Internal_Server_Error"), null, uuid), HttpStatus.INTERNAL_SERVER_ERROR);
} }
return ResponseEntity.ok(json.toString());
} }
} }

View File

@ -0,0 +1,14 @@
package org.ccalm.dbms;
import ch.qos.logback.classic.pattern.ThrowableProxyConverter;
import ch.qos.logback.classic.spi.IThrowableProxy;
import ch.qos.logback.classic.spi.ThrowableProxyUtil;
public class SingleLineThrowableProxyConverter extends ThrowableProxyConverter {
@Override
protected String throwableProxyToString(IThrowableProxy tp) {
if (tp == null) return "";
String stackTrace = ThrowableProxyUtil.asString(tp);
return stackTrace.replace("\r", "").replace("\n", "\\n").replace("\t", " ");
}
}

View File

@ -0,0 +1,68 @@
package org.ccalm.dbms;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import tools.DBTools;
import org.json.JSONObject;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import java.util.List;
public class Translation {
private static final Logger logger = LogManager.getLogger(Translation.class);
public int language_id;
public NamedParameterJdbcTemplate jdbcTemplate;
Translation(String lng, NamedParameterJdbcTemplate jdbcTemplate){
language_id=1;
switch (lng) {
case "kz":
case "kk":
language_id = 2;
break;
case "en":
language_id = 3;
break;
case "uz":
language_id = 4;
break;
case "ru":
default:
language_id = 1;
break;
}
this.jdbcTemplate = jdbcTemplate;
}
String trt(boolean translate,String text){
if(translate) {
String sql = """
select
translation
from
main._translations
where
del=false
and language_id=:language_id
and identifier=:identifier;
""";
MapSqlParameterSource parameters = new MapSqlParameterSource();
parameters.addValue("language_id", language_id);
parameters.addValue("identifier", text);
List<String> ret = jdbcTemplate.query(sql, parameters, new DBTools.JsonRowMapper());
int i = 0;
for (i = 0; i < ret.size(); i++) {
JSONObject json = new JSONObject(ret.get(i));
text = json.getString("translation");
}
if(i==0){
text = text.replace("_", " ");
}
return text;
}else {
return text;
}
}
}

View File

@ -1,32 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<!-- Please check if the user has access to the directory from which the application is being executed --> <conversionRule conversionWord="exOneLine" converterClass="org.ccalm.dbms.SingleLineThrowableProxyConverter"/>
<property name="LOGS" value="logs" /> <property name="LOGS" value="logs" />
<springProperty scope="context" name="appName" source="spring.application.name"/> <springProperty scope="context" name="appName" source="spring.application.name"/>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOGS}/${appName}.log</file> <file>${LOGS}/${appName}.log</file>
<encoder> <encoder>
<pattern>{"timestamp":"%d{yyyy-MM-dd'T'HH:mm:ss.SSS'Z'}","thread":"[%thread]","level":"%level","logger":"%logger{36}","marker":"%X{marker}","message":"%msg"}%n</pattern> <pattern>{"timestamp":"%d{yyyy-MM-dd'T'HH:mm:ss.SSS'Z'}","thread":"[%thread]","level":"%level","logger":"%logger{36}","marker":"%marker","message":"%msg","exception":"%exOneLine"}%n</pattern>
</encoder> </encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOGS}/${appName}.%d{yyyy-MM-dd}.%i.log</fileNamePattern> <fileNamePattern>${LOGS}/${appName}.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>100MB</maxFileSize>
<maxHistory>30</maxHistory> <maxHistory>30</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <totalSizeCap>3GB</totalSizeCap>
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy> </rollingPolicy>
</appender> </appender>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSS'Z'} | %level | %logger{36} | %X{marker} | %msg%n</pattern> <pattern>
%d{yyyy-MM-dd'T'HH:mm:ss.SSS'Z'} | %level | %logger{36} | %marker | %msg%n
</pattern>
</encoder> </encoder>
</appender> </appender>
<!--root level="info"--> <!--root level="warn"-->
<root level="warn"> <root level="info">
<appender-ref ref="FILE" /> <appender-ref ref="FILE" />
<appender-ref ref="CONSOLE" /> <appender-ref ref="CONSOLE" />
</root> </root>