diff --git a/.github/workflows/release-sdk.yaml b/.github/workflows/release-sdk.yaml index f65aeed18..e0ede578c 100644 --- a/.github/workflows/release-sdk.yaml +++ b/.github/workflows/release-sdk.yaml @@ -14,7 +14,7 @@ jobs: integration-tests: strategy: matrix: - jdk: [ 8, 11, 17, 21 ] + jdk: [ 11, 17, 21 ] uses: ./.github/workflows/integration-tests.yaml secrets: inherit with: diff --git a/code/README.md b/code/README.md index 10e38267a..2f722eeda 100644 --- a/code/README.md +++ b/code/README.md @@ -5,7 +5,7 @@ com.expediagroup xap-sdk - 1.2.0 + 1.2.7-SNAPSHOT ``` diff --git a/code/pom.xml b/code/pom.xml index aefb3cb2c..cdc800dfb 100644 --- a/code/pom.xml +++ b/code/pom.xml @@ -4,9 +4,9 @@ 4.0.0 com.expediagroup xap-sdk - 1.2.0 + 1.2.7-SNAPSHOT EG xap-sdk for Java - EG xap-sdk v1.2.0 + EG xap-sdk v1.2.7-SNAPSHOT https://github.com/ExpediaGroup/test-sdk 2022 jar diff --git a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/ExpediaGroupJsonFieldFilter.kt b/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/ExpediaGroupJsonFieldFilter.kt deleted file mode 100644 index 9a60c277d..000000000 --- a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/ExpediaGroupJsonFieldFilter.kt +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2022 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.expediagroup.sdk.core.plugin.logging - -import com.ebay.ejmask.core.BaseFilter - -internal class ExpediaGroupJsonFieldFilter(maskedFields: Array) : BaseFilter( - ExpediaGroupJsonFieldPatternBuilder::class.java, - *maskedFields -) diff --git a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/ExpediaGroupJsonFieldPatternBuilder.kt b/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/ExpediaGroupJsonFieldPatternBuilder.kt deleted file mode 100644 index 63ca9cfdb..000000000 --- a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/ExpediaGroupJsonFieldPatternBuilder.kt +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2022 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.expediagroup.sdk.core.plugin.logging - -import com.ebay.ejmask.extenstion.builder.json.JsonFieldPatternBuilder -import com.expediagroup.sdk.core.constant.LoggingMessage.OMITTED - -internal class ExpediaGroupJsonFieldPatternBuilder : JsonFieldPatternBuilder() { - override fun buildReplacement( - visibleCharacters: Int, - vararg fieldNames: String? - ): String = "\"$1$2$OMITTED\"" -} diff --git a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/RequestBodyLogger.kt b/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/RequestBodyLogger.kt deleted file mode 100644 index 5a077a148..000000000 --- a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/RequestBodyLogger.kt +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2022 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.expediagroup.sdk.core.plugin.logging - -import com.expediagroup.sdk.core.constant.LoggerName -import com.expediagroup.sdk.core.constant.provider.LoggingMessageProvider -import com.expediagroup.sdk.core.model.getTransactionId -import io.ktor.client.HttpClient -import io.ktor.client.plugins.HttpClientPlugin -import io.ktor.client.request.HttpRequestBuilder -import io.ktor.client.request.HttpSendPipeline -import io.ktor.http.content.OutputStreamContent -import io.ktor.http.contentType -import io.ktor.util.AttributeKey -import io.ktor.util.pipeline.PipelineContext -import io.ktor.utils.io.writer -import kotlinx.coroutines.coroutineScope - -internal class RequestBodyLogger { - private val log = ExpediaGroupLoggerFactory.getLogger(javaClass) - - companion object Plugin : HttpClientPlugin { - override val key: AttributeKey = AttributeKey(LoggerName.REQUEST_BODY_LOGGER) - - override fun install( - plugin: RequestBodyLogger, - scope: HttpClient - ) { - scope.sendPipeline.intercept(HttpSendPipeline.Monitoring) { - val body: String = getBody() - plugin.log.debug(LoggingMessageProvider.getRequestBodyMessage(body, context.headers.getTransactionId())) - proceed() - } - } - - private suspend fun PipelineContext.getBody(): String { - val body = - when { - context.contentType() in LoggableContentTypes -> context.body - else -> return "Body of type ${context.contentType()?.contentType} cannot be logged!" - } - - if (body is OutputStreamContent) { - return coroutineScope { - writer { - body.writeTo(channel) - }.channel.readRemaining().readText() - } - } - return body.toString() - } - - override fun prepare(block: RequestBodyLoggerConfig.() -> Unit): RequestBodyLogger = RequestBodyLogger() - } -} - -internal class RequestBodyLoggerConfig diff --git a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/ResponseBodyLogger.kt b/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/ResponseBodyLogger.kt deleted file mode 100644 index c06f8fdc7..000000000 --- a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/logging/ResponseBodyLogger.kt +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2022 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.expediagroup.sdk.core.plugin.logging - -import com.expediagroup.sdk.core.constant.HeaderValue -import com.expediagroup.sdk.core.constant.LoggerName -import com.expediagroup.sdk.core.constant.provider.LoggingMessageProvider -import com.expediagroup.sdk.core.model.getTransactionId -import com.expediagroup.sdk.core.plugin.logging.GZipEncoder.decode -import io.ktor.client.HttpClient -import io.ktor.client.plugins.HttpClientPlugin -import io.ktor.client.plugins.compression.ContentEncoder -import io.ktor.client.statement.HttpResponse -import io.ktor.client.statement.HttpResponsePipeline -import io.ktor.client.statement.request -import io.ktor.http.HttpHeaders -import io.ktor.http.contentType -import io.ktor.util.AttributeKey -import io.ktor.util.Encoder -import io.ktor.util.GZip -import io.ktor.util.InternalAPI -import io.ktor.utils.io.ByteReadChannel - -class ResponseBodyLogger { - private val log = ExpediaGroupLoggerFactory.getLogger(javaClass) - - companion object Plugin : HttpClientPlugin { - override val key: AttributeKey = AttributeKey(LoggerName.RESPONSE_BODY_LOGGER) - - @OptIn(InternalAPI::class) - override fun install( - plugin: ResponseBodyLogger, - scope: HttpClient - ) { - scope.responsePipeline.intercept(HttpResponsePipeline.Receive) { - val response: HttpResponse = context.response - val byteReadChannel: ByteReadChannel = if (response.contentEncoding().equals(HeaderValue.GZIP)) scope.decode(response.content) else response.content - - when { - response.contentType() in LoggableContentTypes -> - LoggingMessageProvider.getResponseBodyMessage( - byteReadChannel.readRemaining().readText(), - response.request.headers.getTransactionId() - ) - else -> LoggingMessageProvider.getResponseBodyMessage("Body of type ${response.contentType()?.contentType} cannot be logged!", response.request.headers.getTransactionId()) - }.let { - plugin.log.debug(it) - } - - proceed() - } - } - - override fun prepare(block: ResponseBodyLoggerConfig.() -> Unit): ResponseBodyLogger = ResponseBodyLogger() - } -} - -fun HttpResponse.contentEncoding(): String? = headers[HttpHeaders.ContentEncoding] - -internal object GZipEncoder : ContentEncoder, Encoder by GZip { - override val name: String = HeaderValue.GZIP -} - -class ResponseBodyLoggerConfig diff --git a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/serialization/ContentNegotiation.kt b/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/serialization/ContentNegotiation.kt deleted file mode 100644 index 00d4e672a..000000000 --- a/code/src/main/kotlin/com/expediagroup/sdk/core/plugin/serialization/ContentNegotiation.kt +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright (C) 2022 Expedia, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.expediagroup.sdk.core.plugin.serialization - -import com.expediagroup.sdk.core.plugin.logging.ExpediaGroupLoggerFactory -import io.ktor.client.HttpClient -import io.ktor.client.plugins.HttpClientPlugin -import io.ktor.client.plugins.contentnegotiation.ContentConverterException -import io.ktor.client.plugins.contentnegotiation.JsonContentTypeMatcher -import io.ktor.client.request.HttpRequestBuilder -import io.ktor.client.request.HttpRequestPipeline -import io.ktor.client.statement.HttpResponseContainer -import io.ktor.client.statement.HttpResponsePipeline -import io.ktor.client.utils.EmptyContent -import io.ktor.http.ContentType -import io.ktor.http.ContentTypeMatcher -import io.ktor.http.HttpHeaders -import io.ktor.http.HttpStatusCode -import io.ktor.http.Url -import io.ktor.http.charset -import io.ktor.http.content.NullBody -import io.ktor.http.content.OutgoingContent -import io.ktor.http.contentType -import io.ktor.serialization.Configuration -import io.ktor.serialization.ContentConverter -import io.ktor.serialization.deserialize -import io.ktor.serialization.suitableCharset -import io.ktor.util.AttributeKey -import io.ktor.util.InternalAPI -import io.ktor.util.reflect.TypeInfo -import io.ktor.utils.io.ByteReadChannel -import io.ktor.utils.io.charsets.Charset -import java.io.InputStream -import kotlin.reflect.KClass - -internal val DefaultCommonIgnoredTypes: Set> = - setOf( - ByteArray::class, - String::class, - HttpStatusCode::class, - ByteReadChannel::class, - OutgoingContent::class - ) - -internal val DefaultIgnoredTypes: Set> = mutableSetOf(InputStream::class) - -internal class ContentNegotiation( - private val registrations: List, - private val ignoredTypes: Set> -) { - internal class Config : Configuration { - internal class ConverterRegistration( - val converter: ContentConverter, - val contentTypeToSend: ContentType, - val contentTypeMatcher: ContentTypeMatcher - ) - - val registrations = mutableListOf() - val ignoredTypes: MutableSet> = - (DefaultIgnoredTypes + DefaultCommonIgnoredTypes).toMutableSet() - - override fun register( - contentType: ContentType, - converter: T, - configuration: T.() -> Unit - ) { - val matcher = - when (contentType) { - ContentType.Application.Json -> JsonContentTypeMatcher - else -> defaultMatcher(contentType) - } - register(contentType, converter, matcher, configuration) - } - - private fun register( - contentTypeToSend: ContentType, - converter: T, - contentTypeMatcher: ContentTypeMatcher, - configuration: T.() -> Unit - ) { - val registration = - ConverterRegistration( - converter.apply(configuration), - contentTypeToSend, - contentTypeMatcher - ) - registrations.add(registration) - } - - private fun defaultMatcher(pattern: ContentType): ContentTypeMatcher = - object : ContentTypeMatcher { - override fun contains(contentType: ContentType): Boolean = contentType.match(pattern) - } - } - - private val log = ExpediaGroupLoggerFactory.getLogger(this::class.java) - - internal suspend fun convertRequest( - request: HttpRequestBuilder, - body: Any - ): Any? { - if (body is OutgoingContent || ignoredTypes.any { it.isInstance(body) }) { - log.trace( - "Body type ${body::class} is in ignored types. " + - "Skipping ContentNegotiation for ${request.url}." - ) - return null - } - val contentType = - request.contentType() ?: run { - log.trace("Request doesn't have Content-Type header. Skipping ContentNegotiation for ${request.url}.") - return null - } - - if (body is Unit) { - log.trace("Sending empty body for ${request.url}") - request.headers.remove(HttpHeaders.ContentType) - return EmptyContent - } - - val matchingRegistrations = - registrations.filter { it.contentTypeMatcher.contains(contentType) } - .takeIf { it.isNotEmpty() } ?: run { - log.trace( - "None of the registered converters match request Content-Type=$contentType. " + - "Skipping ContentNegotiation for ${request.url}." - ) - return null - } - if (request.bodyType == null) { - log.trace("Request has unknown body type. Skipping ContentNegotiation for ${request.url}.") - return null - } - request.headers.remove(HttpHeaders.ContentType) - - // Pick the first one that can convert the subject successfully - val serializedContent = - matchingRegistrations.firstNotNullOfOrNull { registration -> - val result = - registration.converter.serializeNullable( - contentType, - contentType.charset() ?: Charsets.UTF_8, - request.bodyType!!, - body.takeIf { it != NullBody } - ) - if (result != null) { - log.trace("Converted request body using ${registration.converter} for ${request.url}") - } - result - } ?: throw ContentConverterException( - "Can't convert $body with contentType $contentType using converters " + - matchingRegistrations.joinToString { it.converter.toString() } - ) - - return serializedContent - } - - @OptIn(InternalAPI::class) - internal suspend fun convertResponse( - requestUrl: Url, - info: TypeInfo, - body: Any, - responseContentType: ContentType, - charset: Charset = Charsets.UTF_8 - ): Any? { - if (body !is ByteReadChannel) { - log.trace("Response body is already transformed. Skipping ContentNegotiation for $requestUrl.") - return null - } - if (info.type in ignoredTypes) { - log.trace( - "Response body type ${info.type} is in ignored types. " + - "Skipping ContentNegotiation for $requestUrl." - ) - return null - } - - log.debug("Test: ${registrations.size}") - val suitableConverters = - registrations - .filter { it.contentTypeMatcher.contains(responseContentType) } - .map { it.converter } - .takeIf { it.isNotEmpty() } - ?: run { - log.trace( - "None of the registered converters match response with Content-Type=$responseContentType. " + - "Skipping ContentNegotiation for $requestUrl." - ) - return null - } - - val result = suitableConverters.deserialize(body, info, charset) - if (result !is ByteReadChannel) { - log.trace("Response body was converted to ${result::class} for $requestUrl.") - } - return result - } - - companion object Plugin : HttpClientPlugin { - override val key: AttributeKey = AttributeKey("ContentNegotiation") - private val log = ExpediaGroupLoggerFactory.getLogger(this::class.java) - - override fun install( - plugin: ContentNegotiation, - scope: HttpClient - ) { - scope.requestPipeline.intercept(HttpRequestPipeline.Transform) { - val result = plugin.convertRequest(context, subject) ?: return@intercept - proceedWith(result) - } - - scope.responsePipeline.intercept(HttpResponsePipeline.Transform) { (info, body) -> - val contentType = - context.response.contentType() ?: run { - log.trace("Response doesn't have \"Content-Type\" header, skipping ContentNegotiation plugin") - return@intercept - } - val charset = context.request.headers.suitableCharset() - - val deserializedBody = - plugin.convertResponse(context.request.url, info, body, contentType, charset) - ?: return@intercept - val result = HttpResponseContainer(info, deserializedBody) - proceedWith(result) - } - } - - override fun prepare(block: Config.() -> Unit): ContentNegotiation { - val config = Config().apply(block) - return ContentNegotiation(config.registrations, config.ignoredTypes) - } - } -} diff --git a/code/src/main/kotlin/com/expediagroup/sdk/xap/models/FlightDetailsOffer.kt b/code/src/main/kotlin/com/expediagroup/sdk/xap/models/FlightDetailsOffer.kt index 00908a9fb..00530587e 100644 --- a/code/src/main/kotlin/com/expediagroup/sdk/xap/models/FlightDetailsOffer.kt +++ b/code/src/main/kotlin/com/expediagroup/sdk/xap/models/FlightDetailsOffer.kt @@ -43,7 +43,6 @@ import javax.validation.constraints.NotNull /** * Contains list of all the available alternate fare upsell/downsell offers. - * @param offerToken Unique key to identify each offer. * @param splitTicket True if more that one ticket will be issued for this offer per passenger. False if only one ticket will be issued per passenger. * @param opaqueFlight Indicate whether the air product is a opaque flight product or not. If true, then there will be no Segments node for this air product. * @param merchantName All Merchant name appending them together with a ?*? @@ -55,6 +54,7 @@ import javax.validation.constraints.NotNull * @param fareOptions Contains list of fare options * @param undisclosedGenderSupported Whether to support undisclosed gender? True = support False = not support * @param unspecifiedGenderSupported Whether to support unspecified gender? True = support False = not support + * @param offerToken Unique key to identify each offer. * @param referenceId Key that allows the user to create a package using this flight. * @param metaApiBook To indicate meta partners whether the air product is available for TAAS instant book. * @param free24HourCancellation True if Booking can be cancelled within 24 hours of booking. @@ -63,11 +63,6 @@ import javax.validation.constraints.NotNull * @param refundPenalty Contains refund penalty information */ data class FlightDetailsOffer( - // Unique key to identify each offer. - @JsonProperty("offerToken") - @field:NotNull - @field:Valid - val offerToken: kotlin.String, // True if more that one ticket will be issued for this offer per passenger. False if only one ticket will be issued per passenger. @JsonProperty("SplitTicket") @field:NotNull @@ -125,6 +120,10 @@ data class FlightDetailsOffer( @field:NotNull @field:Valid val unspecifiedGenderSupported: kotlin.Boolean, + // Unique key to identify each offer. + @JsonProperty("offerToken") + @field:Valid + val offerToken: kotlin.String? = null, // Key that allows the user to create a package using this flight. @JsonProperty("ReferenceId") @field:Valid @@ -156,7 +155,6 @@ data class FlightDetailsOffer( } class Builder( - private var offerToken: kotlin.String? = null, private var splitTicket: kotlin.Boolean? = null, private var opaqueFlight: kotlin.Boolean? = null, private var merchantName: kotlin.String? = null, @@ -168,6 +166,7 @@ data class FlightDetailsOffer( private var fareOptions: kotlin.collections.List? = null, private var undisclosedGenderSupported: kotlin.Boolean? = null, private var unspecifiedGenderSupported: kotlin.Boolean? = null, + private var offerToken: kotlin.String? = null, private var referenceId: kotlin.String? = null, private var metaApiBook: kotlin.Boolean? = null, private var free24HourCancellation: kotlin.Boolean? = null, @@ -175,8 +174,6 @@ data class FlightDetailsOffer( private var vfopKey: kotlin.String? = null, private var refundPenalty: kotlin.collections.List? = null ) { - fun offerToken(offerToken: kotlin.String) = apply { this.offerToken = offerToken } - fun splitTicket(splitTicket: kotlin.Boolean) = apply { this.splitTicket = splitTicket } fun opaqueFlight(opaqueFlight: kotlin.Boolean) = apply { this.opaqueFlight = opaqueFlight } @@ -199,6 +196,8 @@ data class FlightDetailsOffer( fun unspecifiedGenderSupported(unspecifiedGenderSupported: kotlin.Boolean) = apply { this.unspecifiedGenderSupported = unspecifiedGenderSupported } + fun offerToken(offerToken: kotlin.String?) = apply { this.offerToken = offerToken } + fun referenceId(referenceId: kotlin.String?) = apply { this.referenceId = referenceId } fun metaApiBook(metaApiBook: kotlin.Boolean?) = apply { this.metaApiBook = metaApiBook } @@ -214,7 +213,6 @@ data class FlightDetailsOffer( fun build(): FlightDetailsOffer { val instance = FlightDetailsOffer( - offerToken = offerToken!!, splitTicket = splitTicket!!, opaqueFlight = opaqueFlight!!, merchantName = merchantName!!, @@ -226,6 +224,7 @@ data class FlightDetailsOffer( fareOptions = fareOptions!!, undisclosedGenderSupported = undisclosedGenderSupported!!, unspecifiedGenderSupported = unspecifiedGenderSupported!!, + offerToken = offerToken, referenceId = referenceId, metaApiBook = metaApiBook, free24HourCancellation = free24HourCancellation, @@ -260,7 +259,6 @@ data class FlightDetailsOffer( fun toBuilder() = Builder( - offerToken = offerToken!!, splitTicket = splitTicket!!, opaqueFlight = opaqueFlight!!, merchantName = merchantName!!, @@ -272,6 +270,7 @@ data class FlightDetailsOffer( fareOptions = fareOptions!!, undisclosedGenderSupported = undisclosedGenderSupported!!, unspecifiedGenderSupported = unspecifiedGenderSupported!!, + offerToken = offerToken, referenceId = referenceId, metaApiBook = metaApiBook, free24HourCancellation = free24HourCancellation, diff --git a/code/src/main/kotlin/com/expediagroup/sdk/xap/models/GetFlightListingsOperationSegmentParam.kt b/code/src/main/kotlin/com/expediagroup/sdk/xap/models/GetFlightListingsOperationSegmentParam.kt new file mode 100644 index 000000000..1003e11a6 --- /dev/null +++ b/code/src/main/kotlin/com/expediagroup/sdk/xap/models/GetFlightListingsOperationSegmentParam.kt @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2022 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.expediagroup.sdk.xap.models + +data class GetFlightListingsOperationSegmentParam( + val origin: String, + val destination: String, + val departureDate: java.time.LocalDate, + val departureStartTime: String?, + val departureEndTime: String? +) { + companion object { + @JvmStatic + fun builder() = Builder() + } + + class Builder( + private var origin: String? = null, + private var destination: String? = null, + private var departureDate: java.time.LocalDate? = null, + private var departureStartTime: String? = null, + private var departureEndTime: String? = null + ) { + fun origin(origin: String?) = apply { this.origin = origin } + + fun destination(destination: String?) = apply { this.destination = destination } + + fun departureDate(departureDate: java.time.LocalDate?) = apply { this.departureDate = departureDate } + + fun departureStartTime(departureStartTime: String?) = apply { this.departureStartTime = departureStartTime } + + fun departureEndTime(departureEndTime: String?) = apply { this.departureEndTime = departureEndTime } + + fun build(): GetFlightListingsOperationSegmentParam = + GetFlightListingsOperationSegmentParam( + origin = this.origin!!, + destination = this.destination!!, + departureDate = this.departureDate!!, + departureStartTime = this.departureStartTime, + departureEndTime = this.departureEndTime + ) + } +} diff --git a/code/src/main/kotlin/com/expediagroup/sdk/xap/operations/GetFlightListingsOperationParams.kt b/code/src/main/kotlin/com/expediagroup/sdk/xap/operations/GetFlightListingsOperationParams.kt index fd25f840e..a2654c600 100644 --- a/code/src/main/kotlin/com/expediagroup/sdk/xap/operations/GetFlightListingsOperationParams.kt +++ b/code/src/main/kotlin/com/expediagroup/sdk/xap/operations/GetFlightListingsOperationParams.kt @@ -18,6 +18,7 @@ package com.expediagroup.sdk.xap.operations import com.expediagroup.sdk.core.model.OperationParams import com.expediagroup.sdk.core.model.exception.client.PropertyConstraintViolationException import com.expediagroup.sdk.xap.infrastructure.* +import com.expediagroup.sdk.xap.models.GetFlightListingsOperationSegmentParam import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.databind.annotation.JsonDeserialize import io.ktor.http.Headers @@ -375,156 +376,6 @@ data class GetFlightListingsOperationParams( */ fun infantInSeat(infantInSeat: kotlin.Int) = apply { this.infantInSeat = infantInSeat } - /** - * @param segment1Origin 3-letter IATA Airport code/Location name from where the passenger is departing. - */ - fun segment1Origin(segment1Origin: kotlin.String) = apply { this.segment1Origin = segment1Origin } - - /** - * @param segment1Destination 3-letter IATA Airport code/Location name from where the passenger is arriving. - */ - fun segment1Destination(segment1Destination: kotlin.String) = apply { this.segment1Destination = segment1Destination } - - /** - * @param segment1DepartureDate Date, in ISO format [YYYY-MM-DD], on which customer wants to depart. - */ - fun segment1DepartureDate(segment1DepartureDate: java.time.LocalDate) = apply { this.segment1DepartureDate = segment1DepartureDate } - - /** - * @param segment1DepartureStartTime Lower limit of desired departure time window, expressed in the local time of the departure location, in standard ISO format. - */ - fun segment1DepartureStartTime(segment1DepartureStartTime: kotlin.String) = apply { this.segment1DepartureStartTime = segment1DepartureStartTime } - - /** - * @param segment1DepartureEndTime Upper limit of desired departure time window, expressed in the local time of the departure location, in standard ISO format. - */ - fun segment1DepartureEndTime(segment1DepartureEndTime: kotlin.String) = apply { this.segment1DepartureEndTime = segment1DepartureEndTime } - - /** - * @param segment2Origin 3-letter IATA Airport code/Location name from where the passenger is departing. - */ - fun segment2Origin(segment2Origin: kotlin.String) = apply { this.segment2Origin = segment2Origin } - - /** - * @param segment2Destination 3-letter IATA Airport code/Location name from where the passenger is arriving. - */ - fun segment2Destination(segment2Destination: kotlin.String) = apply { this.segment2Destination = segment2Destination } - - /** - * @param segment2DepartureDate Date, in ISO format [YYYY-MM-DD], on which customer wants to depart. - */ - fun segment2DepartureDate(segment2DepartureDate: java.time.LocalDate) = apply { this.segment2DepartureDate = segment2DepartureDate } - - /** - * @param segment2DepartureStartTime Lower limit of desired departure time window, expressed in the local time of the departure location, in standard ISO format. - */ - fun segment2DepartureStartTime(segment2DepartureStartTime: kotlin.String) = apply { this.segment2DepartureStartTime = segment2DepartureStartTime } - - /** - * @param segment2DepartureEndTime Upper limit of desired departure time window, expressed in the local time of the departure location, in standard ISO format. - */ - fun segment2DepartureEndTime(segment2DepartureEndTime: kotlin.String) = apply { this.segment2DepartureEndTime = segment2DepartureEndTime } - - /** - * @param segment3Origin 3-letter IATA Airport code/Location name from where the passenger is departing. - */ - fun segment3Origin(segment3Origin: kotlin.String) = apply { this.segment3Origin = segment3Origin } - - /** - * @param segment3Destination 3-letter IATA Airport code/Location name from where the passenger is arriving. - */ - fun segment3Destination(segment3Destination: kotlin.String) = apply { this.segment3Destination = segment3Destination } - - /** - * @param segment3DepartureDate Date, in ISO format [YYYY-MM-DD], on which customer wants to depart. - */ - fun segment3DepartureDate(segment3DepartureDate: java.time.LocalDate) = apply { this.segment3DepartureDate = segment3DepartureDate } - - /** - * @param segment3DepartureStartTime Lower limit of desired departure time window, expressed in the local time of the departure location, in standard ISO format. - */ - fun segment3DepartureStartTime(segment3DepartureStartTime: kotlin.String) = apply { this.segment3DepartureStartTime = segment3DepartureStartTime } - - /** - * @param segment3DepartureEndTime Upper limit of desired departure time window, expressed in the local time of the departure location, in standard ISO format. - */ - fun segment3DepartureEndTime(segment3DepartureEndTime: kotlin.String) = apply { this.segment3DepartureEndTime = segment3DepartureEndTime } - - /** - * @param segment4Origin 3-letter IATA Airport code/Location name from where the passenger is departing. - */ - fun segment4Origin(segment4Origin: kotlin.String) = apply { this.segment4Origin = segment4Origin } - - /** - * @param segment4Destination 3-letter IATA Airport code/Location name from where the passenger is arriving. - */ - fun segment4Destination(segment4Destination: kotlin.String) = apply { this.segment4Destination = segment4Destination } - - /** - * @param segment4DepartureDate Date, in ISO format [YYYY-MM-DD], on which customer wants to depart. - */ - fun segment4DepartureDate(segment4DepartureDate: java.time.LocalDate) = apply { this.segment4DepartureDate = segment4DepartureDate } - - /** - * @param segment4DepartureStartTime Lower limit of desired departure time window, expressed in the local time of the departure location, in standard ISO format. - */ - fun segment4DepartureStartTime(segment4DepartureStartTime: kotlin.String) = apply { this.segment4DepartureStartTime = segment4DepartureStartTime } - - /** - * @param segment4DepartureEndTime Upper limit of desired departure time window, expressed in the local time of the departure location, in standard ISO format. - */ - fun segment4DepartureEndTime(segment4DepartureEndTime: kotlin.String) = apply { this.segment4DepartureEndTime = segment4DepartureEndTime } - - /** - * @param segment5Origin 3-letter IATA Airport code/Location name from where the passenger is departing. - */ - fun segment5Origin(segment5Origin: kotlin.String) = apply { this.segment5Origin = segment5Origin } - - /** - * @param segment5Destination 3-letter IATA Airport code/Location name from where the passenger is arriving. - */ - fun segment5Destination(segment5Destination: kotlin.String) = apply { this.segment5Destination = segment5Destination } - - /** - * @param segment5DepartureDate Date, in ISO format [YYYY-MM-DD], on which customer wants to depart. - */ - fun segment5DepartureDate(segment5DepartureDate: java.time.LocalDate) = apply { this.segment5DepartureDate = segment5DepartureDate } - - /** - * @param segment5DepartureStartTime Lower limit of desired departure time window, expressed in the local time of the departure location, in standard ISO format. - */ - fun segment5DepartureStartTime(segment5DepartureStartTime: kotlin.String) = apply { this.segment5DepartureStartTime = segment5DepartureStartTime } - - /** - * @param segment5DepartureEndTime Upper limit of desired departure time window, expressed in the local time of the departure location, in standard ISO format. - */ - fun segment5DepartureEndTime(segment5DepartureEndTime: kotlin.String) = apply { this.segment5DepartureEndTime = segment5DepartureEndTime } - - /** - * @param segment6Origin 3-letter IATA Airport code/Location name from where the passenger is departing. - */ - fun segment6Origin(segment6Origin: kotlin.String) = apply { this.segment6Origin = segment6Origin } - - /** - * @param segment6Destination 3-letter IATA Airport code/Location name from where the passenger is arriving. - */ - fun segment6Destination(segment6Destination: kotlin.String) = apply { this.segment6Destination = segment6Destination } - - /** - * @param segment6DepartureDate Date, in ISO format [YYYY-MM-DD], on which customer wants to depart. - */ - fun segment6DepartureDate(segment6DepartureDate: java.time.LocalDate) = apply { this.segment6DepartureDate = segment6DepartureDate } - - /** - * @param segment6DepartureStartTime Lower limit of desired departure time window, expressed in the local time of the departure location, in standard ISO format. - */ - fun segment6DepartureStartTime(segment6DepartureStartTime: kotlin.String) = apply { this.segment6DepartureStartTime = segment6DepartureStartTime } - - /** - * @param segment6DepartureEndTime Upper limit of desired departure time window, expressed in the local time of the departure location, in standard ISO format. - */ - fun segment6DepartureEndTime(segment6DepartureEndTime: kotlin.String) = apply { this.segment6DepartureEndTime = segment6DepartureEndTime } - /** * @param locale Indicates the language and country with which the user would like to see any translated information. */ @@ -617,6 +468,60 @@ data class GetFlightListingsOperationParams( */ fun enableSplitTicket(enableSplitTicket: kotlin.Boolean) = apply { this.enableSplitTicket = enableSplitTicket } + fun segment1(segment: GetFlightListingsOperationSegmentParam) = + apply { + this.segment1Origin = segment.origin + this.segment1Destination = segment.destination + this.segment1DepartureDate = segment.departureDate + this.segment1DepartureStartTime = segment.departureStartTime + this.segment1DepartureEndTime = segment.departureEndTime + } + + fun segment2(segment: GetFlightListingsOperationSegmentParam) = + apply { + this.segment2Origin = segment.origin + this.segment2Destination = segment.destination + this.segment2DepartureDate = segment.departureDate + this.segment2DepartureStartTime = segment.departureStartTime + this.segment2DepartureEndTime = segment.departureEndTime + } + + fun segment3(segment: GetFlightListingsOperationSegmentParam) = + apply { + this.segment3Origin = segment.origin + this.segment3Destination = segment.destination + this.segment3DepartureDate = segment.departureDate + this.segment3DepartureStartTime = segment.departureStartTime + this.segment3DepartureEndTime = segment.departureEndTime + } + + fun segment4(segment: GetFlightListingsOperationSegmentParam) = + apply { + this.segment4Origin = segment.origin + this.segment4Destination = segment.destination + this.segment4DepartureDate = segment.departureDate + this.segment4DepartureStartTime = segment.departureStartTime + this.segment4DepartureEndTime = segment.departureEndTime + } + + fun segment5(segment: GetFlightListingsOperationSegmentParam) = + apply { + this.segment5Origin = segment.origin + this.segment5Destination = segment.destination + this.segment5DepartureDate = segment.departureDate + this.segment5DepartureStartTime = segment.departureStartTime + this.segment5DepartureEndTime = segment.departureEndTime + } + + fun segment6(segment: GetFlightListingsOperationSegmentParam) = + apply { + this.segment6Origin = segment.origin + this.segment6Destination = segment.destination + this.segment6DepartureDate = segment.departureDate + this.segment6DepartureStartTime = segment.departureStartTime + this.segment6DepartureEndTime = segment.departureEndTime + } + fun build(): GetFlightListingsOperationParams { val params = GetFlightListingsOperationParams( diff --git a/code/transformedSpecs.yaml b/code/transformedSpecs.yaml index aabfe3196..3a2310aa1 100644 --- a/code/transformedSpecs.yaml +++ b/code/transformedSpecs.yaml @@ -10,10 +10,6 @@ info: the XAP Booking API, or both. ' - contact: - name: 'PartnerAPIs' - url: 'https://confluence.expedia.biz/display/EWS/EWSHotel' - email: 'dreamweaver@expedia.com' version: 'v3' x-eg-lifecycle: 'LIVE' x-eg-tags: @@ -14541,7 +14537,6 @@ components: - 'International' - 'Links' - 'MerchantName' - - 'offerToken' - 'FareOptions' - 'OpaqueFlight' - 'OfferPrice' diff --git a/specs/xap-flight-v3.specs.yaml b/specs/xap-flight-v3.specs.yaml index 53221ed6c..ddadae944 100644 --- a/specs/xap-flight-v3.specs.yaml +++ b/specs/xap-flight-v3.specs.yaml @@ -3811,7 +3811,6 @@ components: - International - Links - MerchantName - - offerToken - FareOptions - OpaqueFlight - OfferPrice