From e043b80744c8cc60fc612bee0e550bdb2233d5ae Mon Sep 17 00:00:00 2001 From: Igor I Date: Tue, 4 Feb 2025 18:51:27 +0500 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=B5=D0=BB=D0=B0=D1=8E=20=D0=BF=D1=80?= =?UTF-8?q?=D0=B5=D0=B4=D1=83=D0=BF=D1=80=D0=B5=D0=B6=D0=B4=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=BF=D0=BE=20=D0=BD=D0=B0=D0=B6=D0=B0=D1=82?= =?UTF-8?q?=D0=B8=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- org_ccalm_weather.yml | 15 +- pom.xml | 191 +++++++++++------- .../org/ccalm/weather/AirTemperature.java | 157 ++++++++------ .../org/ccalm/weather/BookController.java | 30 +++ .../java/org/ccalm/weather/Precipitation.java | 151 +++++++++++--- .../org/ccalm/weather/SoilTmperature.java | 150 +++++++++++--- .../java/org/ccalm/weather/Translation.java | 54 +++++ .../weather/models/ErrorResponseModel.java | 96 +++++++++ .../org/ccalm/weather/models/PointModel.java | 43 ++++ src/main/java/tools/CustomException.java | 71 +++++++ .../{org/ccalm/weather => tools}/DBTools.java | 2 +- src/main/java/tools/StdTools.java | 30 +++ 12 files changed, 795 insertions(+), 195 deletions(-) create mode 100644 src/main/java/org/ccalm/weather/BookController.java create mode 100644 src/main/java/org/ccalm/weather/Translation.java create mode 100644 src/main/java/org/ccalm/weather/models/ErrorResponseModel.java create mode 100644 src/main/java/org/ccalm/weather/models/PointModel.java create mode 100644 src/main/java/tools/CustomException.java rename src/main/java/{org/ccalm/weather => tools}/DBTools.java (98%) create mode 100644 src/main/java/tools/StdTools.java diff --git a/org_ccalm_weather.yml b/org_ccalm_weather.yml index 71a5023..477f717 100644 --- a/org_ccalm_weather.yml +++ b/org_ccalm_weather.yml @@ -22,14 +22,21 @@ custom: data_dir: /data/ db_all: #url: jdbc:postgresql://92.46.48.43:5444/weather?ApplicationName=kz_mcp_weather&sslmode=require - #url: jdbc:postgresql://192.168.0.90:5432/weather?ApplicationName=kz_mcp_weather&sslmode=require - url: jdbc:postgresql://127.0.0.1:5432/weather?ApplicationName=kz_mcp_weather&sslmode=require + url: jdbc:postgresql://192.168.0.90:5432/weather?ApplicationName=kz_mcp_weather&sslmode=require + #url: jdbc:postgresql://127.0.0.1:5432/weather?ApplicationName=kz_mcp_weather&sslmode=require login: postgres password: PasSecrKey1 db_ru: #url: jdbc:postgresql://92.46.48.43:5444/weather_ru?ApplicationName=kz_mcp_weather&sslmode=require - #url: jdbc:postgresql://192.168.0.90:5432/weather_ru?ApplicationName=kz_mcp_weather&sslmode=require - url: jdbc:postgresql://127.0.0.1:5432/weather_ru?ApplicationName=kz_mcp_weather&sslmode=require + url: jdbc:postgresql://192.168.0.90:5432/weather_ru?ApplicationName=kz_mcp_weather&sslmode=require + #url: jdbc:postgresql://127.0.0.1:5432/weather_ru?ApplicationName=kz_mcp_weather&sslmode=require login: postgres password: PasSecrKey1 + +springdoc: + api-docs: + path: /api-docs + swagger-ui: + disable-swagger-default-url: true + path: /myproject \ No newline at end of file diff --git a/pom.xml b/pom.xml index 5551499..27accc2 100644 --- a/pom.xml +++ b/pom.xml @@ -1,86 +1,123 @@ - 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 3.3.3 - - - org.ccalm - weather - 0.0.8-SNAPSHOT - weather - Weather APP - - 21 - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.4.2 + + + org.ccalm + weather + 0.0.9-SNAPSHOT + weather + Weather APP + + 21 + - - - unidata - Unidata UCAR Repository - https://artifacts.unidata.ucar.edu/content/repositories/unidata-releases/ - - + + + unidata + Unidata UCAR Repository + https://artifacts.unidata.ucar.edu/content/repositories/unidata-releases/ + + - - - org.springframework.boot - spring-boot-starter-web - - - org.postgresql - postgresql - runtime - - - org.springframework.boot - spring-boot-starter-test - test - - - net.logstash.logback - logstash-logback-encoder - 6.6 - - - - - edu.ucar - netcdfAll - 5.3.1 - - - + + + org.springframework.boot + spring-boot-starter-web + + + org.postgresql + postgresql + runtime + + + org.springframework.boot + spring-boot-starter-test + test + + + net.logstash.logback + logstash-logback-encoder + 6.6 + + + org.json + json + 20231013 + + + + com.vaadin.external.google + android-json + 0.0.20131108.vaadin1 + runtime + + + org.json + json + + + - - - - org.springframework.boot - spring-boot-maven-plugin - - - - build-info - - - - + + + edu.ucar + netcdfAll + 5.3.1 + - - org.apache.maven.plugins - maven-surefire-plugin - 2.22.2 - - - file:org_ccalm_weather.yml - - - + + org.springdoc + springdoc-openapi-starter-webmvc-ui + 2.6.0 + + + org.webjars + webjars-locator + 0.52 + - - + + org.projectlombok + lombok + 1.18.36 + provided + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + build-info + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.2 + + + file:org_ccalm_weather.yml + + + + + + diff --git a/src/main/java/org/ccalm/weather/AirTemperature.java b/src/main/java/org/ccalm/weather/AirTemperature.java index 7ca3919..5511ac3 100644 --- a/src/main/java/org/ccalm/weather/AirTemperature.java +++ b/src/main/java/org/ccalm/weather/AirTemperature.java @@ -4,44 +4,36 @@ import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; -import java.io.PrintWriter; import java.sql.*; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.*; import java.util.Date; import java.util.concurrent.TimeUnit; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.servlet.ServletContext; //import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; +import org.ccalm.weather.models.PointModel; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import tools.DBTools; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.core.io.ClassPathResource; import org.springframework.http.CacheControl; import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; import org.springframework.web.context.ServletContextAware; -import org.w3c.dom.Document; - -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; //import main.DownloadFromHTTP; -import org.ccalm.weather.WeatherDownload; import tctable.Tools; +import tools.StdTools; import ucar.ma2.Array; import ucar.nc2.Dimension; import ucar.nc2.Variable; import ucar.nc2.dataset.NetcdfDataset; +import org.json.JSONObject; @Controller public class AirTemperature implements ServletContextAware { @@ -72,6 +64,25 @@ public class AirTemperature implements ServletContextAware { this.context = servletContext; } + //--------------------------------------------------------------------------- + public JSONObject createJSONError(int code, String message, String setting, String marker) { + JSONObject json = new JSONObject(); + //try { + json.put("error_code", code); + if(message!=null && !message.isBlank()) { + json.put("error_message", Arrays.asList(message)); + } + if(setting!=null && !setting.isBlank()) { + json.put("error_setting", Arrays.asList(setting)); + } + if(marker!=null && !marker.isBlank()) { + json.put("error_marker", marker); + } + //} catch (JSONException e) { + // logger.error(e); + //} + return json; + } //--------------------------------------------------------------------------- /** * This function is run every day from CRON, to see the settings call the function: "sudo crontab -e -u tomcat" on PC 127.0.0.1 @@ -133,12 +144,18 @@ public class AirTemperature implements ServletContextAware { //Build URL to download String URL = "https://www.ftp.ncep.noaa.gov/data/nccf/com/gfs/prod/gfs."+date+"/"+time+"/atmos/gfs.t"+time+"z.pgrb2.0p25.f"+forecast; - File f = new File(data_dir+"temp"+File.separator+"air_text.idx"); - if(f.exists()) { - if (!f.delete()) { + File f1 = new File(data_dir+"temp"+File.separator+"air_text.idx"); + if(f1.exists()) { + if (!f1.delete()) { System.out.println("Failed to delete the file \"air_text.idx\"."); } } + File f2 = new File(data_dir+"temp"+File.separator+"air_text.f000"); + if(f2.exists()) { + if (!f2.delete()) { + System.out.println("Failed to delete the file \"air_text.f000\"."); + } + } WeatherDownload wd = new WeatherDownload(); if(wd.download(URL+".idx", data_dir+"temp"+File.separator+"air_text.idx", "0", "")) @@ -507,68 +524,90 @@ public class AirTemperature implements ServletContextAware { } //--------------------------------------------------------------------------- @CrossOrigin - @RequestMapping(value = "/geodatalist/getAirTemperature",method = RequestMethod.GET,produces = "application/json;charset=UTF-8") + @RequestMapping(value = "/geodatalist/getAirTemperature",method = {RequestMethod.POST,RequestMethod.GET},produces = "application/json;charset=utf-8") @ResponseBody - public Object getAirTemperature(@RequestParam("date") String date,@RequestParam("hours") int hours,@RequestParam("lat") double lat, @RequestParam("lon") double lon,HttpServletResponse response) { - + public ResponseEntity getAirTemperature(HttpServletResponse response, HttpServletRequest request, @RequestBody PointModel pointModel, @CookieValue(value = "lng", defaultValue = "1") String language_id) { String headerValue = CacheControl.maxAge(60, TimeUnit.SECONDS).getHeaderValue(); response.addHeader("Cache-Control", headerValue); + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); Map result = new HashMap<>(); - float temperature = -999; + float val = -999; Connection conn_all = DBTools.getConn(db_url_all,db_login_all,db_password_all); Connection conn_ru = DBTools.getConn(db_url_ru,db_login_ru,db_password_ru); - String sql = """ - select main.get_air_temperature(?::timestamp,?,?,?)-273.15; + String sql; + + if(pointModel.getDate()==null){ + //I assume that the dates in all databases are the same. + sql = """ + select max(date) from main.air_temperature_dates where hours=?; """; - if(conn_all!=null) { - try (Statement st = conn_all.createStatement()) { - PreparedStatement pstmt = st.getConnection().prepareStatement(sql); - pstmt.setString(1, date); - pstmt.setInt(2, hours); - pstmt.setDouble(3, lon); - pstmt.setDouble(4, lat); - try (ResultSet rs = pstmt.executeQuery()) { - if (rs.next()) { - temperature = rs.getFloat(1); - if (rs.wasNull()) { - temperature = -999; + if(conn_all!=null){ + try (PreparedStatement pstmt = conn_all.prepareStatement(sql)) { + pstmt.setInt(1, pointModel.getHours()); + try (ResultSet rs = pstmt.executeQuery()) { + if (rs.next()) { + pointModel.setDate(rs.getString(1)); } } + } catch (SQLException e) { + String uuid = UUID.randomUUID().toString(); + logger.error(uuid,e); } - } catch (SQLException ex) { - logger.error("N4:" + ex.getMessage(), ex); } } - if(temperature == -999){ - if(conn_ru!=null) { - try (Statement st = conn_ru.createStatement()) { - PreparedStatement pstmt = st.getConnection().prepareStatement(sql); - pstmt.setString(1, date); - pstmt.setInt(2, hours); - pstmt.setDouble(3, lon); - pstmt.setDouble(4, lat); - try (ResultSet rs = pstmt.executeQuery()) { - if (rs.next()) { - temperature = rs.getFloat(1); - if (rs.wasNull()) { - temperature = -999; - } + sql = """ + select main.get_air_temperature(?::TIMESTAMP WITHOUT TIME ZONE,?,?,?)-273.15; + """; + if(conn_all!=null) { + try (PreparedStatement pstmt = conn_all.prepareStatement(sql)) { + pstmt.setString(1, pointModel.getDate()); + pstmt.setInt(2, pointModel.getHours()); + pstmt.setDouble(3, pointModel.getLon()); + pstmt.setDouble(4, pointModel.getLat()); + try (ResultSet rs = pstmt.executeQuery()) { + if (rs.next()) { + val = rs.getFloat(1); + if (rs.wasNull()) { + val = -999; } } - } catch (SQLException ex) { - logger.error("N4:" + ex.getMessage(), ex); } + } catch (SQLException e) { + String uuid = UUID.randomUUID().toString(); + logger.error(uuid,e); + } + } + if(conn_ru!=null && val == -999) { + try (PreparedStatement pstmt = conn_ru.prepareStatement(sql)) { + pstmt.setString(1, pointModel.getDate()); + pstmt.setInt(2, pointModel.getHours()); + pstmt.setDouble(3, pointModel.getLon()); + pstmt.setDouble(4, pointModel.getLat()); + try (ResultSet rs = pstmt.executeQuery()) { + if (rs.next()) { + val = rs.getFloat(1); + if (rs.wasNull()) { + val = -999; + } + } + } + } catch (SQLException e) { + String uuid = UUID.randomUUID().toString(); + logger.error(uuid,e); } } result.put("error_code", 0); - result.put("temperature", temperature); - - return result; + result.put("date", pointModel.getDate()); + if(val!=-999){ + result.put("value", val); + }else{ + result.put("value", null); + } + return new ResponseEntity<>(result, HttpStatus.OK); } - -} +} \ No newline at end of file diff --git a/src/main/java/org/ccalm/weather/BookController.java b/src/main/java/org/ccalm/weather/BookController.java new file mode 100644 index 0000000..1bdf17d --- /dev/null +++ b/src/main/java/org/ccalm/weather/BookController.java @@ -0,0 +1,30 @@ +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.*; + +import java.awt.print.Book; +import java.util.Collection; + +@RestController +@RequestMapping("/api/book") +public class BookController { + + //@Autowired + //private BookRepository repository; + + @GetMapping("/{id}") + public String findById(@PathVariable long id) { + return "";//repository.findById(id) .orElseThrow(() -> new BookNotFoundException()); + } + + @GetMapping("/") + public String findBooks() { + return "";//repository.getBooks(); + } + + @PutMapping("/{id}") + @ResponseStatus(HttpStatus.OK) + public String updateBook(@PathVariable("id") final String id, @RequestBody final Book book) { + return "";//book; + } +} diff --git a/src/main/java/org/ccalm/weather/Precipitation.java b/src/main/java/org/ccalm/weather/Precipitation.java index 3270ecf..f8253f7 100644 --- a/src/main/java/org/ccalm/weather/Precipitation.java +++ b/src/main/java/org/ccalm/weather/Precipitation.java @@ -4,47 +4,33 @@ import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; -import java.io.PrintWriter; import java.sql.*; import java.text.DateFormat; import java.text.SimpleDateFormat; +import java.util.*; import java.util.Date; -import java.util.Iterator; -import java.util.List; -import java.util.TimeZone; import java.util.concurrent.TimeUnit; -import java.util.logging.Level; -import javax.servlet.ServletContext; //import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.slf4j.LoggerFactory; +import org.ccalm.weather.models.PointModel; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import tctable.Tools; +import tools.DBTools; +import org.json.JSONObject; import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.core.io.ClassPathResource; import org.springframework.http.CacheControl; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -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.bind.annotation.*; import org.springframework.web.context.ServletContextAware; -import org.w3c.dom.Document; - -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; //import main.DownloadFromHTTP; //import org.ccalm.weather.WeatherDownload; -import tctable.Tools; import ucar.ma2.Array; import ucar.nc2.Dimension; import ucar.nc2.Variable; @@ -74,6 +60,25 @@ public class Precipitation implements ServletContextAware { private jakarta.servlet.ServletContext context; + //--------------------------------------------------------------------------- + public JSONObject createJSONError(int code, String message, String setting, String marker) { + JSONObject json = new JSONObject(); + //try { + json.put("error_code", code); + if(message!=null && !message.isBlank()) { + json.put("error_message", Arrays.asList(message)); + } + if(setting!=null && !setting.isBlank()) { + json.put("error_setting", Arrays.asList(setting)); + } + if(marker!=null && !marker.isBlank()) { + json.put("error_marker", marker); + } + //} catch (JSONException e) { + // logger.error(e); + //} + return json; + } //--------------------------------------------------------------------------- @Override public void setServletContext(jakarta.servlet.ServletContext servletContext) { @@ -156,13 +161,19 @@ public class Precipitation implements ServletContextAware { //Build URL to download String URL = "https://www.ftp.ncep.noaa.gov/data/nccf/com/gfs/prod/gfs."+date+"/"+time+"/atmos/gfs.t"+time+"z.pgrb2.0p25.f"+forecast; - File f = new File(data_dir+"temp"+File.separator+"pre_text.idx"); - if(f.exists()) { - if (!f.delete()) { + File f1 = new File(data_dir+"temp"+File.separator+"pre_text.idx"); + if(f1.exists()) { + if (!f1.delete()) { System.out.println("Failed to delete the file \"pre_text.idx\"."); } } - + File f2 = new File(data_dir+"temp"+File.separator+"pre_text.idx"); + if(f2.exists()) { + if (!f2.delete()) { + System.out.println("Failed to delete the file \"pre_text.f000\"."); + } + } + WeatherDownload wd = new WeatherDownload(); if(wd.download(URL+".idx", data_dir+"temp"+File.separator+"pre_text.idx", "0", "")) { @@ -524,5 +535,91 @@ public class Precipitation implements ServletContextAware { return result; } //--------------------------------------------------------------------------- + //Weighted interpolation + @RequestMapping(value = "/geodatalist/getPrecipitation",method = {RequestMethod.POST,RequestMethod.GET},produces = "application/json;charset=utf-8") + @ResponseBody + public ResponseEntity getPrecipitation(HttpServletResponse response, HttpServletRequest request, @RequestBody PointModel pointModel, @CookieValue(value = "lng", defaultValue = "1") String language_id) { + String headerValue = CacheControl.maxAge(60, TimeUnit.SECONDS).getHeaderValue(); + response.addHeader("Cache-Control", headerValue); + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + Map result = new HashMap<>(); + + Connection conn_all = DBTools.getConn(db_url_all,db_login_all,db_password_all); + Connection conn_ru = DBTools.getConn(db_url_ru,db_login_ru,db_password_ru); + float val=-999; + + String sql; + + if(pointModel.getDate()==null){ + //I assume that the dates in all databases are the same. + sql = """ + select max(date) from main.precipitation_dates where hours=?; + """; + if(conn_all!=null){ + try (PreparedStatement pstmt = conn_all.prepareStatement(sql)) { + pstmt.setInt(1, pointModel.getHours()); + try (ResultSet rs = pstmt.executeQuery()) { + if (rs.next()) { + pointModel.setDate(rs.getString(1)); + } + } + } catch (SQLException e) { + String uuid = UUID.randomUUID().toString(); + logger.error(uuid,e); + } + } + } + + sql=""" + select main.get_precipitation(?::TIMESTAMP WITHOUT TIME ZONE,?,?,?) + """; + if(conn_all!=null) { + try (PreparedStatement pstmt = conn_all.prepareStatement(sql)) { + pstmt.setString(1, pointModel.getDate()); + pstmt.setInt(2, pointModel.getHours()); + pstmt.setDouble(3, pointModel.getLon()); + pstmt.setDouble(4, pointModel.getLat()); + try (ResultSet rs = pstmt.executeQuery()) { + if (rs.next()) { + val = rs.getFloat(1); + if (rs.wasNull()) { + val = -999; + } + } + } + } catch (SQLException e) { + String uuid = UUID.randomUUID().toString(); + logger.error(uuid,e); + } + } + if(conn_ru!=null && val == -999) { + try (PreparedStatement pstmt = conn_ru.prepareStatement(sql)) { + pstmt.setString(1, pointModel.getDate()); + pstmt.setInt(2, pointModel.getHours()); + pstmt.setDouble(3, pointModel.getLon()); + pstmt.setDouble(4, pointModel.getLat()); + try (ResultSet rs = pstmt.executeQuery()) { + if (rs.next()) { + val = rs.getFloat(1); + if (rs.wasNull()) { + val = -999; + } + } + } + } catch (SQLException e) { + String uuid = UUID.randomUUID().toString(); + logger.error(uuid,e); + } + } + + result.put("error_code", 0); + result.put("date", pointModel.getDate()); + if(val!=-999){ + result.put("value", val); + }else{ + result.put("value", null); + } + return new ResponseEntity<>(result, HttpStatus.OK); + } } diff --git a/src/main/java/org/ccalm/weather/SoilTmperature.java b/src/main/java/org/ccalm/weather/SoilTmperature.java index 8b14816..fdbb51d 100644 --- a/src/main/java/org/ccalm/weather/SoilTmperature.java +++ b/src/main/java/org/ccalm/weather/SoilTmperature.java @@ -4,46 +4,31 @@ import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; -import java.io.PrintWriter; -import java.lang.reflect.Type; import java.sql.*; import java.text.DateFormat; import java.text.SimpleDateFormat; +import java.util.*; import java.util.Date; -import java.util.Iterator; -import java.util.List; -import java.util.TimeZone; import java.util.concurrent.TimeUnit; -import java.util.logging.Level; -import java.util.logging.Logger; import javax.servlet.ServletContext; //import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; +import org.ccalm.weather.models.PointModel; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import tools.DBTools; +import org.json.JSONObject; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.core.io.ClassPathResource; import org.springframework.http.CacheControl; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -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.bind.annotation.*; import org.springframework.web.context.ServletContextAware; -import org.w3c.dom.Document; - -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; //import main.DownloadFromHTTP; -import org.ccalm.weather.WeatherDownload; import tctable.Tools; import ucar.ma2.Array; import ucar.nc2.Dimension; @@ -74,6 +59,25 @@ public class SoilTmperature implements ServletContextAware { private ServletContext context; + //--------------------------------------------------------------------------- + public JSONObject createJSONError(int code, String message, String setting, String marker) { + JSONObject json = new JSONObject(); + //try { + json.put("error_code", code); + if(message!=null && !message.isBlank()) { + json.put("error_message", Arrays.asList(message)); + } + if(setting!=null && !setting.isBlank()) { + json.put("error_setting", Arrays.asList(setting)); + } + if(marker!=null && !marker.isBlank()) { + json.put("error_marker", marker); + } + //} catch (JSONException e) { + // logger.error(e); + //} + return json; + } //--------------------------------------------------------------------------- @Override public void setServletContext(jakarta.servlet.ServletContext servletContext) { @@ -163,13 +167,19 @@ public class SoilTmperature implements ServletContextAware { //Build URL to download String URL = "https://www.ftp.ncep.noaa.gov/data/nccf/com/gfs/prod/gfs."+date+"/"+time+"/atmos/gfs.t"+time+"z.pgrb2.0p25.f"+forecast; - File f = new File(data_dir+"temp"+File.separator+"text.idx"); - if(f.exists()) { - if (!f.delete()) { + File f1 = new File(data_dir+"temp"+File.separator+"text.idx"); + if(f1.exists()) { + if (!f1.delete()) { System.out.println("Failed to delete the file \"text.idx\"."); } } - + File f2 = new File(data_dir+"temp"+File.separator+"text.f000"); + if(f2.exists()) { + if (!f2.delete()) { + System.out.println("Failed to delete the file \"text.f000\"."); + } + } + WeatherDownload wd = new WeatherDownload(); if(wd.download(URL+".idx", data_dir+"temp"+File.separator+"text.idx", "0", "")) { @@ -539,5 +549,91 @@ public class SoilTmperature implements ServletContextAware { return result; } //--------------------------------------------------------------------------- + //Weighted interpolation + @RequestMapping(value = "/geodatalist/getSoil",method = {RequestMethod.POST,RequestMethod.GET},produces = "application/json;charset=utf-8") + @ResponseBody + public ResponseEntity getSoil(HttpServletResponse response, HttpServletRequest request, @RequestBody PointModel pointModel, @CookieValue(value = "lng", defaultValue = "1") String language_id) { + String headerValue = CacheControl.maxAge(60, TimeUnit.SECONDS).getHeaderValue(); + response.addHeader("Cache-Control", headerValue); + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + Map result = new HashMap<>(); + + Connection conn_all = DBTools.getConn(db_url_all,db_login_all,db_password_all); + Connection conn_ru = DBTools.getConn(db_url_ru,db_login_ru,db_password_ru); + float val=-999; + + String sql; + + if(pointModel.getDate()==null){ + //I assume that the dates in all databases are the same. + sql = """ + select max(date) from main.soil_temperature_dates where hours=?; + """; + if(conn_all!=null){ + try (PreparedStatement pstmt = conn_all.prepareStatement(sql)) { + pstmt.setInt(1, pointModel.getHours()); + try (ResultSet rs = pstmt.executeQuery()) { + if (rs.next()) { + pointModel.setDate(rs.getString(1)); + } + } + } catch (SQLException e) { + String uuid = UUID.randomUUID().toString(); + logger.error(uuid,e); + } + } + } + + sql=""" + select main.get_soil_temperature(?::TIMESTAMP WITHOUT TIME ZONE,?,?,?) + """; + if(conn_all!=null) { + try (PreparedStatement pstmt = conn_all.prepareStatement(sql)) { + pstmt.setString(1, pointModel.getDate()); + pstmt.setInt(2, pointModel.getHours()); + pstmt.setDouble(3, pointModel.getLon()); + pstmt.setDouble(4, pointModel.getLat()); + try (ResultSet rs = pstmt.executeQuery()) { + if (rs.next()) { + val = rs.getFloat(1); + if (rs.wasNull()) { + val = -999; + } + } + } + } catch (SQLException e) { + String uuid = UUID.randomUUID().toString(); + logger.error(uuid,e); + } + } + if(conn_ru!=null && val == -999) { + try (PreparedStatement pstmt = conn_ru.prepareStatement(sql)) { + pstmt.setString(1, pointModel.getDate()); + pstmt.setInt(2, pointModel.getHours()); + pstmt.setDouble(3, pointModel.getLon()); + pstmt.setDouble(4, pointModel.getLat()); + try (ResultSet rs = pstmt.executeQuery()) { + if (rs.next()) { + val = rs.getFloat(1); + if (rs.wasNull()) { + val = -999; + } + } + } + } catch (SQLException e) { + String uuid = UUID.randomUUID().toString(); + logger.error(uuid,e); + } + } + + result.put("error_code", 0); + result.put("date", pointModel.getDate()); + if(val!=-999){ + result.put("value", val); + }else{ + result.put("value", null); + } + return new ResponseEntity<>(result, HttpStatus.OK); + } } diff --git a/src/main/java/org/ccalm/weather/Translation.java b/src/main/java/org/ccalm/weather/Translation.java new file mode 100644 index 0000000..59104b1 --- /dev/null +++ b/src/main/java/org/ccalm/weather/Translation.java @@ -0,0 +1,54 @@ +package org.ccalm.weather; + +//import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; + +public class Translation { + /*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(String text){ + /*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 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; + } +} diff --git a/src/main/java/org/ccalm/weather/models/ErrorResponseModel.java b/src/main/java/org/ccalm/weather/models/ErrorResponseModel.java new file mode 100644 index 0000000..1846483 --- /dev/null +++ b/src/main/java/org/ccalm/weather/models/ErrorResponseModel.java @@ -0,0 +1,96 @@ +package org.ccalm.weather.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; + +import java.util.Collections; +import java.util.List; + +@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 { + + @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 errorMessage; + + @Schema(description = "Options for translated text", example = "[\"99;day\",\"1;2\"]") + @JsonProperty("error_setting") + private List 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 errorCode) { + this.errorCode = errorCode; + this.errorMessage = null; + this.errorSetting = null; + this.errorMarker = null; + } + + public ErrorResponseModel(int errorCode, List errorMessage, String errorMarker) { + this.errorCode = errorCode; + this.errorMessage = errorMessage; + this.errorMarker = errorMarker; + } + + public ErrorResponseModel(int errorCode, String errorMessage, String errorMarker) { + this.errorCode = errorCode; + this.errorMessage = Collections.singletonList(errorMessage); + this.errorMarker = errorMarker; + } + + public ErrorResponseModel(int errorCode, String errorMessage, String errorSetting, String errorMarker) { + this.errorCode = errorCode; + this.errorMessage = Collections.singletonList(errorMessage); + this.errorSetting = Collections.singletonList(errorSetting); + this.errorMarker = errorMarker; + } + + public ErrorResponseModel(int errorCode, List errorMessage, List errorSetting, String errorMarker) { + this.errorCode = errorCode; + this.errorMessage = errorMessage; + this.errorSetting = errorSetting; + this.errorMarker = errorMarker; + } + + public int getError_code() { + return errorCode; + } + + public void setError_code(int errorCode) { + this.errorCode = errorCode; + } + + public List getError_message() { + return errorMessage; + } + + public void setError_message(List errorMessage) { + this.errorMessage = errorMessage; + } + + public void setError_setting(List errorSetting) { + this.errorSetting = errorSetting; + } + + public List getError_setting() { + return errorSetting; + } + + public void setError_marker(String errorMarker) { + this.errorMarker = errorMarker; + } + + public String getError_marker() { + return errorMarker; + } +} \ No newline at end of file diff --git a/src/main/java/org/ccalm/weather/models/PointModel.java b/src/main/java/org/ccalm/weather/models/PointModel.java new file mode 100644 index 0000000..f6389ad --- /dev/null +++ b/src/main/java/org/ccalm/weather/models/PointModel.java @@ -0,0 +1,43 @@ +package org.ccalm.weather.models; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class PointModel { + + @JsonProperty("date") + String date; + @JsonProperty("hours") + int hours; + @JsonProperty("lon") + double lon; + @JsonProperty("lat") + double lat; + + public String getDate() { + return date; + } + public void setDate(String date) { + this.date = date; + } + + public int getHours() { + return hours; + } + public void setHours(int hours) { + this.hours = hours; + } + + public double getLon() { + return lon; + } + public void setLon(double lon) { + this.lon = lon; + } + + public double getLat() { + return lat; + } + public void setLat(double lat) { + this.lat = lat; + } +} diff --git a/src/main/java/tools/CustomException.java b/src/main/java/tools/CustomException.java new file mode 100644 index 0000000..2f1b9fa --- /dev/null +++ b/src/main/java/tools/CustomException.java @@ -0,0 +1,71 @@ +package tools; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.ccalm.weather.models.ErrorResponseModel; +import org.json.JSONException; +import org.json.JSONObject; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +import java.util.List; + +@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) +public class CustomException extends Exception { + private static final Logger logger = LogManager.getLogger(CustomException.class); + + private ErrorResponseModel error; + + public CustomException(int errorCode, String errorMessage, String marker) { + super(errorMessage); + error = new ErrorResponseModel(errorCode, errorMessage, marker); + } + + public CustomException(int errorCode, String errorMessage, String errorSetting, String marker) { + super(errorMessage); + error = new ErrorResponseModel(errorCode, errorMessage, errorSetting, marker); + } + + public CustomException(int errorCode, List errorMessages, String marker) { + super(String.join(" ", errorMessages)); + error = new ErrorResponseModel(errorCode, errorMessages, marker); + } + + public CustomException(int errorCode, List errorMessages, List errorSettings, String marker) { + super(String.join(" ", errorMessages)); + error = new ErrorResponseModel(errorCode, errorMessages, errorSettings, marker); + } + + public int getErrorCode() { + return error.getError_code(); + } + + public String getErrorMarker() { + return error.getError_marker(); + } + + public List getErrorMessages() { + return error.getError_message(); + } + + public List getErrorSettings() { + return error.getError_setting(); + } + + public JSONObject getJson() { + JSONObject json = new JSONObject(); + try { + json.put("error_code", this.getErrorCode()); + json.put("error_message", this.getErrorMessages()); + json.put("error_setting", this.getErrorSettings()); + json.put("error_marker", this.getErrorMarker()); + } catch (JSONException e) { + logger.error("Error", e); + } + return json; + } + + public ErrorResponseModel getErrorResponseModel() { + return error; + } +} diff --git a/src/main/java/org/ccalm/weather/DBTools.java b/src/main/java/tools/DBTools.java similarity index 98% rename from src/main/java/org/ccalm/weather/DBTools.java rename to src/main/java/tools/DBTools.java index 9d842db..c39e56b 100644 --- a/src/main/java/org/ccalm/weather/DBTools.java +++ b/src/main/java/tools/DBTools.java @@ -1,4 +1,4 @@ -package org.ccalm.weather; +package tools; import org.slf4j.LoggerFactory; diff --git a/src/main/java/tools/StdTools.java b/src/main/java/tools/StdTools.java new file mode 100644 index 0000000..9adca0f --- /dev/null +++ b/src/main/java/tools/StdTools.java @@ -0,0 +1,30 @@ +package tools; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Arrays; + +public class StdTools { + + //--------------------------------------------------------------------------- + private static final Logger logger = LogManager.getLogger(StdTools.class); + + //--------------------------------------------------------------------------- + public JSONObject createJSONError(int code, String message, String setting, String marker) { + JSONObject json = new JSONObject(); + try { + json.put("error_code", code); + json.put("error_message", Arrays.asList(message)); + json.put("error_setting", Arrays.asList(setting)); + json.put("error_marker", marker); + } catch (JSONException e) { + logger.error(e); + } + return json; + } + //--------------------------------------------------------------------------- + +}