diff --git a/.github/workflows/build_pr.yaml b/.github/workflows/build_pr.yaml index d02a0ff..7ccf30b 100644 --- a/.github/workflows/build_pr.yaml +++ b/.github/workflows/build_pr.yaml @@ -32,3 +32,5 @@ jobs: ${{ runner.os }}-gradle- - name: Build run: ./gradlew build + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/build.gradle.kts b/build.gradle.kts index 64c899b..e776b2f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -11,7 +11,7 @@ val kluentVersion = "1.72" val ktorVersion = "2.3.5" val logbackVersion = "1.5.3" val logstashEncoderVersion = "7.4" -val openHtmlToPdfVersion = "1.1.4" +val openHtmlToPdfVersion = "pdfbox2-65c2c5010f84b2daa5821971c9c68cd330463830" val prometheusVersion = "0.16.0" val junitJupiterVersion = "5.10.2" val verapdfVersion = "1.24.1" @@ -59,6 +59,13 @@ tasks { repositories { mavenCentral() mavenLocal() + maven { + url = uri("https://maven.pkg.github.com/openhtmltopdf/openhtmltopdf") + credentials { + username = "token" + password = System.getenv("GITHUB_TOKEN") + } + } } dependencies { diff --git a/src/main/kotlin/no/nav/pdfgen/core/Environment.kt b/src/main/kotlin/no/nav/pdfgen/core/Environment.kt index 3b8a6f0..361a08b 100644 --- a/src/main/kotlin/no/nav/pdfgen/core/Environment.kt +++ b/src/main/kotlin/no/nav/pdfgen/core/Environment.kt @@ -80,8 +80,11 @@ data class PDFGenResource(val path: String) { val filePath = filename?.let { _path.resolve(it) } ?: _path log.trace { "Reading file from path $filePath. File exists on path = ${filePath.exists()}" } return if (filePath.exists()) filePath - else Environment::class.java.classLoader.getResource(filePath.pathString)?.let{ - Path.of(it.toURI()) } ?: throw RuntimeException("Could not find file at path $filePath") + else + Environment::class.java.classLoader.getResource(filePath.pathString)?.let { + Path.of(it.toURI()) + } + ?: throw RuntimeException("Could not find file at path $filePath") } } diff --git a/src/main/kotlin/no/nav/pdfgen/core/PDFGenCore.kt b/src/main/kotlin/no/nav/pdfgen/core/PDFGenCore.kt index e44b88f..7c789ef 100644 --- a/src/main/kotlin/no/nav/pdfgen/core/PDFGenCore.kt +++ b/src/main/kotlin/no/nav/pdfgen/core/PDFGenCore.kt @@ -12,7 +12,9 @@ class PDFGenCore { coreEnvironment.set(initialEnvironment) } - val environment: Environment get() = coreEnvironment.get() + val environment: Environment + get() = coreEnvironment.get() + fun reloadEnvironment() { log.debug { "Reloading environment" } coreEnvironment.set(coreEnvironment.get().copy()) diff --git a/src/main/kotlin/no/nav/pdfgen/core/pdf/CreateHtml.kt b/src/main/kotlin/no/nav/pdfgen/core/pdf/CreateHtml.kt index bc71d41..f7ef970 100644 --- a/src/main/kotlin/no/nav/pdfgen/core/pdf/CreateHtml.kt +++ b/src/main/kotlin/no/nav/pdfgen/core/pdf/CreateHtml.kt @@ -27,16 +27,14 @@ fun createHtmlFromTemplateData(template: String, directoryName: String): String? fun render(directoryName: String, template: String, jsonNode: JsonNode): String? { return HANDLEBARS_RENDERING_SUMMARY.startTimer() .use { - PDFGenCore.environment - .templates[directoryName to template] - ?.apply( - Context.newBuilder(jsonNode) - .resolver( - JsonNodeValueResolver.INSTANCE, - MapValueResolver.INSTANCE, - ) - .build(), - ) + PDFGenCore.environment.templates[directoryName to template]?.apply( + Context.newBuilder(jsonNode) + .resolver( + JsonNodeValueResolver.INSTANCE, + MapValueResolver.INSTANCE, + ) + .build(), + ) } ?.let { html -> log.debug { "${"Generated HTML {}"} ${StructuredArguments.keyValue("html", html)}" } diff --git a/src/main/kotlin/no/nav/pdfgen/core/pdf/CreatePdf.kt b/src/main/kotlin/no/nav/pdfgen/core/pdf/CreatePdf.kt index 9256745..b208dc9 100644 --- a/src/main/kotlin/no/nav/pdfgen/core/pdf/CreatePdf.kt +++ b/src/main/kotlin/no/nav/pdfgen/core/pdf/CreatePdf.kt @@ -4,13 +4,13 @@ import com.fasterxml.jackson.databind.JsonNode import com.openhtmltopdf.pdfboxout.PdfRendererBuilder import com.openhtmltopdf.svgsupport.BatikSVGDrawer import io.github.oshai.kotlinlogging.KotlinLogging -import no.nav.pdfgen.core.PDFGenCore import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream import java.io.InputStream import java.io.OutputStream import java.util.Calendar import javax.imageio.ImageIO +import no.nav.pdfgen.core.PDFGenCore import no.nav.pdfgen.core.util.scale import no.nav.pdfgen.core.util.toPortait import org.apache.pdfbox.pdmodel.PDDocument @@ -39,6 +39,7 @@ fun createPDFA(template: String, directoryName: String, jsonPayload: JsonNode? = ?: createHtmlFromTemplateData(template, directoryName) return html?.let { createPDFA(it) } } + fun createPDFA(html: String): ByteArray { val pdf = ByteArrayOutputStream() @@ -92,7 +93,7 @@ fun createPDFA(imageStream: InputStream, outputStream: OutputStream) { dc.addCreator("pdfgen-coree") dc.addDate(cal) - val id = xmp.createAndAddPDFAIdentificationSchema() + val id = xmp.createAndAddPFAIdentificationSchema() id.part = 2 id.conformance = "U" diff --git a/src/main/kotlin/no/nav/pdfgen/core/template/Helpers.kt b/src/main/kotlin/no/nav/pdfgen/core/template/Helpers.kt index 2e52b54..41440be 100644 --- a/src/main/kotlin/no/nav/pdfgen/core/template/Helpers.kt +++ b/src/main/kotlin/no/nav/pdfgen/core/template/Helpers.kt @@ -5,15 +5,15 @@ import com.fasterxml.jackson.databind.node.ArrayNode import com.github.jknack.handlebars.Context import com.github.jknack.handlebars.Handlebars import com.github.jknack.handlebars.Helper -import no.nav.pdfgen.core.PDFGenCore -import no.nav.pdfgen.core.domain.Periode -import no.nav.pdfgen.core.domain.PeriodeMapper -import no.nav.pdfgen.core.objectMapper import java.time.LocalDate import java.time.LocalDateTime import java.time.format.DateTimeFormatter import java.time.temporal.ChronoUnit import java.util.Locale +import no.nav.pdfgen.core.PDFGenCore +import no.nav.pdfgen.core.domain.Periode +import no.nav.pdfgen.core.domain.PeriodeMapper +import no.nav.pdfgen.core.objectMapper val dateFormat: DateTimeFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy") val yearMonthFormat: DateTimeFormatter = DateTimeFormatter.ofPattern("MM.yyyy") @@ -106,10 +106,11 @@ fun registerNavHelpers( registerHelper( "json_to_period", Helper { context, _ -> - val jsonString: String? = when (context) { - is String -> context - else -> context?.let { objectMapper.writeValueAsString(it) } - } + val jsonString: String? = + when (context) { + is String -> context + else -> context?.let { objectMapper.writeValueAsString(it) } + } when (jsonString) { null -> return@Helper "" else -> { @@ -386,15 +387,9 @@ fun registerNavHelpers( Helper { value, _ -> objectMapper.writeValueAsString(value) }, ) - registerHelper( - "now", - Helper { _, _ -> LocalDateTime.now().toString()} - ) + registerHelper("now", Helper { _, _ -> LocalDateTime.now().toString() }) - registerHelper( - "now_date", - Helper { _, _ -> LocalDate.now().toString()} - ) + registerHelper("now_date", Helper { _, _ -> LocalDate.now().toString() }) additionalHelpers.forEach { (t, u) -> registerHelper(t, u) } } diff --git a/src/test/kotlin/no/nav/pdfgen/HelperTest.kt b/src/test/kotlin/no/nav/pdfgen/HelperTest.kt index e377aa7..ba792a5 100644 --- a/src/test/kotlin/no/nav/pdfgen/HelperTest.kt +++ b/src/test/kotlin/no/nav/pdfgen/HelperTest.kt @@ -9,7 +9,6 @@ import com.github.jknack.handlebars.JsonNodeValueResolver import com.github.jknack.handlebars.context.MapValueResolver import com.github.jknack.handlebars.io.ClassPathTemplateLoader import io.kotest.matchers.shouldBe -import io.kotest.matchers.string.shouldContain import io.kotest.matchers.string.shouldInclude import io.kotest.matchers.string.shouldNotInclude import no.nav.pdfgen.core.Environment @@ -23,6 +22,7 @@ import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows fun String.toJson(): JsonNode = objectMapper.readTree(this) + internal class HelperTest { val jsonNodeFactory = JsonNodeFactory.instance @@ -131,7 +131,8 @@ internal class HelperTest { @Test internal fun `Should filter list of object based on parameter`() { @Language("Json") - val jsonString = """ + val jsonString = + """ { "roller": [ { @@ -148,13 +149,18 @@ internal class HelperTest { } ] } - """.trimIndent() + """ + .trimIndent() - val template = handlebars.compileInline(""" + val template = + handlebars.compileInline( + """ {{#filter roller "type" "BARN" as |barn|}} {{barn.navn}} {{/filter}} - """.trimIndent()) + """ + .trimIndent() + ) val result = template.apply(jsonContext(jsonString.toJson())) result shouldInclude "Barn1 Etternavn" @@ -165,18 +171,24 @@ internal class HelperTest { @Test internal fun `json_to_period should convert to date with fom and tom`() { @Language("Json") - val jsonString = """ + val jsonString = + """ { "periode": { "fom": "2020-03-20", "tom": "2021-09-23" } } - """.trimIndent() + """ + .trimIndent() - val template = handlebars.compileInline(""" + val template = + handlebars.compileInline( + """ {{json_to_period periode}} - """.trimIndent()) + """ + .trimIndent() + ) val result = template.apply(jsonContext(jsonString.toJson())) result shouldBe "20.03.2020 - 23.09.2021" @@ -185,18 +197,24 @@ internal class HelperTest { @Test internal fun `json_to_period should convert to date with fom and til`() { @Language("Json") - val jsonString = """ + val jsonString = + """ { "periode": { "fom": "2020-03-20", "til": "2021-09-23" } } - """.trimIndent() + """ + .trimIndent() - val template = handlebars.compileInline(""" + val template = + handlebars.compileInline( + """ {{json_to_period periode}} - """.trimIndent()) + """ + .trimIndent() + ) val result = template.apply(jsonContext(jsonString.toJson())) result shouldBe "20.03.2020 - 23.09.2021" @@ -205,15 +223,21 @@ internal class HelperTest { @Test internal fun `json_to_period should convert to date with fom and tom as string`() { @Language("Json") - val jsonString = """ + val jsonString = + """ { "periode": "{\"fom\": \"2019-08-09\", \"tom\": \"2019-08-10\"}" } - """.trimIndent() + """ + .trimIndent() - val template = handlebars.compileInline(""" + val template = + handlebars.compileInline( + """ {{json_to_period periode}} - """.trimIndent()) + """ + .trimIndent() + ) val result = template.apply(jsonContext(jsonString.toJson())) result shouldBe "09.08.2019 - 10.08.2019" @@ -222,17 +246,23 @@ internal class HelperTest { @Test internal fun `json_to_period should convert to date with tom empty`() { @Language("Json") - val jsonString = """ + val jsonString = + """ { "periode": { "fom": "2020-03-20" } } - """.trimIndent() + """ + .trimIndent() - val template = handlebars.compileInline(""" + val template = + handlebars.compileInline( + """ {{json_to_period periode}} - """.trimIndent()) + """ + .trimIndent() + ) val result = template.apply(jsonContext(jsonString.toJson())) result shouldBe "20.03.2020 - " @@ -353,7 +383,8 @@ internal class HelperTest { ) handlebars.compileInline("{{ iso_to_nor_date date }}").apply(context) shouldBe "03.03.2020" - handlebars.compileInline("{{ iso_to_nor_date dateWithoutDay }}").apply(context) shouldBe "01.03.2020" + handlebars.compileInline("{{ iso_to_nor_date dateWithoutDay }}").apply(context) shouldBe + "01.03.2020" } @Test @@ -367,8 +398,10 @@ internal class HelperTest { ) handlebars.compileInline("{{ iso_to_year_month date }}").apply(context) shouldBe "03.2020" - handlebars.compileInline("{{ iso_to_year_month dateWithDay }}").apply(context) shouldBe "03.2020" + handlebars.compileInline("{{ iso_to_year_month dateWithDay }}").apply(context) shouldBe + "03.2020" } + @Test internal fun `Datetime formatting should format timestamp as Norwegian long date`() { val context = @@ -1547,6 +1580,7 @@ internal class HelperTest { }, ) - handlebars.compileInline("{{concat value1 value2 value3 }}").apply(context) shouldBe "Value1 123123 value3" + handlebars.compileInline("{{concat value1 value2 value3 }}").apply(context) shouldBe + "Value1 123123 value3" } }