Первый
This commit is contained in:
488
src/main/java/org/ccalm/sync/MainController.java
Normal file
488
src/main/java/org/ccalm/sync/MainController.java
Normal file
@ -0,0 +1,488 @@
|
||||
package org.ccalm.sync;
|
||||
|
||||
import jakarta.servlet.ServletContext;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.context.ServletContextAware;
|
||||
import org.json.JSONObject;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import tctable.TCField;
|
||||
import tctable.TCTable;
|
||||
import tctable.TCTableTools;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.sql.*;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
@Controller
|
||||
public class MainController implements ServletContextAware {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(MainController.class);
|
||||
|
||||
@Value("${spring.application.name}")
|
||||
String application_name = "";
|
||||
@Value("${spring.datasource.url}")
|
||||
String db_url="";
|
||||
@Value("${spring.datasource.username}")
|
||||
String db_login="";
|
||||
@Value("${spring.datasource.password}")
|
||||
String db_password="";
|
||||
|
||||
private ServletContext context;
|
||||
|
||||
@Override
|
||||
public void setServletContext(ServletContext servletContext) {
|
||||
this.context = servletContext;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/",method = {RequestMethod.POST,RequestMethod.GET},produces = "application/json;charset=utf-8")
|
||||
@ResponseBody
|
||||
public String index(Model model, @RequestParam(required=false,name="lng",defaultValue = "1") String language_id) {
|
||||
JSONObject json = new JSONObject();
|
||||
try {
|
||||
json.put("error_code",0);
|
||||
json.put("error_message","");
|
||||
json.put("error_marker",(String)null);
|
||||
String buildDate="";
|
||||
//String buildVersion="";
|
||||
try {
|
||||
InputStream inputStream = MainController.class.getClassLoader().getResourceAsStream("META-INF/build-info.properties");
|
||||
if (inputStream != null) {
|
||||
Properties properties = new Properties();
|
||||
properties.load(inputStream);
|
||||
buildDate = properties.getProperty("build.time");
|
||||
//buildVersion = properties.getProperty("build.version");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
json.put("build_date",buildDate);
|
||||
//json.put("build_version",buildVersion);
|
||||
json.put("name",application_name);
|
||||
//json.put("active_connections",dataSource.getHikariPoolMXBean().getActiveConnections());
|
||||
//json.put("idle_connections",dataSource.getHikariPoolMXBean().getIdleConnections());
|
||||
} catch (JSONException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return json.toString();
|
||||
}
|
||||
|
||||
//Скачать с удалённого сервера
|
||||
@RequestMapping(value = "/download/",params = {"fn"},method = { RequestMethod.GET, RequestMethod.POST })
|
||||
@ResponseBody
|
||||
public Object download(HttpServletResponse response, @RequestHeader(required=false,name="Content-Type") String contentType, @RequestBody(required=false) String reqData, @RequestParam(required=false,name="file") MultipartFile file, @RequestParam(required=false,name="fn") String fn, @RequestParam(required=false,name="r") String reqR, @RequestParam(required=false,name="n") String reqN, @RequestParam(required=false,name="s") String reqS, @RequestParam(required=false,name="l") String reqL, @RequestParam(required=false,name="days",defaultValue = "0") int days, @RequestParam(required=false,name="country_id",defaultValue = "0") int country_id, @RequestParam(required=false,name="android_id",defaultValue = "") String device_id) {
|
||||
System.out.println("/asdc/tctable/");
|
||||
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("error_code", 0);
|
||||
result.put("error_message", "");
|
||||
|
||||
byte[] reqData=null;
|
||||
if(file!=null) {
|
||||
try {
|
||||
reqData = file.getBytes();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
if(reqData==null)
|
||||
return "OK";
|
||||
|
||||
Connection conn = null;
|
||||
try {
|
||||
Class.forName("org.postgresql.Driver");
|
||||
conn = DriverManager.getConnection(db_url, db_login, db_password);
|
||||
try {
|
||||
Statement sttTZ = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
|
||||
sttTZ.executeUpdate("SET TIME ZONE 'UTC';");
|
||||
sttTZ.close();
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
InputStream isRaw = null;
|
||||
isRaw = new ByteArrayInputStream(reqData);
|
||||
|
||||
TCTable tbl = new TCTable("", 0);
|
||||
try {
|
||||
if (tbl.OpenTableH(isRaw)) {
|
||||
|
||||
if(tbl.name.equals("frmlocustdel_locations")) {
|
||||
while (tbl.ReadNextRecord()) {
|
||||
String uid=tbl.fields.get(0).getStrVal();
|
||||
if(uid==null || uid.isEmpty()) continue; //Для не пропуска переходных записей...
|
||||
|
||||
boolean exists = false; //Is there a record.
|
||||
Statement st;
|
||||
try {
|
||||
ResultSet rs = null;
|
||||
st = conn.createStatement();
|
||||
try {
|
||||
String sql = "select 1 from main.frmlocustdel_locations where uid=main.strtouuid('"+uid+"')";
|
||||
rs = st.executeQuery(sql);
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
logger.error("Error:",ex);
|
||||
result.put("error_code",1);
|
||||
result.put("error_message", ex.getMessage());
|
||||
return result.toString();
|
||||
}
|
||||
if (rs != null) {
|
||||
if (rs.next())
|
||||
exists = true;
|
||||
}
|
||||
st.close();
|
||||
|
||||
PreparedStatement stmt = null;
|
||||
String sql = "";
|
||||
if (exists) {
|
||||
sql = """
|
||||
update main.frmlocustdel_locations set
|
||||
del=?,
|
||||
seq=?,
|
||||
frmlocustdel_uid=main.strtouuid(?),
|
||||
pos=?,
|
||||
lon=?,
|
||||
lat=?
|
||||
where
|
||||
uid=main.strtouuid(?)
|
||||
""";
|
||||
try {
|
||||
stmt = conn.prepareStatement(sql);
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
logger.error("Error:",ex);
|
||||
result.put("error_code",1);
|
||||
result.put("error_message", ex.getMessage());
|
||||
return result.toString();
|
||||
}
|
||||
} else {
|
||||
sql = """
|
||||
insert into main.frmlocustdel_locations(
|
||||
del,
|
||||
seq,
|
||||
frmlocustdel_uid,
|
||||
pos,
|
||||
lon,
|
||||
lat,
|
||||
uid
|
||||
)values(
|
||||
?,
|
||||
?,
|
||||
main.strtouuid(?),
|
||||
?,
|
||||
?,
|
||||
?,
|
||||
main.strtouuid(?)
|
||||
)
|
||||
""";
|
||||
try {
|
||||
stmt = conn.prepareStatement(sql);
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
logger.error("Error:",ex);
|
||||
result.put("error_code",1);
|
||||
result.put("error_message", ex.getMessage());
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
try {
|
||||
stmt.setBoolean(1, tbl.fields.get(1).getBoolVal());
|
||||
stmt.setLong(2, tbl.fields.get(2).getUIntVal());
|
||||
stmt.setString(3, tbl.fields.get(3).getStrVal());
|
||||
stmt.setInt(4, tbl.fields.get(4).getIntVal());
|
||||
stmt.setDouble(5, tbl.fields.get(5).getDoubleVal());
|
||||
stmt.setDouble(6, tbl.fields.get(6).getDoubleVal());
|
||||
stmt.setString(7, tbl.fields.get(0).getStrVal());
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
logger.error("Error:",ex);
|
||||
result.put("error_code",1);
|
||||
result.put("error_message", ex.getMessage());
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
//Выпоняю запрос на свтавку либо обновление
|
||||
try {
|
||||
stmt.execute();
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
logger.error("Error:",ex);
|
||||
result.put("error_code",1);
|
||||
result.put("error_message", ex.getMessage());
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
logger.error("Error:",ex);
|
||||
result.put("error_code",1);
|
||||
result.put("error_message", ex.getMessage());
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
}
|
||||
}else{
|
||||
//Если это универсальная функция по обновлению данных (похожая функция есть в андроид приложении)
|
||||
|
||||
//Проверка на существование полей в обеих таблицах
|
||||
ExistsType[] fb=new ExistsType[tbl.fields.size()];
|
||||
Map<String, String> col = TCTableTools.getTableSchema(conn, "main", tbl.name);
|
||||
for(int i=0;i<tbl.fields.size();i++)
|
||||
{
|
||||
Iterator<Map.Entry<String, String>> iterator = col.entrySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<String, String> entry = iterator.next();
|
||||
if (entry.getKey().equalsIgnoreCase(col.get(i))) {
|
||||
fb[i].exists=true;
|
||||
fb[i].type=entry.getValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//Переписываем значения существующих полей и выполняем запросы
|
||||
while(tbl.ReadNextRecord())
|
||||
{
|
||||
String sql=null;
|
||||
String[] par=null;
|
||||
if(tbl.getRowByName("id")!=null && tbl.getRowByName("id").getStrVal()!=null){
|
||||
sql="select 1 from main."+tbl.name+" where id = ?";
|
||||
par = new String[] { tbl.getRowByName("id").getStrVal() };
|
||||
}else if(tbl.getRowByName("uid")!=null && tbl.getRowByName("id").getStrVal()!=null){
|
||||
sql="select 1 from main."+tbl.name+" where uid = main.strtouuid(?)";
|
||||
par = new String[] { tbl.getRowByName("uid").getStrVal() };
|
||||
}
|
||||
if(sql==null)
|
||||
continue;
|
||||
|
||||
boolean exists=false;
|
||||
ResultSet rs = null;
|
||||
Statement st = conn.createStatement();
|
||||
try {
|
||||
rs = st.executeQuery(sql);
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
logger.error("Error:",ex);
|
||||
result.put("error_code",1);
|
||||
result.put("error_message", ex.getMessage());
|
||||
return result.toString();
|
||||
}
|
||||
if (rs != null) {
|
||||
if (rs.next())
|
||||
exists = true;
|
||||
}
|
||||
st.close();
|
||||
|
||||
PreparedStatement stmt = null;
|
||||
sql = "";
|
||||
if (exists) {
|
||||
sql="update main."+tbl.name+" set ";
|
||||
for(int i=0;i<tbl.fields.size();i++)
|
||||
{
|
||||
if(fb[i].exists){
|
||||
if(!tbl.fields.get(i).name.equals("uid"))
|
||||
sql+=tbl.fields.get(i).name+"=?,";
|
||||
}
|
||||
}
|
||||
sql=sql.substring(0, sql.length() - 1);
|
||||
sql+="where uid=main.strtouuid(?)";
|
||||
} else {
|
||||
sql="insert into main."+tbl.name+"(";
|
||||
String subSql1=" ";
|
||||
String subSql2=" ";
|
||||
for(int i=0;i<tbl.fields.size();i++)
|
||||
{
|
||||
if(fb[i].exists){
|
||||
if(!tbl.fields.get(i).name.equals("uid")) {
|
||||
subSql1 += tbl.fields.get(i).name + ",";
|
||||
subSql2 += "?,";
|
||||
}
|
||||
}
|
||||
}
|
||||
subSql1 += "uid,";
|
||||
subSql2 += "?,";
|
||||
subSql1=subSql1.substring(0, subSql1.length() - 1);
|
||||
subSql2=subSql1.substring(0, subSql2.length() - 1);
|
||||
sql+=subSql1+")values("+subSql2+");";
|
||||
}
|
||||
try {
|
||||
stmt = conn.prepareStatement(sql);
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
logger.error("Error:",ex);
|
||||
result.put("error_code",1);
|
||||
result.put("error_message", ex.getMessage());
|
||||
return result.toString();
|
||||
}
|
||||
try {
|
||||
for(int i=0;i<tbl.fields.size();i++)
|
||||
{
|
||||
if(fb[i].exists){
|
||||
if(!tbl.fields.get(i).name.equals("uid")) {
|
||||
if(tbl.fields.get(i).isNull()){
|
||||
stmt.setNull(i, Types.NULL);
|
||||
}else{
|
||||
switch (tbl.fields.get(i).type){
|
||||
case TCField.BD_UINT1, TCField.BD_UINT2, TCField.BD_UINT4:
|
||||
stmt.setLong(i, tbl.fields.get(i).getLongVal());
|
||||
break;
|
||||
case TCField.BD_UINT8:
|
||||
stmt.setLong(i, tbl.fields.get(i).getLongVal());
|
||||
break;
|
||||
case TCField.BD_SUINT8:
|
||||
stmt.setLong(i, tbl.fields.get(i).getLongVal());
|
||||
break;
|
||||
case TCField.BD_INT1, TCField.BD_INT2, TCField.BD_INT4:
|
||||
stmt.setInt(i, tbl.fields.get(i).getIntVal());
|
||||
break;
|
||||
case TCField.BD_INT8:
|
||||
stmt.setLong(i, tbl.fields.get(i).getLongVal());
|
||||
break;
|
||||
case TCField.BD_SINT8:
|
||||
stmt.setLong(i, tbl.fields.get(i).getLongVal());
|
||||
break;
|
||||
case TCField.BD_FLOAT4:
|
||||
stmt.setFloat(i, tbl.fields.get(i).getFloatVal());
|
||||
break;
|
||||
case TCField.BD_FLOAT8:
|
||||
stmt.setDouble(i, tbl.fields.get(i).getDoubleVal());
|
||||
break;
|
||||
case TCField.BD_SFLOAT8:
|
||||
stmt.setBigDecimal(i, tbl.fields.get(i).getBigDecimalVal());
|
||||
break;
|
||||
case TCField.BD_UTF8_1,TCField.BD_UTF8_2,TCField.BD_UTF8_4:
|
||||
stmt.setString(i, tbl.fields.get(i).getStrVal());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*stmt.setBoolean(1, tbl.fields.get(1).getBoolVal());
|
||||
stmt.setLong(2, tbl.fields.get(2).getUIntVal());
|
||||
stmt.setString(3, tbl.fields.get(3).getStrVal());
|
||||
stmt.setInt(4, tbl.fields.get(4).getIntVal());
|
||||
stmt.setDouble(5, tbl.fields.get(5).getDoubleVal());
|
||||
stmt.setDouble(6, tbl.fields.get(6).getDoubleVal());
|
||||
stmt.setString(7, tbl.fields.get(0).getStrVal());*/
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
logger.error("Error:",ex);
|
||||
result.put("error_code",1);
|
||||
result.put("error_message", ex.getMessage());
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
logger.error("Error:",ex);
|
||||
result.put("error_code",1);
|
||||
result.put("error_message", ex.getMessage());
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
logger.error("Error:",ex);
|
||||
result.put("error_code",1);
|
||||
result.put("error_message", ex.getMessage());
|
||||
return result.toString();
|
||||
}finally {
|
||||
if(conn!=null) { try { conn.close(); } catch (SQLException e) { } }
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
//отдать с текущего сервера
|
||||
@RequestMapping(value = "/upload/",params = {"fn"},method = { RequestMethod.GET, RequestMethod.POST })
|
||||
@ResponseBody
|
||||
public Object upload(HttpServletResponse response, @RequestHeader(required=false,name="Content-Type") String contentType, @RequestBody(required=false) String reqData, @RequestParam(required=false,name="file") MultipartFile file, @RequestParam(required=false,name="fn") String fn, @RequestParam(required=false,name="r") String reqR, @RequestParam(required=false,name="n") String reqN, @RequestParam(required=false,name="s") String reqS, @RequestParam(required=false,name="l") String reqL, @RequestParam(required=false,name="days",defaultValue = "0") int days, @RequestParam(required=false,name="country_id",defaultValue = "0") int country_id, @RequestParam(required=false,name="android_id",defaultValue = "") String device_id) {
|
||||
|
||||
String result;
|
||||
String sql="select * from main.commands where seq>0";
|
||||
|
||||
//Connect to database
|
||||
Connection conn = null;
|
||||
try {
|
||||
Class.forName("org.postgresql.Driver");
|
||||
conn = DriverManager.getConnection(db_url, db_login, db_password);
|
||||
if (conn != null) {
|
||||
logger.info("Connect is OK!");
|
||||
} else {
|
||||
logger.info("An error occurred while connecting to the database!");
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
Statement st = conn.createStatement();
|
||||
ResultSet rs=null;
|
||||
try {
|
||||
rs = st.executeQuery(sql);
|
||||
} catch( SQLException ex ) {
|
||||
logger.error("Error",ex);
|
||||
}
|
||||
|
||||
if(rs!=null)
|
||||
{
|
||||
TCTable tbl=new TCTable(pN,123456);
|
||||
logger.info("*** "+pN+" ***");
|
||||
|
||||
ResultSetMetaData rsmd = rs.getMetaData();
|
||||
for(int i=1;i<=rsmd.getColumnCount();i++)
|
||||
{
|
||||
logger.info(i+") name="+rsmd.getColumnName(i)+" type="+rsmd.getColumnTypeName(i));
|
||||
|
||||
TCField field=new TCField(rsmd.getColumnName(i), rsmd.getColumnTypeName(i));
|
||||
tbl.addField(field);
|
||||
}
|
||||
|
||||
tbl.getHeader(response.getOutputStream());
|
||||
while (rs.next())
|
||||
{
|
||||
for(int i=1;i<=rsmd.getColumnCount();i++)
|
||||
{
|
||||
if(!rsmd.getColumnTypeName(i).equals("geometry")) {
|
||||
tbl.fields.get(i - 1).setValue(rs.getString(i));
|
||||
//logger.info(String.valueOf(i)+") "+rs.getString(i));
|
||||
}else {
|
||||
tbl.fields.get(i - 1).setValue(null);
|
||||
}
|
||||
}
|
||||
//Save binary data to stream
|
||||
tbl.getCol(response.getOutputStream());
|
||||
}
|
||||
}
|
||||
st.close();
|
||||
|
||||
//response.getOutputStream();
|
||||
response.flushBuffer();
|
||||
|
||||
} catch (IOException e) {
|
||||
logger.error("Error",e);
|
||||
}
|
||||
|
||||
} catch (Exception ex) {
|
||||
logger.error("Error",ex);
|
||||
}finally {
|
||||
if(conn!=null) {try { conn.close(); } catch (SQLException e) {} }
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
13
src/main/java/org/ccalm/sync/SyncApplication.java
Normal file
13
src/main/java/org/ccalm/sync/SyncApplication.java
Normal file
@ -0,0 +1,13 @@
|
||||
package org.ccalm.sync;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SyncApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SyncApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
BIN
src/main/resources/keystore.jks
Normal file
BIN
src/main/resources/keystore.jks
Normal file
Binary file not shown.
34
src/main/resources/logback-spring.xml
Normal file
34
src/main/resources/logback-spring.xml
Normal file
@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
|
||||
<!-- Please check if the user has access to the directory from which the application is being executed -->
|
||||
<property name="LOGS" value="logs" />
|
||||
<springProperty scope="context" name="appName" source="spring.application.name"/>
|
||||
|
||||
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${LOGS}/${appName}.log</file>
|
||||
<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>
|
||||
</encoder>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOGS}/${appName}.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
|
||||
<maxHistory>30</maxHistory>
|
||||
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||
<maxFileSize>100MB</maxFileSize>
|
||||
</timeBasedFileNamingAndTriggeringPolicy>
|
||||
</rollingPolicy>
|
||||
</appender>
|
||||
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSS'Z'} | %level | %logger{36} | %X{marker} | %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!--root level="info"-->
|
||||
<root level="warn">
|
||||
<appender-ref ref="FILE" />
|
||||
<appender-ref ref="CONSOLE" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
13
src/test/java/org/ccalm/sync/SyncApplicationTests.java
Normal file
13
src/test/java/org/ccalm/sync/SyncApplicationTests.java
Normal file
@ -0,0 +1,13 @@
|
||||
package org.ccalm.sync;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class SyncApplicationTests {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user