Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ok 365 sivutus #6

Merged
merged 6 commits into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,20 +43,33 @@ import scala.concurrent.duration.DurationInt

class PalautaLahetyksetResponse() {}

case class VastaanottajatTilassa(
@BeanProperty vastaanottotila: String,
@BeanProperty vastaanottajaLkm: Int
)

@JsonInclude(JsonInclude.Include.NON_ABSENT)
case class PalautaLahetyksetSuccessResponse(
@BeanProperty lahetykset: java.util.List[PalautaLahetysSuccessResponse],
@BeanProperty seuraavatAlkaen: Optional[String]
) extends PalautaLahetyksetResponse

case class PalautaLahetyksetFailureResponse(
@BeanProperty virhe: String,
@BeanProperty virhe: util.List[String],
) extends PalautaLahetyksetResponse
class PalautaLahetysResponse() {}

@JsonInclude(JsonInclude.Include.NON_ABSENT)
case class PalautaLahetysSuccessResponse(
@BeanProperty lahetysTunniste: String,
@BeanProperty otsikko: String,
@BeanProperty luotu: String
@BeanProperty omistaja: String,
@BeanProperty lahettavaPalvelu: String,
@BeanProperty lahettavanVirkailijanOID: String,
@BeanProperty lahettajanNimi: String,
@BeanProperty lahettajanSahkoposti: String,
@BeanProperty replyTo: String,
@BeanProperty luotu: String,
@BeanProperty tilat: java.util.List[VastaanottajatTilassa]
) extends PalautaLahetysResponse

case class PalautaLahetysFailureResponse(
Expand Down Expand Up @@ -145,7 +158,7 @@ class LahetysResource {
if (lahetys.isEmpty)
return ResponseEntity.status(HttpStatus.GONE).build()

val lahetyksenOikeudet : Set[String] = kantaOperaatiot.getLahetystenKayttooikeudet(Seq(lahetys.get.tunniste)).getOrElse(lahetys.get.tunniste, Set.empty)
val lahetyksenOikeudet: Set[String] = Set.empty // ei vielä toteutettu
val onLukuOikeudet = securityOperaatiot.onOikeusKatsellaEntiteetti(lahetys.get.omistaja, lahetyksenOikeudet)
if (!onLukuOikeudet)
return ResponseEntity.status(HttpStatus.FORBIDDEN).build()
Expand All @@ -172,20 +185,46 @@ class LahetysResource {
new ApiResponse(responseCode = "403", description = KATSELU_RESPONSE_403_DESCRIPTION, content = Array(new Content(schema = new Schema(implementation = classOf[Void])))),
new ApiResponse(responseCode = "410", description = KATSELU_RESPONSE_410_DESCRIPTION, content = Array(new Content(schema = new Schema(implementation = classOf[Void]))))
))
def lueLahetykset(): ResponseEntity[PalautaLahetyksetResponse] =
def lueLahetykset(@RequestParam(name = ALKAEN_PARAM_NAME, required = false) alkaen: Optional[String],
@RequestParam(name = ENINTAAN_PARAM_NAME, required = false) enintaan: Optional[String],
request: HttpServletRequest): ResponseEntity[PalautaLahetyksetResponse] =
// TODO tarkempi käyttöoikeusrajaus/suodatus
val securityOperaatiot = new SecurityOperaatiot
if (!securityOperaatiot.onOikeusKatsella())
return ResponseEntity.status(HttpStatus.FORBIDDEN).build()

// validoidaan parametrit
val alkaenAika = ParametriUtil.asInstant(alkaen)
val enintaanInt = ParametriUtil.asInt(enintaan)

var virheet: Seq[String] = Seq.empty
if (alkaen.isPresent && alkaenAika.isEmpty) virheet = virheet.appended(RaportointiAPIConstants.ALKAEN_AIKA_TUNNISTE_INVALID)
if (enintaan.isPresent &&
(enintaanInt.isEmpty || enintaanInt.get < LAHETYKSET_ENINTAAN_MIN || enintaanInt.get > LAHETYKSET_ENINTAAN_MAX))
virheet = virheet.appended(LAHETYKSET_ENINTAAN_INVALID)
if (!virheet.isEmpty)
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(PalautaLahetyksetFailureResponse(virheet.asJava))


val kantaOperaatiot = new KantaOperaatiot(DbUtil.database)
val lahetykset = kantaOperaatiot.getLahetykset()
val lahetykset = kantaOperaatiot.getLahetykset(alkaenAika,enintaanInt)
if (lahetykset.isEmpty)
return ResponseEntity.status(HttpStatus.GONE).build()

// TODO tarkempi käyttöoikeusrajaus/suodatus
// TODO sivutus
val lahetysStatukset = kantaOperaatiot.getLahetystenVastaanottotilat(lahetykset.map(_.tunniste))

val seuraavatAlkaen = {
if(lahetykset.isEmpty || kantaOperaatiot.getLahetykset(Option.apply(lahetykset.last.luotu), Option.apply(1)).isEmpty)
Optional.empty
else
Optional.of(lahetykset.last.luotu.toString)
}
// TODO sivutus edellisiin?
ResponseEntity.status(HttpStatus.OK).body(PalautaLahetyksetSuccessResponse(
lahetykset.map(lahetys => PalautaLahetysSuccessResponse(lahetys.tunniste.toString, lahetys.otsikko, lahetys.luotu.toString)).asJava))
lahetykset.map(lahetys => PalautaLahetysSuccessResponse(
lahetys.tunniste.toString, lahetys.otsikko, lahetys.omistaja, lahetys.lahettavaPalvelu, lahetys.lahettavanVirkailijanOID.getOrElse(""),
lahetys.lahettaja.nimi.getOrElse(""), lahetys.lahettaja.sahkoposti, lahetys.replyTo.getOrElse(""), lahetys.luotu.toString,
lahetysStatukset.getOrElse(lahetys.tunniste, Seq.empty).map(status => VastaanottajatTilassa(status._1, status._2)).asJava)).asJava, seuraavatAlkaen))

@GetMapping(
path = Array(GET_LAHETYS_PATH),
Expand Down Expand Up @@ -219,8 +258,13 @@ class LahetysResource {
if (!onLukuOikeudet)
return ResponseEntity.status(HttpStatus.FORBIDDEN).build()

val lahetysStatukset:Seq[VastaanottajatTilassa] = kantaOperaatiot.getLahetystenVastaanottotilat(Seq.apply(uuid.get))
.getOrElse(uuid.get, Seq.empty)
.map(status => VastaanottajatTilassa(status._1, status._2))

ResponseEntity.status(HttpStatus.OK).body(PalautaLahetysSuccessResponse(
lahetys.get.tunniste.toString, lahetys.get.otsikko, lahetys.get.luotu.toString))
lahetys.get.tunniste.toString, lahetys.get.otsikko, lahetys.get.omistaja, lahetys.get.lahettavaPalvelu, lahetys.get.lahettavanVirkailijanOID.getOrElse(""),
lahetys.get.lahettaja.nimi.getOrElse(""), lahetys.get.lahettaja.sahkoposti, lahetys.get.replyTo.getOrElse(""), lahetys.get.luotu.toString, lahetysStatukset.asJava))


@GetMapping(
Expand Down Expand Up @@ -253,7 +297,7 @@ class LahetysResource {

var virheet: Seq[String] = Seq.empty
if (uuid.isEmpty) virheet = virheet.appended(RaportointiAPIConstants.LAHETYSTUNNISTE_INVALID)
if (alkaen.isPresent && alkaenUuid.isEmpty) virheet = virheet.appended(RaportointiAPIConstants.ALKAEN_TUNNISTE_INVALID)
if (alkaen.isPresent && alkaenUuid.isEmpty) virheet = virheet.appended(RaportointiAPIConstants.ALKAEN_UUID_TUNNISTE_INVALID)
if (enintaan.isPresent &&
(enintaanInt.isEmpty || enintaanInt.get < VASTAANOTTAJAT_ENINTAAN_MIN || enintaanInt.get > VASTAANOTTAJAT_ENINTAAN_MAX))
virheet = virheet.appended(ENINTAAN_INVALID)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ object RaportointiAPIConstants {
/**
* Parametreihin liittyvät vakiot
*/
final val LAHETYKSET_ENINTAAN_MIN_STR = "1"
final val LAHETYKSET_ENINTAAN_MAX_STR = "512"
final val LAHETYKSET_ENINTAAN_MIN = VASTAANOTTAJAT_ENINTAAN_MIN_STR.toInt
final val LAHETYKSET_ENINTAAN_MAX = VASTAANOTTAJAT_ENINTAAN_MAX_STR.toInt
final val LAHETYKSET_ENINTAAN_DEFAULT = VASTAANOTTAJAT_ENINTAAN_DEFAULT_STR.toInt
final val LAHETYKSET_ENINTAAN_DEFAULT_STR = "256"
final val VASTAANOTTAJAT_ENINTAAN_MIN_STR = "1"
final val VASTAANOTTAJAT_ENINTAAN_MAX_STR = "512"
final val VASTAANOTTAJAT_ENINTAAN_MIN = VASTAANOTTAJAT_ENINTAAN_MIN_STR.toInt
Expand All @@ -66,6 +72,8 @@ object RaportointiAPIConstants {
final val VIESTITUNNISTE_INVALID = "Tunniste ei ole muodoltaan validi uuid"
final val LAHETYSTUNNISTE_INVALID = "Lahetystunniste ei ole muodoltaan validi uuid"

final val ALKAEN_TUNNISTE_INVALID = ALKAEN_PARAM_NAME + "-parametri: Tunniste ei ole muodoltaan validi uuid"
final val ALKAEN_UUID_TUNNISTE_INVALID = ALKAEN_PARAM_NAME + "-parametri: Tunniste ei ole muodoltaan validi uuid"
final val ENINTAAN_INVALID = ENINTAAN_PARAM_NAME + "-parametri: Arvon pitää olla numero väliltä " + VASTAANOTTAJAT_ENINTAAN_MIN_STR + "-" + VASTAANOTTAJAT_ENINTAAN_MAX_STR
final val ALKAEN_AIKA_TUNNISTE_INVALID = ALKAEN_PARAM_NAME + "-parametri: Tunniste ei ole muodoltaan validi aikaleima"
final val LAHETYKSET_ENINTAAN_INVALID = ENINTAAN_PARAM_NAME + "-parametri: Arvon pitää olla numero väliltä " + LAHETYKSET_ENINTAAN_MIN_STR + "-" + LAHETYKSET_ENINTAAN_MAX_STR
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package fi.oph.viestinvalitys.raportointi.resource

import java.time.Instant
import java.util.{Optional, UUID}
import scala.jdk.CollectionConverters.*

Expand Down Expand Up @@ -30,5 +31,11 @@ object ParametriUtil {
Option.apply(parametri.get.toInt)
catch
case e: Exception => Option.empty

def asInstant(parametri: Optional[String]): Option[Instant] =
try
Option.apply(Instant.parse(parametri.get))
catch
case e: Exception => Option.empty
}

Original file line number Diff line number Diff line change
Expand Up @@ -81,20 +81,23 @@ class KantaOperaatiot(db: JdbcBackend.JdbcDatabaseDef) {
Kontakti(Option.apply(lahettajanNimi), lahettajanSahkoposti), Option.apply(replyto), Prioriteetti.valueOf(prioriteetti), Instant.parse(luotu)))

/**
* Palauttaa listan lähetyksiä
* Palauttaa listan lähetyksiä hakuehdoilla
*
* @return hakuehtoja (TODO) vastaavat lähetykset
*/
def getLahetykset(): Seq[Lahetys] =
Await.result(db.run(
sql"""
SELECT tunniste, otsikko, omistaja, lahettavapalvelu, lahettavanVirkailijanOid, lahettajanNimi, lahettajanSahkoposti, replyto, prioriteetti, to_json(luotu::timestamptz)#>>'{}'
FROM lahetykset
""".as[(String, String, String, String, String, String, String, String, String, String)]), DB_TIMEOUT)
def getLahetykset(alkaen: Option[Instant], enintaan: Option[Int]): Seq[Lahetys] =
val lahetyksetQuery = sql"""
SELECT tunniste, otsikko, omistaja, lahettavapalvelu, lahettavanVirkailijanOid, lahettajanNimi, lahettajanSahkoposti, replyto, prioriteetti, to_json(luotu::timestamptz)#>>'{}'
FROM lahetykset
WHERE luotu<${alkaen.getOrElse(Instant.now()).toString}::timestamptz
ORDER BY luotu DESC
LIMIT ${enintaan.getOrElse(256)}
""".as[(String, String, String, String, String, String, String, String, String, String)]

Await.result(db.run(lahetyksetQuery), DB_TIMEOUT)
.map((tunniste, otsikko, omistaja, lahettavapalvelu, lahettavanVirkailijanOid, lahettajanNimi, lahettajanSahkoposti, replyTo, prioriteetti, luotu) =>
Lahetys(UUID.fromString(tunniste), otsikko, omistaja, lahettavapalvelu, Option.apply(lahettavanVirkailijanOid), Kontakti(Option.apply(lahettajanNimi), lahettajanSahkoposti), Option.apply(replyTo), Prioriteetti.valueOf(prioriteetti), Instant.parse(luotu)))


/**
* Tallentaa uuden liitteen
*
Expand Down Expand Up @@ -487,6 +490,8 @@ class KantaOperaatiot(db: JdbcBackend.JdbcDatabaseDef) {
* Hakee lähetyksen vastaanottajat
*
* @param lahetysTunniste lähetyksen tunniste
* @param alkaen sivutuksen ensimmäinen vastaanottaja
* @param enintaan sivutuksen sivukoko
* @return lähetyksen vastaanottajat
*/
def getLahetyksenVastaanottajat(lahetysTunniste: UUID, alkaen: Option[UUID], enintaan: Option[Int]): Seq[Vastaanottaja] =
Expand All @@ -503,6 +508,21 @@ class KantaOperaatiot(db: JdbcBackend.JdbcDatabaseDef) {
.map((tunniste, viestiTunniste, nimi, sahkopostiOsoite, tila, prioriteetti, sesTunniste)
=> Vastaanottaja(UUID.fromString(tunniste), UUID.fromString(viestiTunniste), Kontakti(Option.apply(nimi), sahkopostiOsoite), VastaanottajanTila.valueOf(tila), Prioriteetti.valueOf(prioriteetti), Option.apply(sesTunniste)))

def getLahetystenVastaanottotilat(lahetysTunnisteet: Seq[UUID]): Map[UUID, Seq[(String, Int)]] =
if (lahetysTunnisteet.isEmpty) return Map.empty

val vastaanottajaTilatQuery = sql"""
SELECT viestit.lahetys_tunniste, vastaanottajat.tila, count(*) as vastaanottajia
FROM vastaanottajat JOIN viestit ON vastaanottajat.viesti_tunniste=viestit.tunniste
WHERE viestit.lahetys_tunniste IN (#${lahetysTunnisteet.map(tunniste => "'" + tunniste + "'").mkString(",")})
GROUP BY viestit.lahetys_tunniste, vastaanottajat.tila
ORDER BY viestit.lahetys_tunniste, vastaanottajat.tila
""".as[(String, String, Int)]
LOG.info(vastaanottajaTilatQuery.toString)

Await.result(db.run(vastaanottajaTilatQuery), DB_TIMEOUT)
.groupMap((lahetysTunniste, tila, vastaanottajalkm) => UUID.fromString(lahetysTunniste))((lahetysTunniste, tila, vastaanottajalkm) => (tila, vastaanottajalkm))

def getLahetystenKayttooikeudet(lahetysTunnisteet: Seq[UUID]): Map[UUID, Set[String]] =
if (lahetysTunnisteet.isEmpty) return Map.empty

Expand Down