From d0dca19b75a09275cfa8721dfb4783a70c390d20 Mon Sep 17 00:00:00 2001 From: Santeri Korri Date: Fri, 19 Apr 2024 15:50:52 +0300 Subject: [PATCH] OK-493 Tallennetaan jatkuvan sijoittelun data sijoittelun kantaan --- sijoittelu-service/pom.xml | 4 + .../docker/configure-sijoittelu-database.sh | 15 ++- .../main/java/fi/vm/sade/sijoittelu/App.java | 3 +- .../impl/SijoitteluSeurantaResourceImpl.java | 127 +++++++----------- .../SijoitteluServiceConfiguration.java | 19 ++- ...9000000__add_jatkuva_sijoittelu_schema.sql | 18 +++ .../java/fi/vm/sade/sijoittelu/DevApp.java | 6 +- .../common.properties.template | 4 + 8 files changed, 111 insertions(+), 85 deletions(-) create mode 100644 sijoittelu-service/src/main/resources/db/migration/V20240419000000__add_jatkuva_sijoittelu_schema.sql diff --git a/sijoittelu-service/pom.xml b/sijoittelu-service/pom.xml index c2946bae8..94411ceef 100644 --- a/sijoittelu-service/pom.xml +++ b/sijoittelu-service/pom.xml @@ -42,6 +42,10 @@ org.springframework.boot spring-boot-starter-quartz + + org.springframework.boot + spring-boot-starter-jdbc + org.springdoc springdoc-openapi-ui diff --git a/sijoittelu-service/postgresql/docker/configure-sijoittelu-database.sh b/sijoittelu-service/postgresql/docker/configure-sijoittelu-database.sh index b5d65c8b2..93c0799a9 100755 --- a/sijoittelu-service/postgresql/docker/configure-sijoittelu-database.sh +++ b/sijoittelu-service/postgresql/docker/configure-sijoittelu-database.sh @@ -2,17 +2,22 @@ set -euo pipefail -DB_APP_DB=sijoittelu +DB_APP_VALINTAREKISTERI_DB=valintarekisteri +DB_APP_SIJOITTELU_DB=sijoittelu DB_APP_USER=oph DB_APP_PASSWORD=oph -echo "Creating database \"$DB_APP_DB\", creating role \"$DB_APP_USER\" with database owner privileges…" +echo "Creating databases \"$DB_APP_VALINTAREKISTERI_DB\", \"$DB_APP_SIJOITTELU_DB\", creating role \"$DB_APP_USER\" with database owner privileges…" psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-END create role "${DB_APP_USER}" with password '${DB_APP_PASSWORD}' login; -create database "${DB_APP_DB}" encoding 'UTF-8' lc_collate 'C' lc_ctype 'C' TEMPLATE template0; -grant all privileges on database "${DB_APP_DB}" to "${DB_APP_USER}"; +create database "${DB_APP_VALINTAREKISTERI_DB}" encoding 'UTF-8' lc_collate 'C' lc_ctype 'C' TEMPLATE template0; +grant all privileges on database "${DB_APP_VALINTAREKISTERI_DB}" to "${DB_APP_USER}"; +create database "${DB_APP_SIJOITTELU_DB}" encoding 'UTF-8' lc_collate 'C' lc_ctype 'C' TEMPLATE template0; +grant all privileges on database "${DB_APP_SIJOITTELU_DB}" to "${DB_APP_USER}"; END -psql "${DB_APP_DB}" -c "ALTER SCHEMA \"public\" OWNER TO \"${DB_APP_USER}\"" \ +psql "${DB_APP_VALINTAREKISTERI_DB}" -c "ALTER SCHEMA \"public\" OWNER TO \"${DB_APP_USER}\"" \ + -c "GRANT ALL ON SCHEMA \"public\" TO \"${DB_APP_USER}\"" +psql "${DB_APP_SIJOITTELU_DB}" -c "ALTER SCHEMA \"public\" OWNER TO \"${DB_APP_USER}\"" \ -c "GRANT ALL ON SCHEMA \"public\" TO \"${DB_APP_USER}\"" \ No newline at end of file diff --git a/sijoittelu-service/src/main/java/fi/vm/sade/sijoittelu/App.java b/sijoittelu-service/src/main/java/fi/vm/sade/sijoittelu/App.java index 21fd3dc02..bdb9d6eef 100644 --- a/sijoittelu-service/src/main/java/fi/vm/sade/sijoittelu/App.java +++ b/sijoittelu-service/src/main/java/fi/vm/sade/sijoittelu/App.java @@ -2,10 +2,11 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; -@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, MongoAutoConfiguration.class }) +@SpringBootApplication(exclude = { FlywayAutoConfiguration.class, MongoAutoConfiguration.class }) public class App { public static final String CONTEXT_PATH = "/sijoittelu-service"; diff --git a/sijoittelu-service/src/main/java/fi/vm/sade/sijoittelu/kooste/external/resource/seuranta/impl/SijoitteluSeurantaResourceImpl.java b/sijoittelu-service/src/main/java/fi/vm/sade/sijoittelu/kooste/external/resource/seuranta/impl/SijoitteluSeurantaResourceImpl.java index d937c8e65..8b94d1c92 100644 --- a/sijoittelu-service/src/main/java/fi/vm/sade/sijoittelu/kooste/external/resource/seuranta/impl/SijoitteluSeurantaResourceImpl.java +++ b/sijoittelu-service/src/main/java/fi/vm/sade/sijoittelu/kooste/external/resource/seuranta/impl/SijoitteluSeurantaResourceImpl.java @@ -1,45 +1,49 @@ package fi.vm.sade.sijoittelu.kooste.external.resource.seuranta.impl; -import com.google.gson.reflect.TypeToken; import fi.vm.sade.sijoittelu.kooste.external.resource.seuranta.SijoitteluSeurantaResource; -import fi.vm.sade.sijoittelu.kooste.external.resource.viestintapalvelu.RestCasClient; -import fi.vm.sade.sijoittelu.laskenta.util.UrlProperties; import fi.vm.sade.valinta.seuranta.sijoittelu.dto.SijoitteluDto; -import java.util.Collection; -import java.util.Collections; -import java.util.Optional; + +import java.time.Instant; +import java.util.*; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Service; // TODO: clean up implementation @Service public class SijoitteluSeurantaResourceImpl implements SijoitteluSeurantaResource { - private final RestCasClient restCasClient; + private static final Logger LOG = LoggerFactory.getLogger(SijoitteluSeurantaResourceImpl.class); + + private final JdbcTemplate jdbcTemplate; - private final UrlProperties urlProperties; + private final RowMapper sijoitteluDtoRowMapper = (rs, rowNum) -> + new SijoitteluDto( + rs.getString("haku_oid"), + rs.getBoolean("jatkuva_paalla"), + rs.getDate("viimeksi_ajettu"), + null, + rs.getDate("aloitus"), + rs.getInt("ajotiheys") + ); @Autowired - public SijoitteluSeurantaResourceImpl( - @Qualifier("SeurantaCasClient") RestCasClient restCasClient, UrlProperties urlProperties) { - this.restCasClient = restCasClient; - this.urlProperties = urlProperties; + public SijoitteluSeurantaResourceImpl(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; } - ; @Override public SijoitteluDto hae(String hakuOid) { try { - return this.restCasClient - .get( - this.urlProperties.url("valintalaskentakoostepalvelu.seuranta.rest.url") - + "/sijoittelunseuranta/hae/" - + hakuOid, - new TypeToken() {}, - Collections.emptyMap(), - 10 * 60 * 1000) - .get(); + return jdbcTemplate.queryForObject("SELECT haku_oid, jatkuva_paalla, viimeksi_ajettu, aloitus, ajotiheys FROM jatkuvat WHERE haku_oid=?", + sijoitteluDtoRowMapper, hakuOid); + } catch (EmptyResultDataAccessException e) { + return null; } catch (Exception e) { throw new RuntimeException(e); } @@ -48,14 +52,7 @@ public SijoitteluDto hae(String hakuOid) { @Override public Collection hae() { try { - return this.restCasClient - .get( - this.urlProperties.url("valintalaskentakoostepalvelu.seuranta.rest.url") - + "/sijoittelunseuranta/hae", - new TypeToken>() {}, - Collections.emptyMap(), - 10 * 60 * 1000) - .get(); + return jdbcTemplate.query("SELECT haku_oid, jatkuva_paalla, viimeksi_ajettu, aloitus, ajotiheys FROM jatkuvat", sijoitteluDtoRowMapper); } catch (Exception e) { throw new RuntimeException(e); } @@ -64,18 +61,13 @@ public Collection hae() { @Override public SijoitteluDto merkkaaSijoittelunAjossaTila(String hakuOid, boolean tila) { try { - return this.restCasClient - .put( - this.urlProperties.url("valintalaskentakoostepalvelu.seuranta.rest.url") - + "/sijoittelunseuranta/sijoittelu/" - + hakuOid - + "/ajossa/" - + tila, - new TypeToken() {}, - Optional.empty(), - Collections.emptyMap(), - 10 * 60 * 1000) - .get(); + this.jdbcTemplate.update( + "INSERT INTO jatkuvat " + + "(haku_oid, jatkuva_paalla, viimeksi_ajettu, aloitus, ajotiheys) " + + "VALUES (?, ?, null, null, null) " + + "ON CONFLICT (haku_oid) DO UPDATE SET jatkuva_paalla=?", + hakuOid, tila, tila); + return this.hae(hakuOid); } catch (Exception e) { throw new RuntimeException(e); } @@ -84,16 +76,13 @@ public SijoitteluDto merkkaaSijoittelunAjossaTila(String hakuOid, boolean tila) @Override public SijoitteluDto merkkaaSijoittelunAjetuksi(String hakuOid) { try { - return this.restCasClient - .put( - this.urlProperties.url("valintalaskentakoostepalvelu.seuranta.rest.url") - + "/sijoittelunseuranta/sijoittelu/" - + hakuOid, - new TypeToken() {}, - Optional.empty(), - Collections.emptyMap(), - 10 * 60 * 1000) - .get(); + String now = new Date().toString(); + this.jdbcTemplate.update("INSERT INTO jatkuvat " + + "(haku_oid, jatkuva_paalla, viimeksi_ajettu, aloitus, ajotiheys) " + + "VALUES (?, false, ?::timestamptz, null, null) " + + "ON CONFLICT (haku_oid) DO UPDATE SET viimeksi_ajettu=?::timestamptz", + hakuOid, now, now); + return this.hae(hakuOid); } catch (Exception e) { throw new RuntimeException(e); } @@ -102,14 +91,7 @@ public SijoitteluDto merkkaaSijoittelunAjetuksi(String hakuOid) { @Override public void poistaSijoittelu(String hakuOid) { try { - this.restCasClient - .delete( - this.urlProperties.url("valintalaskentakoostepalvelu.seuranta.rest.url") - + "/sijoittelunseuranta/sijoittelu/" - + hakuOid, - Collections.emptyMap(), - 10 * 60 * 1000) - .get(); + this.jdbcTemplate.update("DELETE FROM jatkuvat WHERE haku_oid=?", hakuOid); } catch (Exception e) { throw new RuntimeException(e); } @@ -119,23 +101,14 @@ public void poistaSijoittelu(String hakuOid) { public void paivitaSijoittelunAloitusajankohta( String hakuOid, long aloitusajankohta, int ajotiheys) { try { - this.restCasClient - .put( - this.urlProperties.url("valintalaskentakoostepalvelu.seuranta.rest.url") - + "/sijoittelunseuranta/sijoittelu/" - + hakuOid - + "/paivita" - + "?aloitusajankohta=" - + aloitusajankohta - + "&ajotiheys=" - + ajotiheys, - new TypeToken() {}, - Optional.empty(), - Collections.emptyMap(), - 10 * 60 * 1000) - .get(); + String aloitus = Date.from(Instant.ofEpochMilli(aloitusajankohta)).toString(); + this.jdbcTemplate.update("INSERT INTO jatkuvat " + + "(haku_oid, jatkuva_paalla, viimeksi_ajettu, aloitus, ajotiheys) " + + "VALUES (?, false, null, ?::timestamptz, ?) " + + "ON CONFLICT (haku_oid) DO UPDATE SET aloitus=?::timestamptz, ajotiheys=?", + hakuOid, aloitus, ajotiheys, aloitus, ajotiheys); } catch (Exception e) { throw new RuntimeException(e); } } -} +} \ No newline at end of file diff --git a/sijoittelu-service/src/main/java/fi/vm/sade/sijoittelu/laskenta/configuration/SijoitteluServiceConfiguration.java b/sijoittelu-service/src/main/java/fi/vm/sade/sijoittelu/laskenta/configuration/SijoitteluServiceConfiguration.java index a108eb3fa..3358197d5 100644 --- a/sijoittelu-service/src/main/java/fi/vm/sade/sijoittelu/laskenta/configuration/SijoitteluServiceConfiguration.java +++ b/sijoittelu-service/src/main/java/fi/vm/sade/sijoittelu/laskenta/configuration/SijoitteluServiceConfiguration.java @@ -8,10 +8,14 @@ import fi.vm.sade.valinta.sharedutils.AuditLogger; import fi.vm.sade.valintalaskenta.tulos.logging.LaskentaAuditLogImpl; import fi.vm.sade.valintalaskenta.tulos.mapping.ValintalaskentaModelMapper; +import org.flywaydb.core.Flyway; import org.mongodb.morphia.Datastore; import org.mongodb.morphia.Morphia; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.*; +import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.scheduling.annotation.EnableAsync; @@ -23,10 +27,13 @@ "fi.vm.sade.valintalaskenta.tulos.service.impl", "fi.vm.sade.valintalaskenta.tulos.service.impl.converters", }) -public class SijoitteluServiceConfiguration { +public class SijoitteluServiceConfiguration implements InitializingBean { public static final String CALLER_ID = "1.2.246.562.10.00000000001.sijoittelu.sijoittelu-service"; + @Autowired + JdbcTemplate jdbcTemplate; + @Bean public Audit audit() { return new Audit(new AuditLogger(), "sijoittelu", ApplicationType.VIRKAILIJA); } @@ -59,4 +66,14 @@ public void addCorsMappings(CorsRegistry registry) { } }; } + + @Override + public void afterPropertiesSet() throws Exception { + Flyway flyway = new Flyway(); + flyway.setSchemas("public"); + flyway.setDataSource(jdbcTemplate.getDataSource()); + flyway.setLocations("/db/migration"); + flyway.setTable("sijoittelu_schema_version"); + flyway.migrate(); + } } diff --git a/sijoittelu-service/src/main/resources/db/migration/V20240419000000__add_jatkuva_sijoittelu_schema.sql b/sijoittelu-service/src/main/resources/db/migration/V20240419000000__add_jatkuva_sijoittelu_schema.sql new file mode 100644 index 000000000..11f887b06 --- /dev/null +++ b/sijoittelu-service/src/main/resources/db/migration/V20240419000000__add_jatkuva_sijoittelu_schema.sql @@ -0,0 +1,18 @@ +CREATE TABLE IF NOT EXISTS jatkuvat ( + haku_oid TEXT PRIMARY KEY, + jatkuva_paalla BOOLEAN, + viimeksi_ajettu TIMESTAMP, + aloitus TIMESTAMP, + ajotiheys INTEGER +); + +CREATE TABLE IF NOT EXISTS jatkuva_virheet ( + haku_oid TEXT, + aika TIMESTAMP, + virhe TEXT, + CONSTRAINT fk_haku_oid FOREIGN KEY (haku_oid) REFERENCES jatkuvat(haku_oid) ON DELETE CASCADE +); + +DROP INDEX IF EXISTS jatkuva_virheet_haku_oid; + +CREATE INDEX jatkuva_virheet_haku_oid ON jatkuva_virheet (haku_oid); diff --git a/sijoittelu-service/src/test/java/fi/vm/sade/sijoittelu/DevApp.java b/sijoittelu-service/src/test/java/fi/vm/sade/sijoittelu/DevApp.java index a7e2e90b9..ebf1f58a7 100644 --- a/sijoittelu-service/src/test/java/fi/vm/sade/sijoittelu/DevApp.java +++ b/sijoittelu-service/src/test/java/fi/vm/sade/sijoittelu/DevApp.java @@ -24,10 +24,14 @@ public static void main(String[] args) { System.setProperty("web.url.cas", "https://virkailija.hahtuvaopintopolku.fi/cas"); // postgres - System.setProperty("valintarekisteri.db.url", "jdbc:postgresql://localhost:5433/sijoittelu"); + System.setProperty("valintarekisteri.db.url", "jdbc:postgresql://localhost:5433/valintarekisteri"); System.setProperty("valintarekisteri.db.user", "oph"); System.setProperty("valintarekisteri.db.password", "oph"); + System.setProperty("spring.datasource.url", "jdbc:postgresql://localhost:5433/sijoittelu"); + System.setProperty("spring.datasource.username", "oph"); + System.setProperty("spring.datasource.password", "oph"); + // mongo System.setProperty("valintalaskenta-laskenta-service.mongodb.uri", "mongodb://${valintalaskentadb.user}:${valintalaskentadb.password}@localhost/valintalaskentadb"); System.setProperty("valintalaskenta-laskenta-service.mongodb.dbname", "valintalaskentadb"); diff --git a/src/main/resources/oph-configuration/common.properties.template b/src/main/resources/oph-configuration/common.properties.template index 36cf35042..46a29f5a7 100644 --- a/src/main/resources/oph-configuration/common.properties.template +++ b/src/main/resources/oph-configuration/common.properties.template @@ -99,3 +99,7 @@ sijoittelu.email.smtp.use_tls={{ sijoittelu_email_smtp_use_tls | default('false' sijoittelu.email.smtp.toinen_aste_emails={{ sijoittelu_email_smtp_toinen_aste_emails | default('') }} sijoittelu.email.smtp.kk_emails={{ sijoittelu_email_smtp_kk_emails | default('') }} sijoittelu.email.smtp.use_authentication={{ sijoittelu_email_smtp_use_authentication | default('false') }} + +spring.datasource.username={{postgres_app_user}} +spring.datasource.password={{host_postgresql_sijoittelu_app_password}} +spring.datasource.url=jdbc:postgresql://{{host_postgresql_sijoittelu}}/sijoittelu