From 82eb2628c02730c37b677afc54f0bca8003ae865 Mon Sep 17 00:00:00 2001 From: arielmirra Date: Fri, 1 Mar 2024 19:28:31 -0300 Subject: [PATCH] W-12689958: add Solace binding parsing --- .../AsyncOperationBindingsParser.scala | 14 +- .../bindings/AsyncServerBindingsParser.scala | 7 +- .../async/parser/bindings/BindingParser.scala | 6 +- .../SolaceOperationBindingParser.scala | 93 +++ .../server/SolaceServerBindingParser.scala | 24 + .../parser/context/AsyncValidBindingSet.scala | 2 +- .../parser/context/syntax/Async23Syntax.scala | 31 +- .../validations/solace-binding-extra-key.yaml | 32 + .../async20/solace-binding-extra-key.report | 38 + ...c20UniquePlatformUnitValidationsTest.scala | 716 +++++++++--------- 10 files changed, 592 insertions(+), 371 deletions(-) create mode 100644 amf-api-contract/shared/src/main/scala/amf/apicontract/internal/spec/async/parser/bindings/operation/SolaceOperationBindingParser.scala create mode 100644 amf-api-contract/shared/src/main/scala/amf/apicontract/internal/spec/async/parser/bindings/server/SolaceServerBindingParser.scala create mode 100644 amf-cli/shared/src/test/resources/validations/async20/validations/solace-binding-extra-key.yaml create mode 100644 amf-cli/shared/src/test/resources/validations/reports/async20/solace-binding-extra-key.report diff --git a/amf-api-contract/shared/src/main/scala/amf/apicontract/internal/spec/async/parser/bindings/AsyncOperationBindingsParser.scala b/amf-api-contract/shared/src/main/scala/amf/apicontract/internal/spec/async/parser/bindings/AsyncOperationBindingsParser.scala index 4139ae41fd..e67c80847f 100644 --- a/amf-api-contract/shared/src/main/scala/amf/apicontract/internal/spec/async/parser/bindings/AsyncOperationBindingsParser.scala +++ b/amf-api-contract/shared/src/main/scala/amf/apicontract/internal/spec/async/parser/bindings/AsyncOperationBindingsParser.scala @@ -3,12 +3,13 @@ package amf.apicontract.internal.spec.async.parser.bindings import amf.apicontract.client.scala.model.domain.bindings.{OperationBinding, OperationBindings} import amf.apicontract.internal.metamodel.domain.bindings._ import amf.apicontract.internal.spec.async.parser.bindings.AsyncOperationBindingsParser.parserMap -import amf.apicontract.internal.spec.async.parser.bindings.Bindings.{Amqp, Http, Kafka, Mqtt} +import amf.apicontract.internal.spec.async.parser.bindings.Bindings.{Amqp, Http, Kafka, Mqtt, Solace} import amf.apicontract.internal.spec.async.parser.bindings.operation.{ Amqp091OperationBindingParser, HttpOperationBindingParser, KafkaOperationBindingParser, - MqttOperationBindingParser + MqttOperationBindingParser, + SolaceOperationBindingParser } import amf.apicontract.internal.spec.async.parser.context.AsyncWebApiContext import amf.apicontract.internal.spec.common.WebApiDeclarations.ErrorOperationBindings @@ -20,10 +21,11 @@ import amf.shapes.internal.spec.common.parser.YMapEntryLike object AsyncOperationBindingsParser { private val parserMap: Map[String, BindingParser[OperationBinding]] = Map( - Amqp -> Amqp091OperationBindingParser, - Http -> HttpOperationBindingParser, - Kafka -> KafkaOperationBindingParser, - Mqtt -> MqttOperationBindingParser + Amqp -> Amqp091OperationBindingParser, + Http -> HttpOperationBindingParser, + Kafka -> KafkaOperationBindingParser, + Mqtt -> MqttOperationBindingParser, + Solace -> SolaceOperationBindingParser ) } diff --git a/amf-api-contract/shared/src/main/scala/amf/apicontract/internal/spec/async/parser/bindings/AsyncServerBindingsParser.scala b/amf-api-contract/shared/src/main/scala/amf/apicontract/internal/spec/async/parser/bindings/AsyncServerBindingsParser.scala index cd65930a25..d4097b605f 100644 --- a/amf-api-contract/shared/src/main/scala/amf/apicontract/internal/spec/async/parser/bindings/AsyncServerBindingsParser.scala +++ b/amf-api-contract/shared/src/main/scala/amf/apicontract/internal/spec/async/parser/bindings/AsyncServerBindingsParser.scala @@ -2,7 +2,7 @@ package amf.apicontract.internal.spec.async.parser.bindings import amf.apicontract.client.scala.model.domain.bindings.{ServerBinding, ServerBindings} import amf.apicontract.internal.metamodel.domain.bindings.ServerBindingsModel -import amf.apicontract.internal.spec.async.parser.bindings.Bindings.{IBMMQ, Mqtt} +import amf.apicontract.internal.spec.async.parser.bindings.Bindings.{IBMMQ, Mqtt, Solace} import amf.apicontract.internal.spec.async.parser.bindings.server._ import amf.apicontract.internal.spec.async.parser.context.AsyncWebApiContext import amf.apicontract.internal.spec.common.WebApiDeclarations.ErrorServerBindings @@ -14,8 +14,9 @@ import amf.shapes.internal.spec.common.parser.YMapEntryLike object AsyncServerBindingsParser { private val parserMap: Map[String, BindingParser[ServerBinding]] = Map( - Mqtt -> MqttServerBindingParser, - IBMMQ -> IBMMQServerBindingParser + Mqtt -> MqttServerBindingParser, + IBMMQ -> IBMMQServerBindingParser, + Solace -> SolaceServerBindingParser ) } case class AsyncServerBindingsParser(entryLike: YMapEntryLike)(implicit ctx: AsyncWebApiContext) diff --git a/amf-api-contract/shared/src/main/scala/amf/apicontract/internal/spec/async/parser/bindings/BindingParser.scala b/amf-api-contract/shared/src/main/scala/amf/apicontract/internal/spec/async/parser/bindings/BindingParser.scala index 9706c079da..b969d93d08 100644 --- a/amf-api-contract/shared/src/main/scala/amf/apicontract/internal/spec/async/parser/bindings/BindingParser.scala +++ b/amf-api-contract/shared/src/main/scala/amf/apicontract/internal/spec/async/parser/bindings/BindingParser.scala @@ -3,7 +3,7 @@ package amf.apicontract.internal.spec.async.parser.bindings import amf.apicontract.client.scala.model.domain.bindings.BindingVersion import amf.apicontract.internal.spec.async.parser.context.AsyncWebApiContext import amf.apicontract.internal.spec.common.parser.SpecParserOps -import amf.core.client.scala.model.domain.{AmfElement, AmfScalar, DomainElement, Linkable} +import amf.core.client.scala.model.domain.{AmfElement, AmfObject, AmfScalar, DomainElement, Linkable} import amf.core.internal.metamodel.Field import amf.core.internal.parser.YMapOps import amf.core.internal.parser.domain.Annotations @@ -24,8 +24,8 @@ trait BindingParser[+Binding <: DomainElement] extends SpecParserOps { if (bindingVersionIsEmpty(binding)) setDefaultBindingVersionValue(binding, field) } - protected def setDefaultValue(binding: BindingVersion, field: Field, element: AmfElement): binding.type = { - binding.setWithoutId(field, element, Annotations.synthesized()) + protected def setDefaultValue(obj: AmfObject, field: Field, element: AmfElement): obj.type = { + obj.setWithoutId(field, element, Annotations.synthesized()) } private def setDefaultBindingVersionValue(binding: BindingVersion, field: Field) = { diff --git a/amf-api-contract/shared/src/main/scala/amf/apicontract/internal/spec/async/parser/bindings/operation/SolaceOperationBindingParser.scala b/amf-api-contract/shared/src/main/scala/amf/apicontract/internal/spec/async/parser/bindings/operation/SolaceOperationBindingParser.scala new file mode 100644 index 0000000000..e50408338e --- /dev/null +++ b/amf-api-contract/shared/src/main/scala/amf/apicontract/internal/spec/async/parser/bindings/operation/SolaceOperationBindingParser.scala @@ -0,0 +1,93 @@ +package amf.apicontract.internal.spec.async.parser.bindings.operation + +import amf.apicontract.client.scala.model.domain.bindings.solace.{ + SolaceOperationBinding, + SolaceOperationDestination, + SolaceOperationQueue, + SolaceOperationTopic +} +import amf.apicontract.internal.metamodel.domain.bindings.{ + SolaceOperationBindingModel, + SolaceOperationDestinationModel, + SolaceOperationQueueModel, + SolaceOperationTopicModel +} +import amf.apicontract.internal.spec.async.parser.bindings.BindingParser +import amf.apicontract.internal.spec.async.parser.context.AsyncWebApiContext +import amf.core.client.scala.model.domain.AmfScalar +import amf.core.internal.parser.domain.Annotations +import org.yaml.model.{YMap, YMapEntry} +import amf.core.internal.parser.YMapOps + +object SolaceOperationBindingParser extends BindingParser[SolaceOperationBinding] { + override def parse(entry: YMapEntry, parent: String)(implicit ctx: AsyncWebApiContext): SolaceOperationBinding = { + val binding = SolaceOperationBinding(Annotations(entry)) + val map = entry.value.as[YMap] + + map.key("destinations").foreach { entry => + val destinations = entry.value.as[Seq[YMap]].map(destinationMap => parseDestination(binding, destinationMap)) + binding.setArrayWithoutId(SolaceOperationBindingModel.Destinations, destinations) + } + + parseBindingVersion(binding, SolaceOperationBindingModel.BindingVersion, map) + + ctx.closedShape(binding, map, "SolaceOperationBinding") + + binding + } + + private def parseDestination(binding: SolaceOperationBinding, map: YMap)(implicit + ctx: AsyncWebApiContext + ): SolaceOperationDestination = { + val destination = SolaceOperationDestination(Annotations()) + map.key("destinationType", SolaceOperationDestinationModel.DestinationType in destination) + + map.key("deliveryMode") match { // todo validate that it can only be 'direct' or 'persistent' + case Some(value) => Some(value).foreach(SolaceOperationDestinationModel.DeliveryMode in destination) + case None => setDefaultValue(destination, SolaceOperationDestinationModel.DeliveryMode, AmfScalar("persistent")) + } + + parseQueue(destination, map) + parseTopic(destination, map) + + destination + } + + private def parseQueue(destination: SolaceOperationDestination, map: YMap)(implicit ctx: AsyncWebApiContext): Unit = { + map.key( + "queue", + { entry => + val queue = SolaceOperationQueue(Annotations(entry.value)) + val queueMap = entry.value.as[YMap] + + queueMap.key("name", SolaceOperationQueueModel.Name in queue) + + queueMap.key("topicSubscriptions", SolaceOperationQueueModel.TopicSubscriptions in queue) + + queueMap.key("accessType", SolaceOperationQueueModel.AccessType in queue) + queueMap.key("maxMsgSpoolSize", SolaceOperationQueueModel.MaxMsgSpoolSize in queue) + queueMap.key("maxTtl", SolaceOperationQueueModel.MaxTtl in queue) + + ctx.closedShape(queue, queueMap, "SolaceOperationQueue") + + destination.setWithoutId(SolaceOperationDestinationModel.Queue, queue, Annotations(entry)) + } + ) + } + + private def parseTopic(destination: SolaceOperationDestination, map: YMap)(implicit ctx: AsyncWebApiContext): Unit = { + map.key( + "topic", + { entry => + val topic = SolaceOperationTopic(Annotations(entry.value)) + val topicMap = entry.value.as[YMap] + + topicMap.key("topicSubscriptions", SolaceOperationTopicModel.TopicSubscriptions in topic) + + ctx.closedShape(topic, topicMap, "SolaceOperationTopic") + + destination.setWithoutId(SolaceOperationDestinationModel.Topic, topic, Annotations(entry)) + } + ) + } +} diff --git a/amf-api-contract/shared/src/main/scala/amf/apicontract/internal/spec/async/parser/bindings/server/SolaceServerBindingParser.scala b/amf-api-contract/shared/src/main/scala/amf/apicontract/internal/spec/async/parser/bindings/server/SolaceServerBindingParser.scala new file mode 100644 index 0000000000..d01b88f927 --- /dev/null +++ b/amf-api-contract/shared/src/main/scala/amf/apicontract/internal/spec/async/parser/bindings/server/SolaceServerBindingParser.scala @@ -0,0 +1,24 @@ +package amf.apicontract.internal.spec.async.parser.bindings.server + +import amf.apicontract.client.scala.model.domain.bindings.solace.SolaceServerBinding +import amf.apicontract.internal.metamodel.domain.bindings.SolaceServerBindingModel +import amf.apicontract.internal.spec.async.parser.bindings.BindingParser +import amf.apicontract.internal.spec.async.parser.context.AsyncWebApiContext +import amf.core.internal.parser.YMapOps +import amf.core.internal.parser.domain.Annotations +import org.yaml.model.{YMap, YMapEntry} + +object SolaceServerBindingParser extends BindingParser[SolaceServerBinding] { + override def parse(entry: YMapEntry, parent: String)(implicit ctx: AsyncWebApiContext): SolaceServerBinding = { + val binding = SolaceServerBinding(Annotations(entry)) + val map = entry.value.as[YMap] + + map.key("msgVpn", SolaceServerBindingModel.MsgVpn in binding) + + parseBindingVersion(binding, SolaceServerBindingModel.BindingVersion, map) + + ctx.closedShape(binding, map, "SolaceServerBinding") + + binding + } +} diff --git a/amf-api-contract/shared/src/main/scala/amf/apicontract/internal/spec/async/parser/context/AsyncValidBindingSet.scala b/amf-api-contract/shared/src/main/scala/amf/apicontract/internal/spec/async/parser/context/AsyncValidBindingSet.scala index 2e1ebcca98..a0244fcfdb 100644 --- a/amf-api-contract/shared/src/main/scala/amf/apicontract/internal/spec/async/parser/context/AsyncValidBindingSet.scala +++ b/amf-api-contract/shared/src/main/scala/amf/apicontract/internal/spec/async/parser/context/AsyncValidBindingSet.scala @@ -13,7 +13,7 @@ object AsyncValidBindingSet { val async20: AsyncValidBindingSet = AsyncValidBindingSet(basic) val async21: AsyncValidBindingSet = async20.add(Mercure, IBMMQ) val async22: AsyncValidBindingSet = async21.add(AnypointMQ) - val async23: AsyncValidBindingSet = async22 + val async23: AsyncValidBindingSet = async22.add(Solace) val async24: AsyncValidBindingSet = async23 val async25: AsyncValidBindingSet = async24 val async26: AsyncValidBindingSet = async25 diff --git a/amf-api-contract/shared/src/main/scala/amf/apicontract/internal/spec/async/parser/context/syntax/Async23Syntax.scala b/amf-api-contract/shared/src/main/scala/amf/apicontract/internal/spec/async/parser/context/syntax/Async23Syntax.scala index 0e4418ca66..2d7e89206c 100644 --- a/amf-api-contract/shared/src/main/scala/amf/apicontract/internal/spec/async/parser/context/syntax/Async23Syntax.scala +++ b/amf-api-contract/shared/src/main/scala/amf/apicontract/internal/spec/async/parser/context/syntax/Async23Syntax.scala @@ -1,7 +1,36 @@ package amf.apicontract.internal.spec.async.parser.context.syntax +import amf.apicontract.internal.spec.async.parser.bindings.Bindings.Solace import amf.shapes.internal.spec.common.parser.SpecSyntax object Async23Syntax extends SpecSyntax { - override val nodes: Map[String, Set[String]] = Async22Syntax.nodes + override val nodes: Map[String, Set[String]] = + add( + Async22Syntax.nodes, + "bindings" -> Set(Solace), + "SolaceServerBinding" -> Set( + "msgVpn", + "bindingVersion" + ), + "SolaceOperationBinding" -> Set( + "destinations", + "bindingVersion" + ), + "SolaceOperationDestination" -> Set( + "destinationType", + "deliveryMode", + "queue", + "topic" + ), + "SolaceOperationQueue" -> Set( + "name", + "topicSubscriptions", + "accessType", + "maxMsgSpoolSize", + "maxTtl" + ), + "SolaceOperationTopic" -> Set( + "topicSubscriptions" + ) + ) } diff --git a/amf-cli/shared/src/test/resources/validations/async20/validations/solace-binding-extra-key.yaml b/amf-cli/shared/src/test/resources/validations/async20/validations/solace-binding-extra-key.yaml new file mode 100644 index 0000000000..1766a6329d --- /dev/null +++ b/amf-cli/shared/src/test/resources/validations/async20/validations/solace-binding-extra-key.yaml @@ -0,0 +1,32 @@ +asyncapi: 2.3.0 +info: + title: test solace binding + version: 1.0.0 +servers: + theName: + url: some.com + protocol: solace + bindings: + solace: + msgVpn: test + bindingVersion: 1.2.3 + thisKeyIsNotAllowed: should throw validation error +channels: + some-channel: + publish: + bindings: + solace: + bindingVersion: 0.3.0 + destinations: + - destinationType: queue + queue: + name: CreatedHREvents + thisKeyIsNotAllowed: should throw validation error + topicSubscriptions: + - person/*/created + - destinationType: topic + topic: + thisKeyIsNotAllowed: should throw validation error + topicSubscriptions: + - person/*/updated + thisKeyIsNotAllowed: should throw validation error \ No newline at end of file diff --git a/amf-cli/shared/src/test/resources/validations/reports/async20/solace-binding-extra-key.report b/amf-cli/shared/src/test/resources/validations/reports/async20/solace-binding-extra-key.report new file mode 100644 index 0000000000..0e36f6a039 --- /dev/null +++ b/amf-cli/shared/src/test/resources/validations/reports/async20/solace-binding-extra-key.report @@ -0,0 +1,38 @@ +ModelId: file://amf-cli/shared/src/test/resources/validations/async20/validations/solace-binding-extra-key.yaml +Profile: +Conforms: false +Number of results: 4 + +Level: Violation + +- Constraint: http://a.ml/vocabularies/amf/parser#closed-shape + Message: Property 'thisKeyIsNotAllowed' not supported in a ASYNC 2.3 SolaceServerBinding node + Severity: Violation + Target: file://amf-cli/shared/src/test/resources/validations/async20/validations/solace-binding-extra-key.yaml#/async-api/server/some.com/server-bindings/bindings/solace-server + Property: + Range: [(13,8)-(14,0)] + Location: file://amf-cli/shared/src/test/resources/validations/async20/validations/solace-binding-extra-key.yaml + +- Constraint: http://a.ml/vocabularies/amf/parser#closed-shape + Message: Property 'thisKeyIsNotAllowed' not supported in a ASYNC 2.3 SolaceOperationQueue node + Severity: Violation + Target: file://amf-cli/shared/src/test/resources/validations/async20/validations/solace-binding-extra-key.yaml#/async-api/endpoint/some-channel/supportedOperation/publish/operation-bindings/bindings/solace-operation/destinations/solace-destination/solace-queue + Property: + Range: [(24,16)-(25,0)] + Location: file://amf-cli/shared/src/test/resources/validations/async20/validations/solace-binding-extra-key.yaml + +- Constraint: http://a.ml/vocabularies/amf/parser#closed-shape + Message: Property 'thisKeyIsNotAllowed' not supported in a ASYNC 2.3 SolaceOperationTopic node + Severity: Violation + Target: file://amf-cli/shared/src/test/resources/validations/async20/validations/solace-binding-extra-key.yaml#/async-api/endpoint/some-channel/supportedOperation/publish/operation-bindings/bindings/solace-operation/destinations/solace-destination_1/solace-topic + Property: + Range: [(29,16)-(30,0)] + Location: file://amf-cli/shared/src/test/resources/validations/async20/validations/solace-binding-extra-key.yaml + +- Constraint: http://a.ml/vocabularies/amf/parser#closed-shape + Message: Property 'thisKeyIsNotAllowed' not supported in a ASYNC 2.3 SolaceOperationBinding node + Severity: Violation + Target: file://amf-cli/shared/src/test/resources/validations/async20/validations/solace-binding-extra-key.yaml#/async-api/endpoint/some-channel/supportedOperation/publish/operation-bindings/bindings/solace-operation + Property: + Range: [(32,10)-(32,60)] + Location: file://amf-cli/shared/src/test/resources/validations/async20/validations/solace-binding-extra-key.yaml diff --git a/amf-cli/shared/src/test/scala/amf/validation/Async20UniquePlatformUnitValidationsTest.scala b/amf-cli/shared/src/test/scala/amf/validation/Async20UniquePlatformUnitValidationsTest.scala index 2435e26c4e..857a32bb54 100644 --- a/amf-cli/shared/src/test/scala/amf/validation/Async20UniquePlatformUnitValidationsTest.scala +++ b/amf-cli/shared/src/test/scala/amf/validation/Async20UniquePlatformUnitValidationsTest.scala @@ -8,366 +8,368 @@ class Async20UniquePlatformUnitValidationsTest extends UniquePlatformReportGenTe override val basePath: String = asyncPath + "validations/" override val reportsPath: String = "amf-cli/shared/src/test/resources/validations/reports/async20/" -// test("Required channel object") { -// validate("required-channels.yaml", Some("required-channels.report")) -// } -// -// test("Required title in info object") { -// validate("required-info-title.yaml", Some("required-info-title.report")) -// } -// -// test("Required version in info object") { -// validate("required-info-version.yaml", Some("required-info-version.report")) -// } -// -// test("Required license name") { -// validate("required-license-name.yaml", Some("required-license-name.report")) -// } -// -// test("Server name must comply with pattern") { -// validate("server-name-pattern.yaml", Some("server-name-pattern.report")) -// } -// -// test("Mandatory server url") { -// validate("mandatory-server-url.yaml", Some("mandatory-server-url.report")) -// } -// -// test("Mandatory server protocol") { -// validate("mandatory-server-protocol.yaml", Some("mandatory-server-protocol.report")) -// } -// -// test("Channel name must conform with RFC 6570 URI template") { -// validate("channel-name-format.yaml", Some("channel-name-format.report")) -// } -// -// test("OperationId must be unique") { -// validate("duplicate-operation-id.yaml", Some("duplicate-operation-id.report")) -// } -// -// test("Parameter name must comply with regex") { -// validate("parameter-name-regex.yaml", Some("parameter-name-regex.report")) -// } -// -// test("Required tag name") { -// validate("required-tag-name.yaml", Some("required-tag-name.report")) -// } -// -// test("Required external documentation url") { -// validate("required-documentation-url.yaml", Some("required-documentation-url.report")) -// } -// -// test("Required security scheme type") { -// validate("required-security-scheme-type.yaml", Some("required-security-scheme-type.report")) -// } -// -// test("Security scheme type must meet valid values") { -// validate("security-scheme-valid-types.yaml", Some("security-scheme-valid-types.report")) -// } -// -// test("Required correlation id location") { -// validate("required-correlation-id-location.yaml", Some("required-correlation-id-location.report")) -// } -// -// test("Required httpApiKey scheme name value") { -// validate("required-httpApiKey-name.yaml", Some("required-httpApiKey-name.report")) -// } -// -// test("Required openIdConnect url") { -// validate("required-openIdConnect-url.yaml", Some("required-openIdConnect-url.report")) -// } -// -// test("Required OAuth2 flows") { -// validate("required-oauth2-flows.yaml", Some("required-oauth2-flows.report")) -// } -// -// test("Required http scheme field") { -// validate("required-http-scheme.yaml", Some("required-http-scheme.report")) -// } -// -// test("Required OAuth2 authorizatinUrl for implicit and authorizationCode") { -// validate("required-oauth2-authorizationUrl.yaml", Some("required-oauth2-authorizationUrl.report")) -// } -// -// test("Required OAuth2 tokenUrl for all but implicit") { -// validate("required-oauth2-tokenUrl.yaml", Some("required-oauth2-tokenUrl.report")) -// } -// -// test("Required OAuth2 scopes for all") { -// validate("required-oauth2-scopes.yaml", Some("required-oauth2-scopes.report")) -// } -// -// test("Required in field for apiKey and httpApiKey scheme") { -// validate("required-in-field.yaml", Some("required-in-field.report")) -// } -// -// test("Required httpOperationBinding type") { -// validate("required-httpOperationBinding-type.yaml", Some("required-httpOperationBinding-type.report")) -// } -// -// test("HttpOperationBinding type must be request or response") { -// validate("required-httpOperationBinding-type-values.yaml", Some("required-httpOperationBinding-type-values.report")) -// } -// -// test("HttpOperationBinding method must be an HTTP operation") { -// validate( -// "required-httpOperationBinding-method-values.yaml", -// Some("required-httpOperationBinding-method-values.report") -// ) -// } -// -// test("WebSocketChannelBinding method must be GET or POST") { -// validate("ws-channel-binding-valid-method.yaml", Some("ws-channel-binding-valid-method.report")) -// } -// -// test("AmqpChannelBinding is field must be request or response") { -// validate("amqp-channel-binding-is-value.yaml", Some("amqp-channel-binding-is-value.report")) -// } -// -// test("AmqpChannelBinding name max length of 255") { -// validate("amqp-channel-binding-name-max-length.yaml", Some("amqp-channel-binding-name-max-length.report")) -// } -// -// test("LastWill binding Qos field value must be 0, 1 or 2") { -// validate("last-will-qos.yaml", Some("last-will-qos.report")) -// } -// -// test("MqttOperationBinding Qos field value must be 0, 1 or 2") { -// validate("mqtt-operation-binding-qos.yaml", Some("mqtt-operation-binding-qos.report")) -// } -// -// test("AmqpOperationBinding deliveryMode field value must be 1 or 2") { -// validate("amqp-operation-binding-deliveryMode.yaml", Some("amqp-operation-binding-deliveryMode.report")) -// } -// -// test("AmqpOperationBinding expiration field value must greater than or equal to 0") { -// validate("amqp-operation-binding-expiration.yaml", Some("amqp-operation-binding-expiration.report")) -// } -// -// test("WsSocketChannelBinding query and header field must be an object type and have properties key") { -// validate("ws-channel-binding-header-query.yaml", Some("ws-channel-binding-header-query.report")) -// } -// -// test("HttpOperationBinding query field must be an object type and have properties key") { -// validate("http-operation-query.yaml", Some("http-operation-query.report")) -// } -// -// test("HttpMessageBinding headers field must be an object type and have properties key") { -// validate("http-message-headers.yaml", Some("http-message-headers.report")) -// } -// -// ignore("Nested external correlationId refs") { -// validate("nested-libraries/nested-correlationIds/api.yaml") -// } -// -// test("Nested external operation refs") { -// validate( -// "nested-libraries/nested-operation-traits/api.yaml", -// Some("nested-libraries/nested-external-operation-trait-refs.report") -// ) -// } -// -// test("Valid message trait node") { -// validate("valid-messageTrait-node.yaml") -// } -// -// test("httpApiKey and apiKey 'in' facet validation") { -// validate("security-scheme-in-facet.yaml", Some("invalid-in-facet-security-scheme.report")) -// } -// -// test("async runtime expression validations") { -// validate("invalid-runtime-expressions.yaml", Some("invalid-runtime-expressions.report")) -// } -// -// test("JsonReference is invalid with '#' only") { -// validate("json-reference/invalid-json-reference-format.yaml", Some("invalid-json-reference-format.report")) -// } -// -// test("Several url formats") { -// validate("several-url-formats.yaml", Some("several-url-formats.report")) -// } -// -// test("Invalid Id uri format") { -// validate("invalid-id-uri-format.yaml", Some("invalid-id-uri-format.report")) -// } -// -// test("Valid Id uri format") { -// validate("valid-id-uri-format.yaml") -// } -// -// test("Contact email format") { -// validate("contact-email-format.yaml", Some("contact-email-format.report")) -// } -// -// test("Message headers must type object") { -// validate("message-headers-object.yaml", Some("message-headers-object.report")) -// } -// -// test("Empty binding validation report should have location") { -// validate("empty-binding.yaml", Some("empty-binding.report")) -// } -// -// test("Invalid query parameter defined in channel uri") { -// validate("invalid-query-param-in-channel.yaml", Some("invalid-query-param-in-channel.report")) -// } -// -// test("Invalid fragment defined in channel uri") { -// validate("invalid-fragment-in-uri.yaml", Some("invalid-fragment-in-uri.report")) -// } -// -// test("Invalid yaml tags") { -// validate("invalid-yaml-tags.yaml", Some("invalid-yaml-tags.report")) -// } -// -// test("Valid header binding names according to RFC-7230") { -// validate("invalid-header-names.yaml", Some("invalid-header-names.report")) -// } -// -// test("Invalid binding names") { -// validate("invalid-binding-names.yaml", Some("invalid-binding-names.report")) -// } -// -// test("Discriminator property has to be included in required properties") { -// validate("discriminator-in-required-fields.yaml", Some("discriminator-in-required-fields.report")) -// } -// -// test("JSON with duplicate keys") { -// validate( -// "duplicate-keys.json", -// Some("duplicate-keys.report") -// ) -// } -// -// test("Components must use keys with certain regex") { -// validate("invalid-component-names.yaml", Some("invalid-component-names.report")) -// } -// -// test("Closed shape in components object") { -// validate("components-closed-shape.yaml", Some("components-closed-shape.report")) -// } -// -// test("Using $ref within inlined raml content") { -// validate( -// "invalid-inlined-ref.yaml", -// Some("invalid-inlined-ref.report"), -// directory = asyncPath + "raml-data-type-references/" -// ) -// } -// -// test("Invalid relative pointer to raml library content") { -// validate( -// "invalid-relative-pointer-to-lib.yaml", -// Some("invalid-relative-pointer-to-lib.report"), -// directory = asyncPath + "raml-data-type-references/" -// ) -// } -// -// test("Verify isolated raml context in inlined raml content") { -// validate("invalid-ref-to-async-type.yaml", Some("invalid-ref-to-async-type.report")) -// } -// -// test("Verify isolated raml context for raml content in external yaml") { -// validate( -// "ref-invalid-external-yaml.yaml", -// Some("ref-invalid-external-yaml.report"), -// directory = asyncPath + "raml-data-type-references/" -// ) -// } -// -// test("Invalid reference to type defined in raml api") { -// validate( -// "invalid-ref-to-raml-api.yaml", -// Some("invalid-ref-to-raml-api.report"), -// directory = asyncPath + "raml-data-type-references/" -// ) -// } -// -// test("Reference to invalid library type") { -// validate( -// "ref-type-in-library-invalid.yaml", -// Some("ref-type-in-library-invalid.report"), -// directory = asyncPath + "raml-data-type-references/" -// ) -// } -// -// test("Closed shape in keys of message examples") { -// validate("invalid-keys-message-examples.yaml", Some("invalid-keys-message-examples.report")) -// } -// -// test("Validate ref key in operation object") { -// validate("invalid-ref-key-operation.yaml", Some("invalid-ref-key-operation.report")) -// } -// -// test("Valid ref key in message trait defined in components") { -// validate("external-reference/valid-external-ref-message-trait.yaml") -// } -// -// test("Valid ref key in operation trait defined in components") { -// validate("external-reference/valid-external-ref-operation-trait.yaml") -// } -// -// test("Valid ref to message with another ref") { -// validate("double-references/valid-ref-to-message-with-ref.yaml") -// } -// -// test("Valid ref to operation with another ref") { -// validate("double-references/valid-ref-to-operation-with-ref.yaml") -// } -// -// test("Valid ref to parameter with another ref") { -// validate("double-references/valid-ref-to-parameter-with-ref.yaml") -// } -// -// test("Valid ref to bindings with another ref") { -// validate("double-references/valid-ref-to-bindings-with-ref.yaml") -// } -// -// test("Resources paths") { -// validate( -// "resources-paths/resources-paths.yaml", -// Some("resources-paths.report"), -// hideValidationResultsIfParseNotConforms = false -// ) -// } -// -// test("Mercure binding should be empty") { -// validate("mercure-binding-nonempty.yaml", Some("mercure-binding-nonempty.report")) -// } -// -// test("IBMMQ Closed Shape validation") { -// validate("ibmmq-binding-extra-key.yaml", Some("ibmmq-binding-extra-key.report")) -// } -// -// -// test("MessageIds NOT duplicated") { -// validate("messageIds-not-duplicated.yaml", Some("messageIds-not-duplicated.report")) -// } -// -// test("MessageIds cant be duplicate") { -// validate("messageIds-duplicated.yaml", Some("messageIds-duplicated.report")) -// } -// -// test("MessageIds inline duplicate") { -// validate("duplicate-messageId-inline.yaml", Some("duplicate-messageId-inline.report")) -// } -// -// test("invalid key in async 2.0") { -// validate("messageId-invalid.yaml", Some("messageId-invalid.report")) -// } -// -// test("Async 2.2+ channel servers property") { -// validate("channel-servers.yaml", Some("channel-servers.report")) -// } -// -// test("Async 2.2+ AnypointMQ Closed Shape validation") { -// validate("anypoint-binding-extra-key.yaml", Some("anypoint-binding-extra-key.report")) -// } -// -// test("Async 2.5 tags in servers") { -// validate("server-tags.yaml", Some("server-tags.report")) -// } + test("Required channel object") { + validate("required-channels.yaml", Some("required-channels.report")) + } + + test("Required title in info object") { + validate("required-info-title.yaml", Some("required-info-title.report")) + } + + test("Required version in info object") { + validate("required-info-version.yaml", Some("required-info-version.report")) + } + + test("Required license name") { + validate("required-license-name.yaml", Some("required-license-name.report")) + } + + test("Server name must comply with pattern") { + validate("server-name-pattern.yaml", Some("server-name-pattern.report")) + } + + test("Mandatory server url") { + validate("mandatory-server-url.yaml", Some("mandatory-server-url.report")) + } + + test("Mandatory server protocol") { + validate("mandatory-server-protocol.yaml", Some("mandatory-server-protocol.report")) + } + + test("Channel name must conform with RFC 6570 URI template") { + validate("channel-name-format.yaml", Some("channel-name-format.report")) + } + + test("OperationId must be unique") { + validate("duplicate-operation-id.yaml", Some("duplicate-operation-id.report")) + } + + test("Parameter name must comply with regex") { + validate("parameter-name-regex.yaml", Some("parameter-name-regex.report")) + } + + test("Required tag name") { + validate("required-tag-name.yaml", Some("required-tag-name.report")) + } + + test("Required external documentation url") { + validate("required-documentation-url.yaml", Some("required-documentation-url.report")) + } + + test("Required security scheme type") { + validate("required-security-scheme-type.yaml", Some("required-security-scheme-type.report")) + } + + test("Security scheme type must meet valid values") { + validate("security-scheme-valid-types.yaml", Some("security-scheme-valid-types.report")) + } + + test("Required correlation id location") { + validate("required-correlation-id-location.yaml", Some("required-correlation-id-location.report")) + } + + test("Required httpApiKey scheme name value") { + validate("required-httpApiKey-name.yaml", Some("required-httpApiKey-name.report")) + } + + test("Required openIdConnect url") { + validate("required-openIdConnect-url.yaml", Some("required-openIdConnect-url.report")) + } + + test("Required OAuth2 flows") { + validate("required-oauth2-flows.yaml", Some("required-oauth2-flows.report")) + } + + test("Required http scheme field") { + validate("required-http-scheme.yaml", Some("required-http-scheme.report")) + } + + test("Required OAuth2 authorizatinUrl for implicit and authorizationCode") { + validate("required-oauth2-authorizationUrl.yaml", Some("required-oauth2-authorizationUrl.report")) + } + + test("Required OAuth2 tokenUrl for all but implicit") { + validate("required-oauth2-tokenUrl.yaml", Some("required-oauth2-tokenUrl.report")) + } + + test("Required OAuth2 scopes for all") { + validate("required-oauth2-scopes.yaml", Some("required-oauth2-scopes.report")) + } + + test("Required in field for apiKey and httpApiKey scheme") { + validate("required-in-field.yaml", Some("required-in-field.report")) + } + + test("Required httpOperationBinding type") { + validate("required-httpOperationBinding-type.yaml", Some("required-httpOperationBinding-type.report")) + } + + test("HttpOperationBinding type must be request or response") { + validate("required-httpOperationBinding-type-values.yaml", Some("required-httpOperationBinding-type-values.report")) + } + + test("HttpOperationBinding method must be an HTTP operation") { + validate( + "required-httpOperationBinding-method-values.yaml", + Some("required-httpOperationBinding-method-values.report") + ) + } + + test("WebSocketChannelBinding method must be GET or POST") { + validate("ws-channel-binding-valid-method.yaml", Some("ws-channel-binding-valid-method.report")) + } + + test("AmqpChannelBinding is field must be request or response") { + validate("amqp-channel-binding-is-value.yaml", Some("amqp-channel-binding-is-value.report")) + } + + test("AmqpChannelBinding name max length of 255") { + validate("amqp-channel-binding-name-max-length.yaml", Some("amqp-channel-binding-name-max-length.report")) + } + + test("LastWill binding Qos field value must be 0, 1 or 2") { + validate("last-will-qos.yaml", Some("last-will-qos.report")) + } + + test("MqttOperationBinding Qos field value must be 0, 1 or 2") { + validate("mqtt-operation-binding-qos.yaml", Some("mqtt-operation-binding-qos.report")) + } + + test("AmqpOperationBinding deliveryMode field value must be 1 or 2") { + validate("amqp-operation-binding-deliveryMode.yaml", Some("amqp-operation-binding-deliveryMode.report")) + } + + test("AmqpOperationBinding expiration field value must greater than or equal to 0") { + validate("amqp-operation-binding-expiration.yaml", Some("amqp-operation-binding-expiration.report")) + } + + test("WsSocketChannelBinding query and header field must be an object type and have properties key") { + validate("ws-channel-binding-header-query.yaml", Some("ws-channel-binding-header-query.report")) + } + + test("HttpOperationBinding query field must be an object type and have properties key") { + validate("http-operation-query.yaml", Some("http-operation-query.report")) + } + + test("HttpMessageBinding headers field must be an object type and have properties key") { + validate("http-message-headers.yaml", Some("http-message-headers.report")) + } + + ignore("Nested external correlationId refs") { + validate("nested-libraries/nested-correlationIds/api.yaml") + } + + test("Nested external operation refs") { + validate( + "nested-libraries/nested-operation-traits/api.yaml", + Some("nested-libraries/nested-external-operation-trait-refs.report") + ) + } + + test("Valid message trait node") { + validate("valid-messageTrait-node.yaml") + } + + test("httpApiKey and apiKey 'in' facet validation") { + validate("security-scheme-in-facet.yaml", Some("invalid-in-facet-security-scheme.report")) + } + + test("async runtime expression validations") { + validate("invalid-runtime-expressions.yaml", Some("invalid-runtime-expressions.report")) + } + + test("JsonReference is invalid with '#' only") { + validate("json-reference/invalid-json-reference-format.yaml", Some("invalid-json-reference-format.report")) + } + + test("Several url formats") { + validate("several-url-formats.yaml", Some("several-url-formats.report")) + } + + test("Invalid Id uri format") { + validate("invalid-id-uri-format.yaml", Some("invalid-id-uri-format.report")) + } + + test("Valid Id uri format") { + validate("valid-id-uri-format.yaml") + } + + test("Contact email format") { + validate("contact-email-format.yaml", Some("contact-email-format.report")) + } + + test("Message headers must type object") { + validate("message-headers-object.yaml", Some("message-headers-object.report")) + } + + test("Empty binding validation report should have location") { + validate("empty-binding.yaml", Some("empty-binding.report")) + } + + test("Invalid query parameter defined in channel uri") { + validate("invalid-query-param-in-channel.yaml", Some("invalid-query-param-in-channel.report")) + } + + test("Invalid fragment defined in channel uri") { + validate("invalid-fragment-in-uri.yaml", Some("invalid-fragment-in-uri.report")) + } + + test("Invalid yaml tags") { + validate("invalid-yaml-tags.yaml", Some("invalid-yaml-tags.report")) + } + + test("Valid header binding names according to RFC-7230") { + validate("invalid-header-names.yaml", Some("invalid-header-names.report")) + } + + test("Invalid binding names") { + validate("invalid-binding-names.yaml", Some("invalid-binding-names.report")) + } + + test("Discriminator property has to be included in required properties") { + validate("discriminator-in-required-fields.yaml", Some("discriminator-in-required-fields.report")) + } + + test("JSON with duplicate keys") { + validate( + "duplicate-keys.json", + Some("duplicate-keys.report") + ) + } + + test("Components must use keys with certain regex") { + validate("invalid-component-names.yaml", Some("invalid-component-names.report")) + } + + test("Closed shape in components object") { + validate("components-closed-shape.yaml", Some("components-closed-shape.report")) + } + + test("Using $ref within inlined raml content") { + validate( + "invalid-inlined-ref.yaml", + Some("invalid-inlined-ref.report"), + directory = asyncPath + "raml-data-type-references/" + ) + } + + test("Invalid relative pointer to raml library content") { + validate( + "invalid-relative-pointer-to-lib.yaml", + Some("invalid-relative-pointer-to-lib.report"), + directory = asyncPath + "raml-data-type-references/" + ) + } + + test("Verify isolated raml context in inlined raml content") { + validate("invalid-ref-to-async-type.yaml", Some("invalid-ref-to-async-type.report")) + } + + test("Verify isolated raml context for raml content in external yaml") { + validate( + "ref-invalid-external-yaml.yaml", + Some("ref-invalid-external-yaml.report"), + directory = asyncPath + "raml-data-type-references/" + ) + } + + test("Invalid reference to type defined in raml api") { + validate( + "invalid-ref-to-raml-api.yaml", + Some("invalid-ref-to-raml-api.report"), + directory = asyncPath + "raml-data-type-references/" + ) + } + + test("Reference to invalid library type") { + validate( + "ref-type-in-library-invalid.yaml", + Some("ref-type-in-library-invalid.report"), + directory = asyncPath + "raml-data-type-references/" + ) + } + + test("Closed shape in keys of message examples") { + validate("invalid-keys-message-examples.yaml", Some("invalid-keys-message-examples.report")) + } + + test("Validate ref key in operation object") { + validate("invalid-ref-key-operation.yaml", Some("invalid-ref-key-operation.report")) + } + + test("Valid ref key in message trait defined in components") { + validate("external-reference/valid-external-ref-message-trait.yaml") + } + + test("Valid ref key in operation trait defined in components") { + validate("external-reference/valid-external-ref-operation-trait.yaml") + } + + test("Valid ref to message with another ref") { + validate("double-references/valid-ref-to-message-with-ref.yaml") + } + + test("Valid ref to operation with another ref") { + validate("double-references/valid-ref-to-operation-with-ref.yaml") + } + + test("Valid ref to parameter with another ref") { + validate("double-references/valid-ref-to-parameter-with-ref.yaml") + } + + test("Valid ref to bindings with another ref") { + validate("double-references/valid-ref-to-bindings-with-ref.yaml") + } + + test("Resources paths") { + validate( + "resources-paths/resources-paths.yaml", + Some("resources-paths.report"), + hideValidationResultsIfParseNotConforms = false + ) + } + + test("Mercure binding should be empty") { + validate("mercure-binding-nonempty.yaml", Some("mercure-binding-nonempty.report")) + } + + test("IBMMQ Closed Shape validation") { + validate("ibmmq-binding-extra-key.yaml", Some("ibmmq-binding-extra-key.report")) + } + + test("MessageIds NOT duplicated") { + validate("messageIds-not-duplicated.yaml", Some("messageIds-not-duplicated.report")) + } + + test("MessageIds cant be duplicate") { + validate("messageIds-duplicated.yaml", Some("messageIds-duplicated.report")) + } + + test("MessageIds inline duplicate") { + validate("duplicate-messageId-inline.yaml", Some("duplicate-messageId-inline.report")) + } + + test("invalid key in async 2.0") { + validate("messageId-invalid.yaml", Some("messageId-invalid.report")) + } + + test("Async 2.2+ channel servers property") { + validate("channel-servers.yaml", Some("channel-servers.report")) + } + + test("Async 2.2+ AnypointMQ Closed Shape validation") { + validate("anypoint-binding-extra-key.yaml", Some("anypoint-binding-extra-key.report")) + } + + test("Async 2.5 tags in servers") { + validate("server-tags.yaml", Some("server-tags.report")) + } test("Async 2.4 Server Variables") { validate("server-variable.yaml", Some("server-variable.report")) } + test("Async 2.3+ Solace Closed Shape validation") { + validate("solace-binding-extra-key.yaml", Some("solace-binding-extra-key.report")) + } }