diff --git a/CHANGELOG.md b/CHANGELOG.md index 524ef1a5..7d14c93e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,11 @@ Dropping a requirement of a major version of a dependency is a new contract. ## [Unreleased] [Unreleased]: https://github.com/atlassian/jira-actions/compare/release-3.24.0...master +### Fixed +- Speed up all JSON code, by reusing a `JsonProvider` instance. Fix the same root cause as in [JPERF-1401]. + +[JPERF-1401]: https://ecosystem.atlassian.net/browse/JPERF-1401 + ## [3.24.0] - 2023-10-24 [3.24.0]: https://github.com/atlassian/jira-actions/compare/release-3.23.1...release-3.24.0 diff --git a/src/main/kotlin/com/atlassian/performance/tools/jiraactions/JsonProviderSingleton.kt b/src/main/kotlin/com/atlassian/performance/tools/jiraactions/JsonProviderSingleton.kt new file mode 100644 index 00000000..7e97b6f8 --- /dev/null +++ b/src/main/kotlin/com/atlassian/performance/tools/jiraactions/JsonProviderSingleton.kt @@ -0,0 +1,8 @@ +package com.atlassian.performance.tools.jiraactions + +import javax.json.spi.JsonProvider + +internal object JsonProviderSingleton { + + val JSON: JsonProvider = JsonProvider.provider() +} diff --git a/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/ActionMetric.kt b/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/ActionMetric.kt index 2990e258..39cd2b5b 100644 --- a/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/ActionMetric.kt +++ b/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/ActionMetric.kt @@ -1,11 +1,11 @@ package com.atlassian.performance.tools.jiraactions.api +import com.atlassian.performance.tools.jiraactions.JsonProviderSingleton.JSON import com.atlassian.performance.tools.jiraactions.api.w3c.RecordedPerformanceEntries import com.atlassian.performance.tools.jiraactions.w3c.VerboseJsonFormat import java.time.Duration import java.time.Instant import java.util.* -import javax.json.Json import javax.json.JsonObject /** @@ -63,7 +63,7 @@ data class ActionMetric @Deprecated("Use ActionMetric.Builder instead.") constru @Deprecated("Use AppendableActionMetricOutput instead.") fun toJson(): JsonObject { - val builder = Json.createObjectBuilder() + val builder = JSON.createObjectBuilder() .add("label", label) .add("result", result.name) .add("duration", duration.toString()) diff --git a/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/action/SearchIssues.kt b/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/action/SearchIssues.kt index 2c97f676..ca47e0e5 100644 --- a/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/action/SearchIssues.kt +++ b/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/action/SearchIssues.kt @@ -1,5 +1,6 @@ package com.atlassian.performance.tools.jiraactions.api.action +import com.atlassian.performance.tools.jiraactions.JsonProviderSingleton.JSON import com.atlassian.performance.tools.jiraactions.api.ActionType import com.atlassian.performance.tools.jiraactions.api.SEARCH_WITH_JQL import com.atlassian.performance.tools.jiraactions.api.SeededRandom @@ -15,7 +16,6 @@ import com.atlassian.performance.tools.jiraactions.api.page.issuenav.DetailView import com.atlassian.performance.tools.jiraactions.api.page.issuenav.IssueNavResultsView import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.Logger -import javax.json.Json import javax.json.JsonObject class SearchIssues private constructor( @@ -109,7 +109,7 @@ class SearchIssues private constructor( json.getBoolean("switched") ) - fun serialize(): JsonObject = Json.createObjectBuilder() + fun serialize(): JsonObject = JSON.createObjectBuilder() .add("desiredView", desiredView) .add("selectedBefore", selectedBefore) .add("selectedAfter", selectedAfter) diff --git a/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/action/ViewCommentAction.kt b/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/action/ViewCommentAction.kt index 87326161..3aed586b 100644 --- a/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/action/ViewCommentAction.kt +++ b/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/action/ViewCommentAction.kt @@ -1,12 +1,12 @@ package com.atlassian.performance.tools.jiraactions.api.action +import com.atlassian.performance.tools.jiraactions.JsonProviderSingleton.JSON import com.atlassian.performance.tools.jiraactions.api.VIEW_COMMENT import com.atlassian.performance.tools.jiraactions.api.WebJira import com.atlassian.performance.tools.jiraactions.api.measure.ActionMeter import com.atlassian.performance.tools.jiraactions.api.memories.CommentMemory import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.Logger -import javax.json.Json class ViewCommentAction( private val jira: WebJira, @@ -26,7 +26,7 @@ class ViewCommentAction( key = VIEW_COMMENT, action = { jira.goToComment(comment.url).validateCommentIsFocused(comment.id) }, observation = { page -> - Json.createObjectBuilder() + JSON.createObjectBuilder() .add("issueKey", page.getIssueKey()) .add("commentId", comment.id) .build() diff --git a/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/action/ViewIssueAction.kt b/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/action/ViewIssueAction.kt index 4898d412..58c647e9 100644 --- a/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/action/ViewIssueAction.kt +++ b/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/action/ViewIssueAction.kt @@ -1,12 +1,12 @@ package com.atlassian.performance.tools.jiraactions.api.action +import com.atlassian.performance.tools.jiraactions.JsonProviderSingleton.JSON import com.atlassian.performance.tools.jiraactions.api.VIEW_ISSUE import com.atlassian.performance.tools.jiraactions.api.WebJira import com.atlassian.performance.tools.jiraactions.api.measure.ActionMeter import com.atlassian.performance.tools.jiraactions.api.memories.* import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.Logger -import javax.json.Json class ViewIssueAction private constructor( private val jira: WebJira, @@ -44,7 +44,7 @@ class ViewIssueAction private constructor( key = VIEW_ISSUE, action = { jira.goToIssue(issueKey).waitForSummary() }, observation = { page -> - Json.createObjectBuilder() + JSON.createObjectBuilder() .add("issueKey", issueKey) .add("issueId", page.getIssueId()) .build() diff --git a/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/format/MetricCompactJsonFormat.kt b/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/format/MetricCompactJsonFormat.kt index 32cf4c39..0905f55b 100644 --- a/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/format/MetricCompactJsonFormat.kt +++ b/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/format/MetricCompactJsonFormat.kt @@ -1,11 +1,11 @@ package com.atlassian.performance.tools.jiraactions.api.format +import com.atlassian.performance.tools.jiraactions.JsonProviderSingleton.JSON import com.atlassian.performance.tools.jiraactions.api.ActionMetric import com.atlassian.performance.tools.jiraactions.api.ActionResult import java.time.Duration import java.time.Instant import java.util.* -import javax.json.Json import javax.json.JsonObject /** @@ -16,7 +16,7 @@ class MetricCompactJsonFormat: MetricJsonFormat { override fun serialize( actionMetric: ActionMetric ): JsonObject = actionMetric.run { - Json.createObjectBuilder() + JSON.createObjectBuilder() .add("label", label) .add("result", result.name) .add("duration", duration.toString()) diff --git a/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/format/MetricVerboseJsonFormat.kt b/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/format/MetricVerboseJsonFormat.kt index 599ee212..d20ece11 100644 --- a/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/format/MetricVerboseJsonFormat.kt +++ b/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/format/MetricVerboseJsonFormat.kt @@ -1,12 +1,12 @@ package com.atlassian.performance.tools.jiraactions.api.format +import com.atlassian.performance.tools.jiraactions.JsonProviderSingleton.JSON import com.atlassian.performance.tools.jiraactions.api.ActionMetric import com.atlassian.performance.tools.jiraactions.api.ActionResult import com.atlassian.performance.tools.jiraactions.w3c.VerboseJsonFormat import java.time.Duration import java.time.Instant import java.util.* -import javax.json.Json import javax.json.JsonObject class MetricVerboseJsonFormat : MetricJsonFormat { @@ -16,7 +16,7 @@ class MetricVerboseJsonFormat : MetricJsonFormat { override fun serialize( actionMetric: ActionMetric ): JsonObject = actionMetric.run { - Json.createObjectBuilder() + JSON.createObjectBuilder() .add("label", label) .add("result", result.name) .add("duration", duration.toString()) diff --git a/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/observation/IssueObservation.kt b/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/observation/IssueObservation.kt index d16310a9..d6c283ff 100644 --- a/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/observation/IssueObservation.kt +++ b/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/observation/IssueObservation.kt @@ -1,6 +1,6 @@ package com.atlassian.performance.tools.jiraactions.api.observation -import javax.json.Json +import com.atlassian.performance.tools.jiraactions.JsonProviderSingleton.JSON import javax.json.JsonObject data class IssueObservation( @@ -8,7 +8,7 @@ data class IssueObservation( ) { constructor(json: JsonObject) : this(json.getString("issueKey")) - fun serialize(): JsonObject = Json.createObjectBuilder() + fun serialize(): JsonObject = JSON.createObjectBuilder() .add("issueKey", issueKey) .build() -} \ No newline at end of file +} diff --git a/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/observation/IssuesOnBoard.kt b/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/observation/IssuesOnBoard.kt index e6309e2c..8e73daf6 100644 --- a/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/observation/IssuesOnBoard.kt +++ b/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/observation/IssuesOnBoard.kt @@ -1,10 +1,10 @@ package com.atlassian.performance.tools.jiraactions.api.observation -import javax.json.Json +import com.atlassian.performance.tools.jiraactions.JsonProviderSingleton.JSON import javax.json.JsonObject data class IssuesOnBoard(val issues: Int) { constructor(json: JsonObject) : this(json.getInt("issues")) - fun serialize(): JsonObject = Json.createObjectBuilder().add("issues", issues).build() -} \ No newline at end of file + fun serialize(): JsonObject = JSON.createObjectBuilder().add("issues", issues).build() +} diff --git a/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/observation/SearchJqlObservation.kt b/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/observation/SearchJqlObservation.kt index 220ca824..51c0c80d 100644 --- a/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/observation/SearchJqlObservation.kt +++ b/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/observation/SearchJqlObservation.kt @@ -1,6 +1,6 @@ package com.atlassian.performance.tools.jiraactions.api.observation -import javax.json.Json +import com.atlassian.performance.tools.jiraactions.JsonProviderSingleton.JSON import javax.json.JsonObject data class SearchJqlObservation( @@ -10,9 +10,9 @@ data class SearchJqlObservation( ) { constructor(json: JsonObject) : this(json.getString("jql"), json.getInt("issues"), json.getInt("totalResults")) - fun serialize(): JsonObject = Json.createObjectBuilder() + fun serialize(): JsonObject = JSON.createObjectBuilder() .add("jql", jql) .add("issues", issues) .add("totalResults", totalResults) .build() -} \ No newline at end of file +} diff --git a/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/parser/ActionMetricsParser.kt b/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/parser/ActionMetricsParser.kt index ce8e76aa..47cb8054 100644 --- a/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/parser/ActionMetricsParser.kt +++ b/src/main/kotlin/com/atlassian/performance/tools/jiraactions/api/parser/ActionMetricsParser.kt @@ -1,5 +1,6 @@ package com.atlassian.performance.tools.jiraactions.api.parser +import com.atlassian.performance.tools.jiraactions.JsonProviderSingleton.JSON import com.atlassian.performance.tools.jiraactions.api.ActionMetric import com.atlassian.performance.tools.jiraactions.api.format.MetricJsonFormat import com.atlassian.performance.tools.jiraactions.api.format.MetricVerboseJsonFormat @@ -7,7 +8,6 @@ import org.apache.logging.log4j.LogManager import java.io.InputStream import java.io.StringReader import java.util.stream.Stream -import javax.json.Json import javax.json.JsonStructure import kotlin.streams.asStream import kotlin.streams.toList @@ -35,7 +35,7 @@ class ActionMetricsParser(private val format: MetricJsonFormat) { private fun parseOrNull( line: String ): JsonStructure? = try { - Json.createReader(StringReader(line)).read() + JSON.createReader(StringReader(line)).read() } catch (e: Exception) { logger.debug("Discarding '$line'", e) null diff --git a/src/main/kotlin/com/atlassian/performance/tools/jiraactions/w3c/VerboseJsonFormat.kt b/src/main/kotlin/com/atlassian/performance/tools/jiraactions/w3c/VerboseJsonFormat.kt index 047780ca..5dbadc51 100644 --- a/src/main/kotlin/com/atlassian/performance/tools/jiraactions/w3c/VerboseJsonFormat.kt +++ b/src/main/kotlin/com/atlassian/performance/tools/jiraactions/w3c/VerboseJsonFormat.kt @@ -1,5 +1,6 @@ package com.atlassian.performance.tools.jiraactions.w3c +import com.atlassian.performance.tools.jiraactions.JsonProviderSingleton.JSON import com.atlassian.performance.tools.jiraactions.api.w3c.* import java.time.Duration import javax.json.Json @@ -11,7 +12,7 @@ internal class VerboseJsonFormat { fun serializeRecordedEntries( entries: RecordedPerformanceEntries ): JsonObject = entries.run { - Json.createObjectBuilder() + JSON.createObjectBuilder() .add("navigations", navigations.map { serializeNavigationTiming(it) }.toJsonArray()) .add("resources", resources.map { serializeResourceTiming(it) }.toJsonArray()) .add("elements", (elements.map { serializeElementTiming(it) }).toJsonArray()) @@ -38,7 +39,7 @@ internal class VerboseJsonFormat { private fun serializeEntry( entry: PerformanceEntry ): JsonObject = entry.run { - Json.createObjectBuilder() + JSON.createObjectBuilder() .add("name", name) .add("entryType", entryType) .add("startTime", startTime.toString()) @@ -60,7 +61,7 @@ internal class VerboseJsonFormat { private fun serializeResourceTiming( resourceTiming: PerformanceResourceTiming ): JsonObject = resourceTiming.run { - Json.createObjectBuilder() + JSON.createObjectBuilder() .add("entry", serializeEntry(entry)) .add("initiatorType", initiatorType) .add("nextHopProtocol", nextHopProtocol) @@ -118,7 +119,7 @@ internal class VerboseJsonFormat { private fun serializeNavigationTiming( navigationTiming: PerformanceNavigationTiming ): JsonObject = navigationTiming.run { - Json.createObjectBuilder() + JSON.createObjectBuilder() .add("resource", serializeResourceTiming(resource)) .add("unloadEventStart", unloadEventStart.toString()) .add("unloadEventEnd", unloadEventEnd.toString()) @@ -154,7 +155,7 @@ internal class VerboseJsonFormat { private fun serializeServerTiming( serverTiming: PerformanceServerTiming ): JsonObject = serverTiming.run { - Json.createObjectBuilder() + JSON.createObjectBuilder() .add("name", serverTiming.name) .add("duration", serverTiming.duration.toString()) .add("description", serverTiming.description) @@ -172,7 +173,7 @@ internal class VerboseJsonFormat { } private fun List.toJsonArray(): JsonArray { - val builder = Json.createArrayBuilder() + val builder = JSON.createArrayBuilder() forEach { builder.add(it) } return builder.build() } @@ -184,7 +185,7 @@ internal class VerboseJsonFormat { private fun serializeElementTiming( elementTiming: PerformanceElementTiming ): JsonObject = elementTiming.run { - return Json.createObjectBuilder() + return JSON.createObjectBuilder() .add("renderTime", renderTime.toString()) .add("loadTime", loadTime.toString()) .add("identifier", identifier)