Skip to content
Open
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
4 changes: 4 additions & 0 deletions core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,10 @@
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.evomaster.core.problem.rest.arazzo.deserializer

import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.JsonDeserializer
import com.fasterxml.jackson.databind.JsonNode
import org.evomaster.core.problem.rest.arazzo.models.AnyExpression
import org.evomaster.core.problem.rest.arazzo.parser.ExpressionParser

class AnyExpressionDeserializer : JsonDeserializer<AnyExpression>() {
override fun deserialize(
p0: JsonParser,
p1: DeserializationContext
): AnyExpression {
val node: JsonNode = p0.codec.readTree(p0)
if (node.isTextual && node.asText().startsWith("$")) {
return try {
val parsedExpression = ExpressionParser.parse(node.asText())
AnyExpression.Expression(parsedExpression)
} catch (e: Exception) {
throw IllegalArgumentException("Arazzo Parsing Error: Invalid ${node.asText()}", e)
}
}

return AnyExpression.Constant(node)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.evomaster.core.problem.rest.arazzo.deserializer

import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.JsonDeserializer
import com.fasterxml.jackson.databind.JsonNode
import org.evomaster.core.problem.rest.arazzo.models.CriterionExpression
import org.evomaster.core.problem.rest.arazzo.models.CriterionType

class CriterionTypeDeserializer : JsonDeserializer<CriterionType>() {
override fun deserialize(
p0: JsonParser,
p1: DeserializationContext
): CriterionType {
val node: JsonNode = p0.codec.readTree(p0)
return when {
node.isTextual -> CriterionType.Simple(node.asText())
node.isObject -> {
val complexObj = p0.codec.treeToValue(node, CriterionExpression::class.java)
CriterionType.Complex(complexObj)
}
else -> throw IllegalArgumentException("Arazzo Parsing Error: Invalid ${node.nodeType}. Expected string or Criterion Expression")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.evomaster.core.problem.rest.arazzo.deserializer

import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.JsonDeserializer
import com.fasterxml.jackson.databind.JsonNode
import org.evomaster.core.problem.rest.arazzo.models.FailureAction
import org.evomaster.core.problem.rest.arazzo.models.FailureReusable
import org.evomaster.core.problem.rest.arazzo.models.Reusable

class FailureReusableDeserializer : JsonDeserializer<FailureReusable>() {
override fun deserialize(
p0: JsonParser,
p1: DeserializationContext
): FailureReusable? {
val node: JsonNode = p0.codec.readTree(p0)

return if (node.has("reference")) {
val reusable = p0.codec.treeToValue(node, Reusable::class.java)
FailureReusable.ReusableObj(reusable)
} else {
val action = p0.codec.treeToValue(node, FailureAction::class.java)
FailureReusable.Failure(action)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.evomaster.core.problem.rest.arazzo.deserializer

import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.JsonDeserializer
import com.fasterxml.jackson.databind.JsonNode
import org.evomaster.core.problem.rest.arazzo.models.Parameter
import org.evomaster.core.problem.rest.arazzo.models.ParameterReusable
import org.evomaster.core.problem.rest.arazzo.models.Reusable

class ParameterReusableDeserializer : JsonDeserializer<ParameterReusable>() {
override fun deserialize(
p0: JsonParser,
p1: DeserializationContext
): ParameterReusable? {
val node: JsonNode = p0.codec.readTree(p0)

return if (node.has("reference")) {
val reusable = p0.codec.treeToValue(node, Reusable::class.java)
ParameterReusable.ReusableObj(reusable)
} else {
val parameter = p0.codec.treeToValue(node, Parameter::class.java)
ParameterReusable.Param(parameter)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.evomaster.core.problem.rest.arazzo.deserializer

import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.JsonDeserializer
import org.evomaster.core.problem.rest.arazzo.models.RuntimeExpression
import org.evomaster.core.problem.rest.arazzo.parser.ExpressionParser

class RuntimeExpressionDeserializer : JsonDeserializer<RuntimeExpression>() {
override fun deserialize(
p0: JsonParser,
p1: DeserializationContext
): RuntimeExpression {
val expressionString = p0.text

return try {
ExpressionParser.parse(expressionString)
} catch (e: Exception) {
throw IllegalArgumentException("Arazzo Parsing Error: Invalid $expressionString", e)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.evomaster.core.problem.rest.arazzo.deserializer

import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.JsonDeserializer
import com.fasterxml.jackson.databind.JsonNode
import org.evomaster.core.problem.rest.arazzo.models.Reusable
import org.evomaster.core.problem.rest.arazzo.models.SuccessAction
import org.evomaster.core.problem.rest.arazzo.models.SuccessReusable

class SuccessReusableDeserializer : JsonDeserializer<SuccessReusable>() {
override fun deserialize(
p0: JsonParser,
p1: DeserializationContext
): SuccessReusable? {
val node: JsonNode = p0.codec.readTree(p0)

return if (node.has("reference")) {
val reusable = p0.codec.treeToValue(node, Reusable::class.java)
SuccessReusable.ReusableObj(reusable)
} else {
val action = p0.codec.treeToValue(node, SuccessAction::class.java)
SuccessReusable.Success(action)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package org.evomaster.core.problem.rest.arazzo.mapper

import io.swagger.v3.oas.models.media.Schema
import org.evomaster.core.problem.rest.arazzo.models.ArazzoSpecifications
import org.evomaster.core.problem.rest.arazzo.models.Step
import org.evomaster.core.problem.rest.arazzo.models.Workflow
import org.evomaster.core.problem.rest.arazzo.models.raws.ArazzoSpecificationsRaw
import org.evomaster.core.problem.rest.arazzo.models.raws.StepRaw
import org.evomaster.core.problem.rest.arazzo.models.raws.WorkflowRaw
import org.evomaster.core.problem.rest.arazzo.resolver.ArazzoReferenceResolver

class ArazzoMapper(
val resolver: ArazzoReferenceResolver
) {

fun toDomain(raw: ArazzoSpecificationsRaw) : ArazzoSpecifications {
return ArazzoSpecifications(
common = raw,
workflows = raw.workflows.map { toDomain(it) }
)
}

fun toDomain(raw: WorkflowRaw) : Workflow {
return Workflow(
common = raw,
inputs = toDomain(raw.inputs),
steps = raw.steps.map { toDomain(it) },
successActions = resolver.resolveSuccessReusable(raw.successActions),
failureActions = resolver.resolveFailureReusable(raw.failureActions),
parameters = resolver.resolveParametersReusable(raw.parameters)
)
}

fun toDomain(raw: StepRaw) : Step {
return Step(
common = raw,
parameters = resolver.resolveParametersReusable(raw.parameters),
onSuccess = resolver.resolveSuccessReusable(raw.onSuccess),
onFailure = resolver.resolveFailureReusable(raw.onFailure)
)
}

fun toDomain(schema: Schema<*>?) : Schema<*>? {
if (schema?.`$ref`?.isNotBlank() == true) {
val reference = toDomain(resolver.resolveJsonPointer(schema.`$ref`))
return reference?.apply {
properties = properties?.mapValues { toDomain(it.value) }
}
}
return schema
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.evomaster.core.problem.rest.arazzo.models

import com.fasterxml.jackson.databind.JsonNode

sealed class AnyExpression {
data class Constant(val data: JsonNode) : AnyExpression()

data class Expression(val expression: RuntimeExpression) : AnyExpression()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.evomaster.core.problem.rest.arazzo.models

import org.evomaster.core.problem.rest.arazzo.models.commons.ArazzoSpecificationsCommon

class ArazzoSpecifications(
common: ArazzoSpecificationsCommon,
val workflows: List<Workflow>,
) : ArazzoSpecificationsCommon by common
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.evomaster.core.problem.rest.arazzo.models

import io.swagger.v3.oas.models.media.Schema

class Components(
val inputs: Map<String, Schema<*>>?,
val parameters: Map<String, Parameter>?,
val successActions: Map<String, SuccessAction>?,
val failureActions: Map<String, FailureAction>?
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.evomaster.core.problem.rest.arazzo.models

import com.fasterxml.jackson.databind.annotation.JsonDeserialize
import org.evomaster.core.problem.rest.arazzo.deserializer.CriterionTypeDeserializer

class Criterion(
val context: RuntimeExpression?,
val condition: String,
@JsonDeserialize(using = CriterionTypeDeserializer::class)
val type: CriterionType?
) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.evomaster.core.problem.rest.arazzo.models

class CriterionExpression(
val type: String,
val version: String
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.evomaster.core.problem.rest.arazzo.models

sealed class CriterionType {
data class Simple(val value: String) : CriterionType()

data class Complex(val expr: CriterionExpression) : CriterionType()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.evomaster.core.problem.rest.arazzo.models

class FailureAction(
val name: String,
val type: String,
val workflowId: String?,
val stepId: String?,
val retryAfter: Number?,
val retryLimit: Integer?,
val criteria: List<Criterion>?
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.evomaster.core.problem.rest.arazzo.models

sealed class FailureReusable {
data class Failure(val action: FailureAction) : FailureReusable()

data class ReusableObj(val reusable: Reusable) : FailureReusable()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.evomaster.core.problem.rest.arazzo.models

class InfoArazzo(
val title: String,
val summary: String?,
val description: String?,
val version: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.evomaster.core.problem.rest.arazzo.models

import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
import org.evomaster.core.problem.rest.arazzo.deserializer.AnyExpressionDeserializer

class Parameter(
val name: String,
@JsonProperty("in")
val location: String?,
@JsonDeserialize(using = AnyExpressionDeserializer::class)
val value: AnyExpression
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.evomaster.core.problem.rest.arazzo.models

sealed class ParameterReusable {
data class Param(val parameter: Parameter) : ParameterReusable()

data class ReusableObj(val reusable: Reusable) : ParameterReusable()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.evomaster.core.problem.rest.arazzo.models

import com.fasterxml.jackson.databind.JsonNode

class PayloadReplacement(
val target: String,
val value: JsonNode
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.evomaster.core.problem.rest.arazzo.models

import com.fasterxml.jackson.databind.JsonNode

class RequestBody(
val contentType: String?,
val payload: JsonNode?,
val replacements: List<PayloadReplacement>?
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.evomaster.core.problem.rest.arazzo.models

import com.fasterxml.jackson.databind.annotation.JsonDeserialize
import org.evomaster.core.problem.rest.arazzo.deserializer.RuntimeExpressionDeserializer

class Reusable(
@JsonDeserialize(using = RuntimeExpressionDeserializer::class)
val reference: RuntimeExpression,
val value: String?
) {
}
Loading