From dcf44cc982f67c08e5f5ebb153f9539a1db25861 Mon Sep 17 00:00:00 2001 From: Eduardo San Segundo Date: Tue, 16 Jun 2026 10:42:32 +0200 Subject: [PATCH 1/4] Voice: use SvamlControlPatch for updateCall and manageCallWithCallLeg --- .../v1/svaml/action/SvamlActionPatch.java | 9 + .../api/v1/adapters/CallsServiceTest.java | 9 +- .../sdk/e2e/domains/voice/v1/CallsSteps.java | 14 +- .../domains/voice/api/v1/CallsService.java | 10 +- .../api/v1/adapters/CallsServiceImpl.java | 25 +- .../v1/calls/request/SvamlActionPatch.java | 16 + .../calls/request/SvamlActionPatchImpl.java | 362 ++++++++++++++++++ .../v1/calls/request/SvamlControlPatch.java | 78 ++++ .../calls/request/SvamlControlPatchImpl.java | 124 ++++++ .../v1/svaml/action/SvamlActionContinue.java | 3 +- .../svaml/action/SvamlActionContinueImpl.java | 4 +- .../v1/svaml/action/SvamlActionHangup.java | 3 +- .../svaml/action/SvamlActionHangupImpl.java | 4 +- .../v1/svaml/action/SvamlActionPark.java | 3 +- .../v1/svaml/action/SvamlActionParkImpl.java | 4 +- .../v1/svaml/SvamlControlPatchTest.java | 39 ++ .../voice/v1/svaml/SvamlControlPatchDto.json | 12 + 17 files changed, 685 insertions(+), 34 deletions(-) create mode 100644 client/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionPatch.java create mode 100644 openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlActionPatch.java create mode 100644 openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlActionPatchImpl.java create mode 100644 openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlControlPatch.java create mode 100644 openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlControlPatchImpl.java create mode 100644 openapi-contracts/src/test/java/com/sinch/sdk/domains/voice/models/v1/svaml/SvamlControlPatchTest.java create mode 100644 openapi-contracts/src/test/resources/domains/voice/v1/svaml/SvamlControlPatchDto.json diff --git a/client/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionPatch.java b/client/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionPatch.java new file mode 100644 index 000000000..aac08730d --- /dev/null +++ b/client/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionPatch.java @@ -0,0 +1,9 @@ +package com.sinch.sdk.domains.voice.models.v1.svaml.action; + +/** + * Base class related to SVAML actions available for PATCH call operations (updateCall and + * manageCallWithCallLeg). Only hangup, continue and park actions are supported. + * + * @since 2.1 + */ +public interface SvamlActionPatch {} diff --git a/client/src/test/java/com/sinch/sdk/domains/voice/api/v1/adapters/CallsServiceTest.java b/client/src/test/java/com/sinch/sdk/domains/voice/api/v1/adapters/CallsServiceTest.java index 3d158a320..1253b9881 100644 --- a/client/src/test/java/com/sinch/sdk/domains/voice/api/v1/adapters/CallsServiceTest.java +++ b/client/src/test/java/com/sinch/sdk/domains/voice/api/v1/adapters/CallsServiceTest.java @@ -23,7 +23,7 @@ import com.sinch.sdk.domains.voice.models.v1.calls.CallInformationTest; import com.sinch.sdk.domains.voice.models.v1.calls.request.CallLeg; import com.sinch.sdk.domains.voice.models.v1.calls.response.CallInformation; -import com.sinch.sdk.domains.voice.models.v1.svaml.SvamlControlTest; +import com.sinch.sdk.domains.voice.models.v1.svaml.SvamlControlPatchTest; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -38,7 +38,7 @@ public class CallsServiceTest extends BaseTest { @GivenTextResource("/domains/voice/v1/calls/GetCallInformationResponseDto.json") String getCallInformationResponseDto; - @GivenTextResource("/domains/voice/v1/svaml/SvamlControlDto.json") + @GivenTextResource("/domains/voice/v1/svaml/SvamlControlPatchDto.json") String svamlControlDto; static final Collection AUTH_NAMES = Arrays.asList("Basic", "Signed"); @@ -108,7 +108,7 @@ void update() throws ApiException { argThat(new HttpRequestMatcher(httpRequest)))) .thenReturn(httpResponse); - service.update("call/id", SvamlControlTest.expectedSvamlControl); + service.update("call/id", SvamlControlPatchTest.expectedSvamlControlPatch); } @Test @@ -132,6 +132,7 @@ void manageWithCallLeg() throws ApiException { argThat(new HttpRequestMatcher(httpRequest)))) .thenReturn(httpResponse); - service.manageWithCallLeg("call/id", CallLeg.BOTH, SvamlControlTest.expectedSvamlControl); + service.manageWithCallLeg( + "call/id", CallLeg.BOTH, SvamlControlPatchTest.expectedSvamlControlPatch); } } diff --git a/client/src/test/java/com/sinch/sdk/e2e/domains/voice/v1/CallsSteps.java b/client/src/test/java/com/sinch/sdk/e2e/domains/voice/v1/CallsSteps.java index 6e32a5dbf..34a1452f6 100644 --- a/client/src/test/java/com/sinch/sdk/e2e/domains/voice/v1/CallsSteps.java +++ b/client/src/test/java/com/sinch/sdk/e2e/domains/voice/v1/CallsSteps.java @@ -5,13 +5,13 @@ import com.sinch.sdk.domains.voice.api.v1.CallsService; import com.sinch.sdk.domains.voice.models.v1.Price; import com.sinch.sdk.domains.voice.models.v1.calls.request.CallLeg; +import com.sinch.sdk.domains.voice.models.v1.calls.request.SvamlControlPatch; import com.sinch.sdk.domains.voice.models.v1.calls.response.CallInformation; import com.sinch.sdk.domains.voice.models.v1.calls.response.CallInformation.DomainEnum; import com.sinch.sdk.domains.voice.models.v1.calls.response.CallInformation.ReasonEnum; import com.sinch.sdk.domains.voice.models.v1.calls.response.CallInformation.StatusEnum; import com.sinch.sdk.domains.voice.models.v1.calls.response.CallResult; import com.sinch.sdk.domains.voice.models.v1.destination.DestinationPstn; -import com.sinch.sdk.domains.voice.models.v1.svaml.SvamlControl; import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionContinue; import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionHangup; import com.sinch.sdk.domains.voice.models.v1.svaml.instruction.SvamlInstructionPlayFiles; @@ -46,8 +46,8 @@ public void getCall() { @When("^I send a request to update a call$") public void updateCall() { - SvamlControl request = - SvamlControl.builder() + SvamlControlPatch request = + SvamlControlPatch.builder() .setInstructions( Arrays.asList( SvamlInstructionSay.builder() @@ -63,8 +63,8 @@ public void updateCall() { @When("^I send a request to update a call that doesn't exist$") public void updateCallNotExits() { - SvamlControl request = - SvamlControl.builder() + SvamlControlPatch request = + SvamlControlPatch.builder() .setInstructions( Arrays.asList( SvamlInstructionSay.builder() @@ -83,8 +83,8 @@ public void updateCallNotExits() { @When("^I send a request to manage a call with callLeg$") public void manageCallWithCallLeg() { - SvamlControl request = - SvamlControl.builder() + SvamlControlPatch request = + SvamlControlPatch.builder() .setInstructions( Arrays.asList( SvamlInstructionPlayFiles.builder() diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/api/v1/CallsService.java b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/api/v1/CallsService.java index 6aa50ceb5..28f0b209b 100644 --- a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/api/v1/CallsService.java +++ b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/api/v1/CallsService.java @@ -12,8 +12,8 @@ import com.sinch.sdk.core.exceptions.ApiException; import com.sinch.sdk.domains.voice.models.v1.calls.request.CallLeg; +import com.sinch.sdk.domains.voice.models.v1.calls.request.SvamlControlPatch; import com.sinch.sdk.domains.voice.models.v1.calls.response.CallInformation; -import com.sinch.sdk.domains.voice.models.v1.svaml.SvamlControl; /** Calls Service */ public interface CallsService { @@ -53,10 +53,10 @@ public interface CallsService { * `caller`.<br><Warning>The `callLeg` identifier is ignored * for calls that are part of a conference and calls initiated using the Callout * API.</Warning> (required) - * @param svamlControl (optional) + * @param svamlControlPatch (optional) * @throws ApiException if fails to make API call */ - void manageWithCallLeg(String callId, CallLeg callLeg, SvamlControl svamlControl) + void manageWithCallLeg(String callId, CallLeg callLeg, SvamlControlPatch svamlControlPatch) throws ApiException; /** @@ -70,8 +70,8 @@ void manageWithCallLeg(String callId, CallLeg callLeg, SvamlControl svamlControl * * @param callId The unique identifier of the call. This value is generated by the system. * (required) - * @param svamlControl (optional) + * @param svamlControlPatch (optional) * @throws ApiException if fails to make API call */ - void update(String callId, SvamlControl svamlControl) throws ApiException; + void update(String callId, SvamlControlPatch svamlControlPatch) throws ApiException; } diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/api/v1/adapters/CallsServiceImpl.java b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/api/v1/adapters/CallsServiceImpl.java index afd380188..1c146f8b0 100644 --- a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/api/v1/adapters/CallsServiceImpl.java +++ b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/api/v1/adapters/CallsServiceImpl.java @@ -24,8 +24,8 @@ import com.sinch.sdk.core.http.URLPathUtils; import com.sinch.sdk.core.models.ServerConfiguration; import com.sinch.sdk.domains.voice.models.v1.calls.request.CallLeg; +import com.sinch.sdk.domains.voice.models.v1.calls.request.SvamlControlPatch; import com.sinch.sdk.domains.voice.models.v1.calls.response.CallInformation; -import com.sinch.sdk.domains.voice.models.v1.svaml.SvamlControl; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -109,7 +109,7 @@ private HttpRequest getRequestBuilder(String callId) throws ApiException { } @Override - public void manageWithCallLeg(String callId, CallLeg callLeg, SvamlControl svamlControl) + public void manageWithCallLeg(String callId, CallLeg callLeg, SvamlControlPatch svamlControlPatch) throws ApiException { LOGGER.finest( @@ -121,10 +121,10 @@ public void manageWithCallLeg(String callId, CallLeg callLeg, SvamlControl svaml + "callLeg: " + callLeg + ", " - + "svamlControl: " - + svamlControl); + + "svamlControlPatch: " + + svamlControlPatch); - HttpRequest httpRequest = manageWithCallLegRequestBuilder(callId, callLeg, svamlControl); + HttpRequest httpRequest = manageWithCallLegRequestBuilder(callId, callLeg, svamlControlPatch); HttpResponse response = httpClient.invokeAPI( this.serverConfiguration, this.authManagersByOasSecuritySchemes, httpRequest); @@ -142,7 +142,7 @@ public void manageWithCallLeg(String callId, CallLeg callLeg, SvamlControl svaml } private HttpRequest manageWithCallLegRequestBuilder( - String callId, CallLeg callLeg, SvamlControl svamlControl) throws ApiException { + String callId, CallLeg callLeg, SvamlControlPatch svamlControlPatch) throws ApiException { // verify the required parameter 'callId' is set if (callId == null) { throw new ApiException( @@ -169,7 +169,7 @@ private HttpRequest manageWithCallLegRequestBuilder( final Collection localVarContentTypes = Arrays.asList("application/json"); final Collection localVarAuthNames = Arrays.asList("Basic", "Signed"); - final String serializedBody = mapper.serialize(localVarContentTypes, svamlControl); + final String serializedBody = mapper.serialize(localVarContentTypes, svamlControlPatch); return new HttpRequest( localVarPath, @@ -183,11 +183,12 @@ private HttpRequest manageWithCallLegRequestBuilder( } @Override - public void update(String callId, SvamlControl svamlControl) throws ApiException { + public void update(String callId, SvamlControlPatch svamlControlPatch) throws ApiException { - LOGGER.finest("[update]" + " " + "callId: " + callId + ", " + "svamlControl: " + svamlControl); + LOGGER.finest( + "[update]" + " " + "callId: " + callId + ", " + "svamlControlPatch: " + svamlControlPatch); - HttpRequest httpRequest = updateRequestBuilder(callId, svamlControl); + HttpRequest httpRequest = updateRequestBuilder(callId, svamlControlPatch); HttpResponse response = httpClient.invokeAPI( this.serverConfiguration, this.authManagersByOasSecuritySchemes, httpRequest); @@ -204,7 +205,7 @@ public void update(String callId, SvamlControl svamlControl) throws ApiException mapper.deserialize(response, new TypeReference>() {})); } - private HttpRequest updateRequestBuilder(String callId, SvamlControl svamlControl) + private HttpRequest updateRequestBuilder(String callId, SvamlControlPatch svamlControlPatch) throws ApiException { // verify the required parameter 'callId' is set if (callId == null) { @@ -225,7 +226,7 @@ private HttpRequest updateRequestBuilder(String callId, SvamlControl svamlContro final Collection localVarContentTypes = Arrays.asList("application/json"); final Collection localVarAuthNames = Arrays.asList("Basic", "Signed"); - final String serializedBody = mapper.serialize(localVarContentTypes, svamlControl); + final String serializedBody = mapper.serialize(localVarContentTypes, svamlControlPatch); return new HttpRequest( localVarPath, diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlActionPatch.java b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlActionPatch.java new file mode 100644 index 000000000..c618d66f4 --- /dev/null +++ b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlActionPatch.java @@ -0,0 +1,16 @@ +/* + * Voice API | Sinch + * + * OpenAPI document version: 1.0.1 + * Contact: support@sinch.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit the class manually. + */ + +package com.sinch.sdk.domains.voice.models.v1.calls.request; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +@JsonDeserialize(using = SvamlActionPatchImpl.SvamlActionPatchImplDeserializer.class) +public interface SvamlActionPatch {} diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlActionPatchImpl.java b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlActionPatchImpl.java new file mode 100644 index 000000000..98f6e10bf --- /dev/null +++ b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlActionPatchImpl.java @@ -0,0 +1,362 @@ +package com.sinch.sdk.domains.voice.models.v1.calls.request; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import com.sinch.sdk.core.models.AbstractOpenApiSchema; +import com.sinch.sdk.core.utils.databind.JSONNavigator; +import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionContinueImpl; +import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionHangupImpl; +import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionParkImpl; +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +@JsonDeserialize(using = SvamlActionPatchImpl.SvamlActionPatchImplDeserializer.class) +@JsonSerialize(using = SvamlActionPatchImpl.SvamlActionPatchImplSerializer.class) +public class SvamlActionPatchImpl extends AbstractOpenApiSchema implements SvamlActionPatch { + private static final Logger log = Logger.getLogger(SvamlActionPatchImpl.class.getName()); + + public static final class SvamlActionPatchImplSerializer + extends StdSerializer { + private static final long serialVersionUID = 1L; + + public SvamlActionPatchImplSerializer(Class t) { + super(t); + } + + public SvamlActionPatchImplSerializer() { + this(null); + } + + @Override + public void serialize( + SvamlActionPatchImpl value, JsonGenerator jgen, SerializerProvider provider) + throws IOException, JsonProcessingException { + jgen.writeObject(value.getActualInstance()); + } + } + + public static final class SvamlActionPatchImplDeserializer + extends StdDeserializer { + + private static final long serialVersionUID = 1L; + + public SvamlActionPatchImplDeserializer() { + this(SvamlActionPatchImpl.class); + } + + public SvamlActionPatchImplDeserializer(Class vc) { + super(vc); + } + + @Override + public SvamlActionPatchImpl deserialize(JsonParser jp, DeserializationContext ctxt) + throws IOException, JsonProcessingException { + JsonNode tree = jp.readValueAsTree(); + Object deserialized = null; + SvamlActionPatchImpl newSvamlActionPatchImpl = new SvamlActionPatchImpl(); + Map result2 = + tree.traverse(jp.getCodec()).readValueAs(new TypeReference>() {}); + String discriminatorValue = (String) result2.get("name"); + switch (discriminatorValue) { + case "continue": + deserialized = tree.traverse(jp.getCodec()).readValueAs(SvamlActionContinueImpl.class); + newSvamlActionPatchImpl.setActualInstance(deserialized); + return newSvamlActionPatchImpl; + case "hangup": + deserialized = tree.traverse(jp.getCodec()).readValueAs(SvamlActionHangupImpl.class); + newSvamlActionPatchImpl.setActualInstance(deserialized); + return newSvamlActionPatchImpl; + case "park": + deserialized = tree.traverse(jp.getCodec()).readValueAs(SvamlActionParkImpl.class); + newSvamlActionPatchImpl.setActualInstance(deserialized); + return newSvamlActionPatchImpl; + default: + log.log( + Level.WARNING, + String.format( + "Failed to lookup discriminator value `%s` for SvamlActionPatchImpl. Possible" + + " values: continue hangup park", + discriminatorValue)); + } + + boolean typeCoercion = ctxt.isEnabled(MapperFeature.ALLOW_COERCION_OF_SCALARS); + int match = 0; + JsonToken token = tree.traverse(jp.getCodec()).nextToken(); + // deserialize SvamlActionContinueImpl + try { + boolean attemptParsing = true; + // ensure that we respect type coercion as set on the client ObjectMapper + if (SvamlActionContinueImpl.class.equals(Integer.class) + || SvamlActionContinueImpl.class.equals(Long.class) + || SvamlActionContinueImpl.class.equals(Float.class) + || SvamlActionContinueImpl.class.equals(Double.class) + || SvamlActionContinueImpl.class.equals(Boolean.class) + || SvamlActionContinueImpl.class.equals(String.class)) { + attemptParsing = typeCoercion; + if (!attemptParsing) { + attemptParsing |= + ((SvamlActionContinueImpl.class.equals(Integer.class) + || SvamlActionContinueImpl.class.equals(Long.class)) + && token == JsonToken.VALUE_NUMBER_INT); + attemptParsing |= + ((SvamlActionContinueImpl.class.equals(Float.class) + || SvamlActionContinueImpl.class.equals(Double.class)) + && token == JsonToken.VALUE_NUMBER_FLOAT); + attemptParsing |= + (SvamlActionContinueImpl.class.equals(Boolean.class) + && (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE)); + attemptParsing |= + (SvamlActionContinueImpl.class.equals(String.class) + && token == JsonToken.VALUE_STRING); + } + } + if (attemptParsing) { + deserialized = tree.traverse(jp.getCodec()).readValueAs(SvamlActionContinueImpl.class); + // TODO: there is no validation against JSON schema constraints + // (min, max, enum, pattern...), this does not perform a strict JSON + // validation, which means the 'match' count may be higher than it should be. + match++; + log.log(Level.FINER, "Input data matches schema 'SvamlActionContinueImpl'"); + } + } catch (Exception e) { + // deserialization failed, continue + log.log(Level.FINER, "Input data does not match schema 'SvamlActionContinueImpl'", e); + } + + // deserialize SvamlActionHangupImpl + try { + boolean attemptParsing = true; + // ensure that we respect type coercion as set on the client ObjectMapper + if (SvamlActionHangupImpl.class.equals(Integer.class) + || SvamlActionHangupImpl.class.equals(Long.class) + || SvamlActionHangupImpl.class.equals(Float.class) + || SvamlActionHangupImpl.class.equals(Double.class) + || SvamlActionHangupImpl.class.equals(Boolean.class) + || SvamlActionHangupImpl.class.equals(String.class)) { + attemptParsing = typeCoercion; + if (!attemptParsing) { + attemptParsing |= + ((SvamlActionHangupImpl.class.equals(Integer.class) + || SvamlActionHangupImpl.class.equals(Long.class)) + && token == JsonToken.VALUE_NUMBER_INT); + attemptParsing |= + ((SvamlActionHangupImpl.class.equals(Float.class) + || SvamlActionHangupImpl.class.equals(Double.class)) + && token == JsonToken.VALUE_NUMBER_FLOAT); + attemptParsing |= + (SvamlActionHangupImpl.class.equals(Boolean.class) + && (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE)); + attemptParsing |= + (SvamlActionHangupImpl.class.equals(String.class) + && token == JsonToken.VALUE_STRING); + } + } + if (attemptParsing) { + deserialized = tree.traverse(jp.getCodec()).readValueAs(SvamlActionHangupImpl.class); + // TODO: there is no validation against JSON schema constraints + // (min, max, enum, pattern...), this does not perform a strict JSON + // validation, which means the 'match' count may be higher than it should be. + match++; + log.log(Level.FINER, "Input data matches schema 'SvamlActionHangupImpl'"); + } + } catch (Exception e) { + // deserialization failed, continue + log.log(Level.FINER, "Input data does not match schema 'SvamlActionHangupImpl'", e); + } + + // deserialize SvamlActionParkImpl + try { + boolean attemptParsing = true; + // ensure that we respect type coercion as set on the client ObjectMapper + if (SvamlActionParkImpl.class.equals(Integer.class) + || SvamlActionParkImpl.class.equals(Long.class) + || SvamlActionParkImpl.class.equals(Float.class) + || SvamlActionParkImpl.class.equals(Double.class) + || SvamlActionParkImpl.class.equals(Boolean.class) + || SvamlActionParkImpl.class.equals(String.class)) { + attemptParsing = typeCoercion; + if (!attemptParsing) { + attemptParsing |= + ((SvamlActionParkImpl.class.equals(Integer.class) + || SvamlActionParkImpl.class.equals(Long.class)) + && token == JsonToken.VALUE_NUMBER_INT); + attemptParsing |= + ((SvamlActionParkImpl.class.equals(Float.class) + || SvamlActionParkImpl.class.equals(Double.class)) + && token == JsonToken.VALUE_NUMBER_FLOAT); + attemptParsing |= + (SvamlActionParkImpl.class.equals(Boolean.class) + && (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE)); + attemptParsing |= + (SvamlActionParkImpl.class.equals(String.class) && token == JsonToken.VALUE_STRING); + } + } + if (attemptParsing) { + deserialized = tree.traverse(jp.getCodec()).readValueAs(SvamlActionParkImpl.class); + // TODO: there is no validation against JSON schema constraints + // (min, max, enum, pattern...), this does not perform a strict JSON + // validation, which means the 'match' count may be higher than it should be. + match++; + log.log(Level.FINER, "Input data matches schema 'SvamlActionParkImpl'"); + } + } catch (Exception e) { + // deserialization failed, continue + log.log(Level.FINER, "Input data does not match schema 'SvamlActionParkImpl'", e); + } + + if (match == 1) { + SvamlActionPatchImpl ret = new SvamlActionPatchImpl(); + ret.setActualInstance(deserialized); + return ret; + } + throw new IOException( + String.format( + "Failed deserialization for SvamlActionPatchImpl: %d classes match result, expected" + + " 1", + match)); + } + + /** Handle deserialization of the 'null' value. */ + @Override + public SvamlActionPatchImpl getNullValue(DeserializationContext ctxt) + throws JsonMappingException { + throw new JsonMappingException(ctxt.getParser(), "SvamlActionPatchImpl cannot be null"); + } + } + + // store a list of schema names defined in oneOf + public static final Map> schemas = new HashMap<>(); + + public SvamlActionPatchImpl() { + super("oneOf", Boolean.FALSE); + } + + public SvamlActionPatchImpl(SvamlActionContinueImpl o) { + super("oneOf", Boolean.FALSE); + setActualInstance(o); + } + + public SvamlActionPatchImpl(SvamlActionHangupImpl o) { + super("oneOf", Boolean.FALSE); + setActualInstance(o); + } + + public SvamlActionPatchImpl(SvamlActionParkImpl o) { + super("oneOf", Boolean.FALSE); + setActualInstance(o); + } + + static { + schemas.put("SvamlActionContinueImpl", SvamlActionContinueImpl.class); + schemas.put("SvamlActionHangupImpl", SvamlActionHangupImpl.class); + schemas.put("SvamlActionParkImpl", SvamlActionParkImpl.class); + JSONNavigator.registerDescendants( + SvamlActionPatchImpl.class, Collections.unmodifiableMap(schemas)); + // Initialize and register the discriminator mappings. + Map> mappings = new HashMap>(); + mappings.put("continue", SvamlActionContinueImpl.class); + mappings.put("hangup", SvamlActionHangupImpl.class); + mappings.put("park", SvamlActionParkImpl.class); + mappings.put("svaml.action.patch", SvamlActionPatchImpl.class); + JSONNavigator.registerDiscriminator(SvamlActionPatchImpl.class, "name", mappings); + } + + @Override + public Map> getSchemas() { + return SvamlActionPatchImpl.schemas; + } + + /** + * Set the instance that matches the oneOf child schema, check the instance parameter is valid + * against the oneOf child schemas: SvamlActionContinueImpl, SvamlActionHangupImpl, + * SvamlActionParkImpl + * + *

It could be an instance of the 'oneOf' schemas. The oneOf child schemas may themselves be a + * composed schema (allOf, anyOf, oneOf). + */ + @Override + public void setActualInstance(Object instance) { + if (JSONNavigator.isInstanceOf( + SvamlActionContinueImpl.class, instance, new HashSet>())) { + super.setActualInstance(instance); + return; + } + + if (JSONNavigator.isInstanceOf( + SvamlActionHangupImpl.class, instance, new HashSet>())) { + super.setActualInstance(instance); + return; + } + + if (JSONNavigator.isInstanceOf(SvamlActionParkImpl.class, instance, new HashSet>())) { + super.setActualInstance(instance); + return; + } + + throw new RuntimeException( + "Invalid instance type. Must be SvamlActionContinueImpl, SvamlActionHangupImpl," + + " SvamlActionParkImpl"); + } + + /** + * Get the actual instance, which can be the following: SvamlActionContinueImpl, + * SvamlActionHangupImpl, SvamlActionParkImpl + * + * @return The actual instance (SvamlActionContinueImpl, SvamlActionHangupImpl, + * SvamlActionParkImpl) + */ + @Override + public Object getActualInstance() { + return super.getActualInstance(); + } + + /** + * Get the actual instance of `SvamlActionContinueImpl`. If the actual instance is not + * `SvamlActionContinueImpl`, the ClassCastException will be thrown. + * + * @return The actual instance of `SvamlActionContinueImpl` + * @throws ClassCastException if the instance is not `SvamlActionContinueImpl` + */ + public SvamlActionContinueImpl getSvamlActionContinueImpl() throws ClassCastException { + return (SvamlActionContinueImpl) super.getActualInstance(); + } + + /** + * Get the actual instance of `SvamlActionHangupImpl`. If the actual instance is not + * `SvamlActionHangupImpl`, the ClassCastException will be thrown. + * + * @return The actual instance of `SvamlActionHangupImpl` + * @throws ClassCastException if the instance is not `SvamlActionHangupImpl` + */ + public SvamlActionHangupImpl getSvamlActionHangupImpl() throws ClassCastException { + return (SvamlActionHangupImpl) super.getActualInstance(); + } + + /** + * Get the actual instance of `SvamlActionParkImpl`. If the actual instance is not + * `SvamlActionParkImpl`, the ClassCastException will be thrown. + * + * @return The actual instance of `SvamlActionParkImpl` + * @throws ClassCastException if the instance is not `SvamlActionParkImpl` + */ + public SvamlActionParkImpl getSvamlActionParkImpl() throws ClassCastException { + return (SvamlActionParkImpl) super.getActualInstance(); + } +} diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlControlPatch.java b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlControlPatch.java new file mode 100644 index 000000000..b48ca0ffb --- /dev/null +++ b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlControlPatch.java @@ -0,0 +1,78 @@ +/* + * Voice API | Sinch + * + * OpenAPI document version: 1.0.1 + * Contact: support@sinch.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit the class manually. + */ + +package com.sinch.sdk.domains.voice.models.v1.calls.request; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionPatch; +import com.sinch.sdk.domains.voice.models.v1.svaml.instruction.SvamlInstruction; +import java.util.Collection; + +/** + * SVAML is a call control markup language. When a server receives a callback event from the Sinch + * platform, it can respond with a SVAML object to control the voice call. The following is an + * example of a SVAML object type and its contents. + */ +@JsonDeserialize(builder = SvamlControlPatchImpl.Builder.class) +public interface SvamlControlPatch extends com.sinch.sdk.domains.voice.models.v1.svaml.Control { + + /** + * The collection of instructions that can perform various tasks during the call. You can include + * as many instructions as necessary. + * + * @return instructions + */ + Collection getInstructions(); + + /** + * Get action + * + * @return action + */ + SvamlActionPatch getAction(); + + /** + * Getting builder + * + * @return New Builder instance + */ + static Builder builder() { + return new SvamlControlPatchImpl.Builder(); + } + + /** Dedicated Builder */ + interface Builder { + + /** + * see getter + * + * @param instructions see getter + * @return Current builder + * @see #getInstructions + */ + Builder setInstructions(Collection instructions); + + /** + * see getter + * + * @param action see getter + * @return Current builder + * @see #getAction + */ + Builder setAction(SvamlActionPatch action); + + /** + * Create instance + * + * @return The instance build with current builder values + */ + SvamlControlPatch build(); + } +} diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlControlPatchImpl.java b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlControlPatchImpl.java new file mode 100644 index 000000000..8bff22441 --- /dev/null +++ b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlControlPatchImpl.java @@ -0,0 +1,124 @@ +package com.sinch.sdk.domains.voice.models.v1.calls.request; + +import com.fasterxml.jackson.annotation.JsonFilter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; +import com.sinch.sdk.core.models.OptionalValue; +import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionPatch; +import com.sinch.sdk.domains.voice.models.v1.svaml.instruction.SvamlInstruction; +import java.util.Collection; +import java.util.Objects; + +@JsonPropertyOrder({ + SvamlControlPatchImpl.JSON_PROPERTY_INSTRUCTIONS, + SvamlControlPatchImpl.JSON_PROPERTY_ACTION +}) +@JsonFilter("uninitializedFilter") +@JsonInclude(value = JsonInclude.Include.CUSTOM) +public class SvamlControlPatchImpl + implements SvamlControlPatch, com.sinch.sdk.domains.voice.models.v1.svaml.Control { + private static final long serialVersionUID = 1L; + + public static final String JSON_PROPERTY_INSTRUCTIONS = "instructions"; + + private OptionalValue> instructions; + + public static final String JSON_PROPERTY_ACTION = "action"; + + private OptionalValue action; + + public SvamlControlPatchImpl() {} + + protected SvamlControlPatchImpl( + OptionalValue> instructions, + OptionalValue action) { + this.instructions = instructions; + this.action = action; + } + + @JsonIgnore + public Collection getInstructions() { + return instructions.orElse(null); + } + + @JsonProperty(JSON_PROPERTY_INSTRUCTIONS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public OptionalValue> instructions() { + return instructions; + } + + @JsonIgnore + public SvamlActionPatch getAction() { + return action.orElse(null); + } + + @JsonProperty(JSON_PROPERTY_ACTION) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public OptionalValue action() { + return action; + } + + /** Return true if this UpdateCallSVAMLRequestBody object is equal to o. */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SvamlControlPatchImpl updateCallSVAMLRequestBody = (SvamlControlPatchImpl) o; + return Objects.equals(this.instructions, updateCallSVAMLRequestBody.instructions) + && Objects.equals(this.action, updateCallSVAMLRequestBody.action); + } + + @Override + public int hashCode() { + return Objects.hash(instructions, action); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class SvamlControlPatchImpl {\n"); + sb.append(" instructions: ").append(toIndentedString(instructions)).append("\n"); + sb.append(" action: ").append(toIndentedString(action)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + + @JsonPOJOBuilder(withPrefix = "set") + static class Builder implements SvamlControlPatch.Builder { + OptionalValue> instructions = OptionalValue.empty(); + OptionalValue action = OptionalValue.empty(); + + @JsonProperty(JSON_PROPERTY_INSTRUCTIONS) + public Builder setInstructions(Collection instructions) { + this.instructions = OptionalValue.of(instructions); + return this; + } + + @JsonProperty(JSON_PROPERTY_ACTION) + public Builder setAction(SvamlActionPatch action) { + this.action = OptionalValue.of(action); + return this; + } + + public SvamlControlPatch build() { + return new SvamlControlPatchImpl(instructions, action); + } + } +} diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionContinue.java b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionContinue.java index 37240e504..784c2b6e9 100644 --- a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionContinue.java +++ b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionContinue.java @@ -23,7 +23,8 @@ */ @JsonDeserialize(builder = SvamlActionContinueImpl.Builder.class) public interface SvamlActionContinue - extends com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlAction { + extends com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlAction, + com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionPatch { /** ready to use action to send a `continue` */ SvamlActionContinue SVAML_ACTION_CONTINUE = SvamlActionContinue.builder().build(); diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionContinueImpl.java b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionContinueImpl.java index 09c3450e7..91f182b55 100644 --- a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionContinueImpl.java +++ b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionContinueImpl.java @@ -13,7 +13,9 @@ @JsonFilter("uninitializedFilter") @JsonInclude(value = JsonInclude.Include.CUSTOM) public class SvamlActionContinueImpl - implements SvamlActionContinue, com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlAction { + implements SvamlActionContinue, + com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlAction, + com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionPatch { private static final long serialVersionUID = 1L; public static final String JSON_PROPERTY_NAME = "name"; diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionHangup.java b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionHangup.java index c40d66663..419dbc3b6 100644 --- a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionHangup.java +++ b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionHangup.java @@ -25,7 +25,8 @@ */ @JsonDeserialize(builder = SvamlActionHangupImpl.Builder.class) public interface SvamlActionHangup - extends com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlAction { + extends com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlAction, + com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionPatch { /** ready to use action to send a `hangup` */ SvamlActionHangup SVAML_ACTION_HANGUP = SvamlActionHangup.builder().build(); diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionHangupImpl.java b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionHangupImpl.java index 9cdac58e9..3d938e358 100644 --- a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionHangupImpl.java +++ b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionHangupImpl.java @@ -13,7 +13,9 @@ @JsonFilter("uninitializedFilter") @JsonInclude(value = JsonInclude.Include.CUSTOM) public class SvamlActionHangupImpl - implements SvamlActionHangup, com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlAction { + implements SvamlActionHangup, + com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlAction, + com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionPatch { private static final long serialVersionUID = 1L; public static final String JSON_PROPERTY_NAME = "name"; diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionPark.java b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionPark.java index db8f2bdf2..69b131dfb 100644 --- a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionPark.java +++ b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionPark.java @@ -24,7 +24,8 @@ */ @JsonDeserialize(builder = SvamlActionParkImpl.Builder.class) public interface SvamlActionPark - extends com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlAction { + extends com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlAction, + com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionPatch { /** The name property. Must have the value park. */ public class NameEnum extends EnumDynamic { diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionParkImpl.java b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionParkImpl.java index d66651404..72fe17653 100644 --- a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionParkImpl.java +++ b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionParkImpl.java @@ -19,7 +19,9 @@ @JsonFilter("uninitializedFilter") @JsonInclude(value = JsonInclude.Include.CUSTOM) public class SvamlActionParkImpl - implements SvamlActionPark, com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlAction { + implements SvamlActionPark, + com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlAction, + com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionPatch { private static final long serialVersionUID = 1L; public static final String JSON_PROPERTY_NAME = "name"; diff --git a/openapi-contracts/src/test/java/com/sinch/sdk/domains/voice/models/v1/svaml/SvamlControlPatchTest.java b/openapi-contracts/src/test/java/com/sinch/sdk/domains/voice/models/v1/svaml/SvamlControlPatchTest.java new file mode 100644 index 000000000..3ffb58741 --- /dev/null +++ b/openapi-contracts/src/test/java/com/sinch/sdk/domains/voice/models/v1/svaml/SvamlControlPatchTest.java @@ -0,0 +1,39 @@ +package com.sinch.sdk.domains.voice.models.v1.svaml; + +import com.adelean.inject.resources.junit.jupiter.GivenTextResource; +import com.adelean.inject.resources.junit.jupiter.TestWithResources; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.sinch.sdk.BaseTest; +import com.sinch.sdk.domains.voice.models.v1.calls.request.SvamlControlPatch; +import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionHangup; +import com.sinch.sdk.domains.voice.models.v1.svaml.instruction.SvamlInstructionSay; +import java.util.Arrays; +import org.json.JSONException; +import org.junit.jupiter.api.Test; +import org.skyscreamer.jsonassert.JSONAssert; + +@TestWithResources +public class SvamlControlPatchTest extends BaseTest { + + public static SvamlControlPatch expectedSvamlControlPatch = + SvamlControlPatch.builder() + .setAction(SvamlActionHangup.SVAML_ACTION_HANGUP) + .setInstructions( + Arrays.asList( + SvamlInstructionSay.builder() + .setText("Sorry, the conference has been cancelled. The call will end now.") + .setLocale("en-US") + .build())) + .build(); + + @GivenTextResource("/domains/voice/v1/svaml/SvamlControlPatchDto.json") + String jsonSvamlControlPatchDto; + + @Test + void serializeSVAMLResponse() throws JsonProcessingException, JSONException { + + String serializedString = objectMapper.writeValueAsString(expectedSvamlControlPatch); + + JSONAssert.assertEquals(jsonSvamlControlPatchDto, serializedString, true); + } +} diff --git a/openapi-contracts/src/test/resources/domains/voice/v1/svaml/SvamlControlPatchDto.json b/openapi-contracts/src/test/resources/domains/voice/v1/svaml/SvamlControlPatchDto.json new file mode 100644 index 000000000..1640c9049 --- /dev/null +++ b/openapi-contracts/src/test/resources/domains/voice/v1/svaml/SvamlControlPatchDto.json @@ -0,0 +1,12 @@ +{ + "instructions": [ + { + "name": "say", + "text": "Sorry, the conference has been cancelled. The call will end now.", + "locale": "en-US" + } + ], + "action": { + "name": "hangup" + } +} From b857f9d4042c876c509c2ab690823830717c4be4 Mon Sep 17 00:00:00 2001 From: Eduardo San Segundo Date: Tue, 16 Jun 2026 10:53:05 +0200 Subject: [PATCH 2/4] Updated references to SvamlPatch in the snippets --- .../src/main/java/voice/calls/ManageWithCallLeg.java | 10 +++++----- .../snippets/src/main/java/voice/calls/Update.java | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/snippets/src/main/java/voice/calls/ManageWithCallLeg.java b/examples/snippets/src/main/java/voice/calls/ManageWithCallLeg.java index 47c74a033..13fb16d46 100644 --- a/examples/snippets/src/main/java/voice/calls/ManageWithCallLeg.java +++ b/examples/snippets/src/main/java/voice/calls/ManageWithCallLeg.java @@ -10,9 +10,9 @@ import com.sinch.sdk.SinchClient; import com.sinch.sdk.domains.voice.api.v1.CallsService; import com.sinch.sdk.domains.voice.models.v1.calls.request.CallLeg; -import com.sinch.sdk.domains.voice.models.v1.svaml.SvamlControl; -import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlAction; +import com.sinch.sdk.domains.voice.models.v1.calls.request.SvamlControlPatch; import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionHangup; +import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionPatch; import com.sinch.sdk.domains.voice.models.v1.svaml.instruction.SvamlInstruction; import com.sinch.sdk.domains.voice.models.v1.svaml.instruction.SvamlInstructionSay; import com.sinch.sdk.models.Configuration; @@ -47,7 +47,7 @@ public static void main(String[] args) { LOGGER.info(String.format("Manage call with ID '%s'", callId)); - SvamlAction action = SvamlActionHangup.SVAML_ACTION_HANGUP; + SvamlActionPatch action = SvamlActionHangup.SVAML_ACTION_HANGUP; Collection instructions = Collections.singletonList( @@ -55,8 +55,8 @@ public static void main(String[] args) { .setText("Hello, the call is over, hanging up now. Goodbye") .build()); - SvamlControl request = - SvamlControl.builder().setInstructions(instructions).setAction(action).build(); + SvamlControlPatch request = + SvamlControlPatch.builder().setInstructions(instructions).setAction(action).build(); callsService.manageWithCallLeg(callId, callLeg, request); diff --git a/examples/snippets/src/main/java/voice/calls/Update.java b/examples/snippets/src/main/java/voice/calls/Update.java index 9d5cbad45..d6d84f461 100644 --- a/examples/snippets/src/main/java/voice/calls/Update.java +++ b/examples/snippets/src/main/java/voice/calls/Update.java @@ -9,9 +9,9 @@ import com.sinch.sdk.SinchClient; import com.sinch.sdk.domains.voice.api.v1.CallsService; -import com.sinch.sdk.domains.voice.models.v1.svaml.SvamlControl; -import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlAction; +import com.sinch.sdk.domains.voice.models.v1.calls.request.SvamlControlPatch; import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionHangup; +import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionPatch; import com.sinch.sdk.domains.voice.models.v1.svaml.instruction.SvamlInstruction; import com.sinch.sdk.domains.voice.models.v1.svaml.instruction.SvamlInstructionSay; import com.sinch.sdk.models.Configuration; @@ -34,7 +34,7 @@ public static void main(String[] args) { // The instruction to be performed SvamlInstruction instruction = SvamlInstructionSay.builder().setText("Goodbye").build(); // The instruction to add to the call - SvamlAction action = SvamlActionHangup.SVAML_ACTION_HANGUP; + SvamlActionPatch action = SvamlActionHangup.SVAML_ACTION_HANGUP; Configuration configuration = Configuration.builder() @@ -50,8 +50,8 @@ public static void main(String[] args) { Collection instructions = Collections.singletonList(instruction); - SvamlControl request = - SvamlControl.builder().setInstructions(instructions).setAction(action).build(); + SvamlControlPatch request = + SvamlControlPatch.builder().setInstructions(instructions).setAction(action).build(); callsService.update(callId, request); From 14c14f8ff2460665fb196a8471ecebcb60226825 Mon Sep 17 00:00:00 2001 From: Eduardo San Segundo Date: Thu, 18 Jun 2026 15:55:57 +0200 Subject: [PATCH 3/4] Voice: updated sources and references for tests and snippet files --- .../api/v1/adapters/CallsServiceTest.java | 14 +- .../sdk/e2e/domains/voice/v1/CallsSteps.java | 14 +- .../java/voice/calls/ManageWithCallLeg.java | 6 +- .../src/main/java/voice/calls/Update.java | 6 +- .../domains/voice/api/v1/CallsService.java | 46 ++- .../api/v1/adapters/CallsServiceImpl.java | 155 +++++++- .../v1/calls/request/CallUpdateRequest.java | 78 ++++ .../calls/request/CallUpdateRequestImpl.java | 123 ++++++ .../internal/SvamlActionPatchInternal.java | 17 + .../SvamlActionPatchInternalImpl.java | 366 ++++++++++++++++++ .../calls/request/CallUpdateRequestTest.java | 38 ++ .../calls/request/CallUpdateRequestDto.json | 12 + 12 files changed, 838 insertions(+), 37 deletions(-) create mode 100644 openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/CallUpdateRequest.java create mode 100644 openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/CallUpdateRequestImpl.java create mode 100644 openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/internal/SvamlActionPatchInternal.java create mode 100644 openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/internal/SvamlActionPatchInternalImpl.java create mode 100644 openapi-contracts/src/test/java/com/sinch/sdk/domains/voice/models/v1/calls/request/CallUpdateRequestTest.java create mode 100644 openapi-contracts/src/test/resources/domains/voice/v1/calls/request/CallUpdateRequestDto.json diff --git a/client/src/test/java/com/sinch/sdk/domains/voice/api/v1/adapters/CallsServiceTest.java b/client/src/test/java/com/sinch/sdk/domains/voice/api/v1/adapters/CallsServiceTest.java index 1253b9881..22e11c14d 100644 --- a/client/src/test/java/com/sinch/sdk/domains/voice/api/v1/adapters/CallsServiceTest.java +++ b/client/src/test/java/com/sinch/sdk/domains/voice/api/v1/adapters/CallsServiceTest.java @@ -22,8 +22,8 @@ import com.sinch.sdk.domains.voice.api.v1.CallsService; import com.sinch.sdk.domains.voice.models.v1.calls.CallInformationTest; import com.sinch.sdk.domains.voice.models.v1.calls.request.CallLeg; +import com.sinch.sdk.domains.voice.models.v1.calls.request.CallUpdateRequestTest; import com.sinch.sdk.domains.voice.models.v1.calls.response.CallInformation; -import com.sinch.sdk.domains.voice.models.v1.svaml.SvamlControlPatchTest; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -38,8 +38,8 @@ public class CallsServiceTest extends BaseTest { @GivenTextResource("/domains/voice/v1/calls/GetCallInformationResponseDto.json") String getCallInformationResponseDto; - @GivenTextResource("/domains/voice/v1/svaml/SvamlControlPatchDto.json") - String svamlControlDto; + @GivenTextResource("/domains/voice/v1/calls/request/CallUpdateRequestDto.json") + String callUpdateRequestDto; static final Collection AUTH_NAMES = Arrays.asList("Basic", "Signed"); @@ -95,7 +95,7 @@ void update() throws ApiException { "/calling/v1/calls/id/" + URLPathUtils.encodePathSegment("call/id"), HttpMethod.PATCH, Collections.emptyList(), - svamlControlDto, + callUpdateRequestDto, Collections.emptyMap(), Collections.emptyList(), Collections.singletonList(HttpContentType.APPLICATION_JSON), @@ -108,7 +108,7 @@ void update() throws ApiException { argThat(new HttpRequestMatcher(httpRequest)))) .thenReturn(httpResponse); - service.update("call/id", SvamlControlPatchTest.expectedSvamlControlPatch); + service.update("call/id", CallUpdateRequestTest.expectedCallUpdateRequest); } @Test @@ -119,7 +119,7 @@ void manageWithCallLeg() throws ApiException { "/calling/v1/calls/id/" + URLPathUtils.encodePathSegment("call/id") + "/leg/both", HttpMethod.PATCH, Collections.emptyList(), - svamlControlDto, + callUpdateRequestDto, Collections.emptyMap(), Collections.singletonList(HttpContentType.APPLICATION_JSON), Collections.singletonList(HttpContentType.APPLICATION_JSON), @@ -133,6 +133,6 @@ void manageWithCallLeg() throws ApiException { .thenReturn(httpResponse); service.manageWithCallLeg( - "call/id", CallLeg.BOTH, SvamlControlPatchTest.expectedSvamlControlPatch); + "call/id", CallLeg.BOTH, CallUpdateRequestTest.expectedCallUpdateRequest); } } diff --git a/client/src/test/java/com/sinch/sdk/e2e/domains/voice/v1/CallsSteps.java b/client/src/test/java/com/sinch/sdk/e2e/domains/voice/v1/CallsSteps.java index 34a1452f6..f371e2c8f 100644 --- a/client/src/test/java/com/sinch/sdk/e2e/domains/voice/v1/CallsSteps.java +++ b/client/src/test/java/com/sinch/sdk/e2e/domains/voice/v1/CallsSteps.java @@ -5,7 +5,7 @@ import com.sinch.sdk.domains.voice.api.v1.CallsService; import com.sinch.sdk.domains.voice.models.v1.Price; import com.sinch.sdk.domains.voice.models.v1.calls.request.CallLeg; -import com.sinch.sdk.domains.voice.models.v1.calls.request.SvamlControlPatch; +import com.sinch.sdk.domains.voice.models.v1.calls.request.CallUpdateRequest; import com.sinch.sdk.domains.voice.models.v1.calls.response.CallInformation; import com.sinch.sdk.domains.voice.models.v1.calls.response.CallInformation.DomainEnum; import com.sinch.sdk.domains.voice.models.v1.calls.response.CallInformation.ReasonEnum; @@ -46,8 +46,8 @@ public void getCall() { @When("^I send a request to update a call$") public void updateCall() { - SvamlControlPatch request = - SvamlControlPatch.builder() + CallUpdateRequest request = + CallUpdateRequest.builder() .setInstructions( Arrays.asList( SvamlInstructionSay.builder() @@ -63,8 +63,8 @@ public void updateCall() { @When("^I send a request to update a call that doesn't exist$") public void updateCallNotExits() { - SvamlControlPatch request = - SvamlControlPatch.builder() + CallUpdateRequest request = + CallUpdateRequest.builder() .setInstructions( Arrays.asList( SvamlInstructionSay.builder() @@ -83,8 +83,8 @@ public void updateCallNotExits() { @When("^I send a request to manage a call with callLeg$") public void manageCallWithCallLeg() { - SvamlControlPatch request = - SvamlControlPatch.builder() + CallUpdateRequest request = + CallUpdateRequest.builder() .setInstructions( Arrays.asList( SvamlInstructionPlayFiles.builder() diff --git a/examples/snippets/src/main/java/voice/calls/ManageWithCallLeg.java b/examples/snippets/src/main/java/voice/calls/ManageWithCallLeg.java index 13fb16d46..d03127cb1 100644 --- a/examples/snippets/src/main/java/voice/calls/ManageWithCallLeg.java +++ b/examples/snippets/src/main/java/voice/calls/ManageWithCallLeg.java @@ -10,7 +10,7 @@ import com.sinch.sdk.SinchClient; import com.sinch.sdk.domains.voice.api.v1.CallsService; import com.sinch.sdk.domains.voice.models.v1.calls.request.CallLeg; -import com.sinch.sdk.domains.voice.models.v1.calls.request.SvamlControlPatch; +import com.sinch.sdk.domains.voice.models.v1.calls.request.CallUpdateRequest; import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionHangup; import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionPatch; import com.sinch.sdk.domains.voice.models.v1.svaml.instruction.SvamlInstruction; @@ -55,8 +55,8 @@ public static void main(String[] args) { .setText("Hello, the call is over, hanging up now. Goodbye") .build()); - SvamlControlPatch request = - SvamlControlPatch.builder().setInstructions(instructions).setAction(action).build(); + CallUpdateRequest request = + CallUpdateRequest.builder().setInstructions(instructions).setAction(action).build(); callsService.manageWithCallLeg(callId, callLeg, request); diff --git a/examples/snippets/src/main/java/voice/calls/Update.java b/examples/snippets/src/main/java/voice/calls/Update.java index d6d84f461..a25d298c6 100644 --- a/examples/snippets/src/main/java/voice/calls/Update.java +++ b/examples/snippets/src/main/java/voice/calls/Update.java @@ -9,7 +9,7 @@ import com.sinch.sdk.SinchClient; import com.sinch.sdk.domains.voice.api.v1.CallsService; -import com.sinch.sdk.domains.voice.models.v1.calls.request.SvamlControlPatch; +import com.sinch.sdk.domains.voice.models.v1.calls.request.CallUpdateRequest; import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionHangup; import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionPatch; import com.sinch.sdk.domains.voice.models.v1.svaml.instruction.SvamlInstruction; @@ -50,8 +50,8 @@ public static void main(String[] args) { Collection instructions = Collections.singletonList(instruction); - SvamlControlPatch request = - SvamlControlPatch.builder().setInstructions(instructions).setAction(action).build(); + CallUpdateRequest request = + CallUpdateRequest.builder().setInstructions(instructions).setAction(action).build(); callsService.update(callId, request); diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/api/v1/CallsService.java b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/api/v1/CallsService.java index 28f0b209b..680128532 100644 --- a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/api/v1/CallsService.java +++ b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/api/v1/CallsService.java @@ -12,8 +12,9 @@ import com.sinch.sdk.core.exceptions.ApiException; import com.sinch.sdk.domains.voice.models.v1.calls.request.CallLeg; -import com.sinch.sdk.domains.voice.models.v1.calls.request.SvamlControlPatch; +import com.sinch.sdk.domains.voice.models.v1.calls.request.CallUpdateRequest; import com.sinch.sdk.domains.voice.models.v1.calls.response.CallInformation; +import com.sinch.sdk.domains.voice.models.v1.svaml.SvamlControl; /** Calls Service */ public interface CallsService { @@ -53,10 +54,10 @@ public interface CallsService { * `caller`.<br><Warning>The `callLeg` identifier is ignored * for calls that are part of a conference and calls initiated using the Callout * API.</Warning> (required) - * @param svamlControlPatch (optional) + * @param callUpdateRequest (optional) * @throws ApiException if fails to make API call */ - void manageWithCallLeg(String callId, CallLeg callLeg, SvamlControlPatch svamlControlPatch) + void manageWithCallLeg(String callId, CallLeg callLeg, CallUpdateRequest callUpdateRequest) throws ApiException; /** @@ -70,8 +71,43 @@ void manageWithCallLeg(String callId, CallLeg callLeg, SvamlControlPatch svamlCo * * @param callId The unique identifier of the call. This value is generated by the system. * (required) - * @param svamlControlPatch (optional) + * @param callUpdateRequest (optional) * @throws ApiException if fails to make API call */ - void update(String callId, SvamlControlPatch svamlControlPatch) throws ApiException; + void update(String callId, CallUpdateRequest callUpdateRequest) throws ApiException; + + /** + * Manage Call with `callLeg` + * + *

This method is deprecated replaced by {@link #manageWithCallLeg(String, CallLeg, + * CallUpdateRequest)} + * + * @param callId The unique identifier of the call. This value is generated by the system. + * (required) + * @param callLeg Specifies which part of the call will be managed. This option is used only by + * the `PlayFiles` and `Say` instructions to indicate which channel the + * sound will be played on. Valid options are `caller`, `callee` or + * `both`. If not specified, the default value is + * `caller`.<br><Warning>The `callLeg` identifier is ignored + * for calls that are part of a conference and calls initiated using the Callout + * API.</Warning> (required) + * @param svamlControl (optional) + * @throws ApiException if fails to make API call + * @deprecated + */ + void manageWithCallLeg(String callId, CallLeg callLeg, SvamlControl svamlControl) + throws ApiException; + + /** + * Update a call in progress + * + *

This method is deprecated replaced by {@link #update(String, CallUpdateRequest)} + * + * @param callId The unique identifier of the call. This value is generated by the system. + * (required) + * @param svamlControl (optional) + * @throws ApiException if fails to make API call + * @deprecated + */ + void update(String callId, SvamlControl svamlControl) throws ApiException; } diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/api/v1/adapters/CallsServiceImpl.java b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/api/v1/adapters/CallsServiceImpl.java index 1c146f8b0..5eabae47c 100644 --- a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/api/v1/adapters/CallsServiceImpl.java +++ b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/api/v1/adapters/CallsServiceImpl.java @@ -24,8 +24,9 @@ import com.sinch.sdk.core.http.URLPathUtils; import com.sinch.sdk.core.models.ServerConfiguration; import com.sinch.sdk.domains.voice.models.v1.calls.request.CallLeg; -import com.sinch.sdk.domains.voice.models.v1.calls.request.SvamlControlPatch; +import com.sinch.sdk.domains.voice.models.v1.calls.request.CallUpdateRequest; import com.sinch.sdk.domains.voice.models.v1.calls.response.CallInformation; +import com.sinch.sdk.domains.voice.models.v1.svaml.SvamlControl; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -109,7 +110,7 @@ private HttpRequest getRequestBuilder(String callId) throws ApiException { } @Override - public void manageWithCallLeg(String callId, CallLeg callLeg, SvamlControlPatch svamlControlPatch) + public void manageWithCallLeg(String callId, CallLeg callLeg, CallUpdateRequest callUpdateRequest) throws ApiException { LOGGER.finest( @@ -121,10 +122,10 @@ public void manageWithCallLeg(String callId, CallLeg callLeg, SvamlControlPatch + "callLeg: " + callLeg + ", " - + "svamlControlPatch: " - + svamlControlPatch); + + "callUpdateRequest: " + + callUpdateRequest); - HttpRequest httpRequest = manageWithCallLegRequestBuilder(callId, callLeg, svamlControlPatch); + HttpRequest httpRequest = manageWithCallLegRequestBuilder(callId, callLeg, callUpdateRequest); HttpResponse response = httpClient.invokeAPI( this.serverConfiguration, this.authManagersByOasSecuritySchemes, httpRequest); @@ -142,7 +143,7 @@ public void manageWithCallLeg(String callId, CallLeg callLeg, SvamlControlPatch } private HttpRequest manageWithCallLegRequestBuilder( - String callId, CallLeg callLeg, SvamlControlPatch svamlControlPatch) throws ApiException { + String callId, CallLeg callLeg, CallUpdateRequest callUpdateRequest) throws ApiException { // verify the required parameter 'callId' is set if (callId == null) { throw new ApiException( @@ -169,7 +170,7 @@ private HttpRequest manageWithCallLegRequestBuilder( final Collection localVarContentTypes = Arrays.asList("application/json"); final Collection localVarAuthNames = Arrays.asList("Basic", "Signed"); - final String serializedBody = mapper.serialize(localVarContentTypes, svamlControlPatch); + final String serializedBody = mapper.serialize(localVarContentTypes, callUpdateRequest); return new HttpRequest( localVarPath, @@ -183,12 +184,12 @@ private HttpRequest manageWithCallLegRequestBuilder( } @Override - public void update(String callId, SvamlControlPatch svamlControlPatch) throws ApiException { + public void update(String callId, CallUpdateRequest callUpdateRequest) throws ApiException { LOGGER.finest( - "[update]" + " " + "callId: " + callId + ", " + "svamlControlPatch: " + svamlControlPatch); + "[update]" + " " + "callId: " + callId + ", " + "callUpdateRequest: " + callUpdateRequest); - HttpRequest httpRequest = updateRequestBuilder(callId, svamlControlPatch); + HttpRequest httpRequest = updateRequestBuilder(callId, callUpdateRequest); HttpResponse response = httpClient.invokeAPI( this.serverConfiguration, this.authManagersByOasSecuritySchemes, httpRequest); @@ -205,7 +206,7 @@ public void update(String callId, SvamlControlPatch svamlControlPatch) throws Ap mapper.deserialize(response, new TypeReference>() {})); } - private HttpRequest updateRequestBuilder(String callId, SvamlControlPatch svamlControlPatch) + private HttpRequest updateRequestBuilder(String callId, CallUpdateRequest callUpdateRequest) throws ApiException { // verify the required parameter 'callId' is set if (callId == null) { @@ -226,7 +227,137 @@ private HttpRequest updateRequestBuilder(String callId, SvamlControlPatch svamlC final Collection localVarContentTypes = Arrays.asList("application/json"); final Collection localVarAuthNames = Arrays.asList("Basic", "Signed"); - final String serializedBody = mapper.serialize(localVarContentTypes, svamlControlPatch); + final String serializedBody = mapper.serialize(localVarContentTypes, callUpdateRequest); + + return new HttpRequest( + localVarPath, + HttpMethod.PATCH, + localVarQueryParams, + serializedBody, + localVarHeaderParams, + localVarAccepts, + localVarContentTypes, + localVarAuthNames); + } + + @Override + public void manageWithCallLeg(String callId, CallLeg callLeg, SvamlControl svamlControl) + throws ApiException { + + LOGGER.finest( + "[manageWithCallLeg]" + + " " + + "callId: " + + callId + + ", " + + "callLeg: " + + callLeg + + ", " + + "svamlControl: " + + svamlControl); + + HttpRequest httpRequest = manageWithCallLegRequestBuilder(callId, callLeg, svamlControl); + HttpResponse response = + httpClient.invokeAPI( + this.serverConfiguration, this.authManagersByOasSecuritySchemes, httpRequest); + + if (HttpStatus.isSuccessfulStatus(response.getCode())) { + return; + } + // fallback to default errors handling: + // all error cases definition are not required from specs: will try some "hardcoded" content + // parsing + throw ApiExceptionBuilder.build( + response.getMessage(), + response.getCode(), + mapper.deserialize(response, new TypeReference>() {})); + } + + private HttpRequest manageWithCallLegRequestBuilder( + String callId, CallLeg callLeg, SvamlControl svamlControl) throws ApiException { + // verify the required parameter 'callId' is set + if (callId == null) { + throw new ApiException( + 400, "Missing the required parameter 'callId' when calling manageWithCallLeg"); + } + // verify the required parameter 'callLeg' is set + if (callLeg == null) { + throw new ApiException( + 400, "Missing the required parameter 'callLeg' when calling manageWithCallLeg"); + } + + String localVarPath = + "/calling/v1/calls/id/{callId}/leg/{callLeg}" + .replaceAll("\\{" + "callId" + "\\}", URLPathUtils.encodePathSegment(callId.toString())) + .replaceAll( + "\\{" + "callLeg" + "\\}", URLPathUtils.encodePathSegment(callLeg.toString())); + + List localVarQueryParams = new ArrayList<>(); + + Map localVarHeaderParams = new HashMap<>(); + + final Collection localVarAccepts = Arrays.asList("application/json"); + + final Collection localVarContentTypes = Arrays.asList("application/json"); + + final Collection localVarAuthNames = Arrays.asList("Basic", "Signed"); + final String serializedBody = mapper.serialize(localVarContentTypes, svamlControl); + + return new HttpRequest( + localVarPath, + HttpMethod.PATCH, + localVarQueryParams, + serializedBody, + localVarHeaderParams, + localVarAccepts, + localVarContentTypes, + localVarAuthNames); + } + + @Override + public void update(String callId, SvamlControl svamlControl) throws ApiException { + + LOGGER.finest("[update]" + " " + "callId: " + callId + ", " + "svamlControl: " + svamlControl); + + HttpRequest httpRequest = updateRequestBuilder(callId, svamlControl); + HttpResponse response = + httpClient.invokeAPI( + this.serverConfiguration, this.authManagersByOasSecuritySchemes, httpRequest); + + if (HttpStatus.isSuccessfulStatus(response.getCode())) { + return; + } + // fallback to default errors handling: + // all error cases definition are not required from specs: will try some "hardcoded" content + // parsing + throw ApiExceptionBuilder.build( + response.getMessage(), + response.getCode(), + mapper.deserialize(response, new TypeReference>() {})); + } + + private HttpRequest updateRequestBuilder(String callId, SvamlControl svamlControl) + throws ApiException { + // verify the required parameter 'callId' is set + if (callId == null) { + throw new ApiException(400, "Missing the required parameter 'callId' when calling update"); + } + + String localVarPath = + "/calling/v1/calls/id/{callId}" + .replaceAll( + "\\{" + "callId" + "\\}", URLPathUtils.encodePathSegment(callId.toString())); + + List localVarQueryParams = new ArrayList<>(); + + Map localVarHeaderParams = new HashMap<>(); + + final Collection localVarAccepts = Arrays.asList(); + + final Collection localVarContentTypes = Arrays.asList("application/json"); + + final Collection localVarAuthNames = Arrays.asList("Basic", "Signed"); + final String serializedBody = mapper.serialize(localVarContentTypes, svamlControl); return new HttpRequest( localVarPath, diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/CallUpdateRequest.java b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/CallUpdateRequest.java new file mode 100644 index 000000000..39221bc4d --- /dev/null +++ b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/CallUpdateRequest.java @@ -0,0 +1,78 @@ +/* + * Voice API | Sinch + * + * OpenAPI document version: 1.0.1 + * Contact: support@sinch.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit the class manually. + */ + +package com.sinch.sdk.domains.voice.models.v1.calls.request; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionPatch; +import com.sinch.sdk.domains.voice.models.v1.svaml.instruction.SvamlInstruction; +import java.util.Collection; + +/** + * SVAML is a call control markup language. When a server receives a callback event from the Sinch + * platform, it can respond with a SVAML object to control the voice call. The following is an + * example of a SVAML object type and its contents. + */ +@JsonDeserialize(builder = CallUpdateRequestImpl.Builder.class) +public interface CallUpdateRequest { + + /** + * The collection of instructions that can perform various tasks during the call. You can include + * as many instructions as necessary. + * + * @return instructions + */ + Collection getInstructions(); + + /** + * Get action + * + * @return action + */ + SvamlActionPatch getAction(); + + /** + * Getting builder + * + * @return New Builder instance + */ + static Builder builder() { + return new CallUpdateRequestImpl.Builder(); + } + + /** Dedicated Builder */ + interface Builder { + + /** + * see getter + * + * @param instructions see getter + * @return Current builder + * @see #getInstructions + */ + Builder setInstructions(Collection instructions); + + /** + * see getter + * + * @param action see getter + * @return Current builder + * @see #getAction + */ + Builder setAction(SvamlActionPatch action); + + /** + * Create instance + * + * @return The instance build with current builder values + */ + CallUpdateRequest build(); + } +} diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/CallUpdateRequestImpl.java b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/CallUpdateRequestImpl.java new file mode 100644 index 000000000..7ba595fa6 --- /dev/null +++ b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/CallUpdateRequestImpl.java @@ -0,0 +1,123 @@ +package com.sinch.sdk.domains.voice.models.v1.calls.request; + +import com.fasterxml.jackson.annotation.JsonFilter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; +import com.sinch.sdk.core.models.OptionalValue; +import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionPatch; +import com.sinch.sdk.domains.voice.models.v1.svaml.instruction.SvamlInstruction; +import java.util.Collection; +import java.util.Objects; + +@JsonPropertyOrder({ + CallUpdateRequestImpl.JSON_PROPERTY_INSTRUCTIONS, + CallUpdateRequestImpl.JSON_PROPERTY_ACTION +}) +@JsonFilter("uninitializedFilter") +@JsonInclude(value = JsonInclude.Include.CUSTOM) +public class CallUpdateRequestImpl implements CallUpdateRequest { + private static final long serialVersionUID = 1L; + + public static final String JSON_PROPERTY_INSTRUCTIONS = "instructions"; + + private OptionalValue> instructions; + + public static final String JSON_PROPERTY_ACTION = "action"; + + private OptionalValue action; + + public CallUpdateRequestImpl() {} + + protected CallUpdateRequestImpl( + OptionalValue> instructions, + OptionalValue action) { + this.instructions = instructions; + this.action = action; + } + + @JsonIgnore + public Collection getInstructions() { + return instructions.orElse(null); + } + + @JsonProperty(JSON_PROPERTY_INSTRUCTIONS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public OptionalValue> instructions() { + return instructions; + } + + @JsonIgnore + public SvamlActionPatch getAction() { + return action.orElse(null); + } + + @JsonProperty(JSON_PROPERTY_ACTION) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public OptionalValue action() { + return action; + } + + /** Return true if this PATCHSVAMLRequestBody object is equal to o. */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CallUpdateRequestImpl paTCHSVAMLRequestBody = (CallUpdateRequestImpl) o; + return Objects.equals(this.instructions, paTCHSVAMLRequestBody.instructions) + && Objects.equals(this.action, paTCHSVAMLRequestBody.action); + } + + @Override + public int hashCode() { + return Objects.hash(instructions, action); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class CallUpdateRequestImpl {\n"); + sb.append(" instructions: ").append(toIndentedString(instructions)).append("\n"); + sb.append(" action: ").append(toIndentedString(action)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + + @JsonPOJOBuilder(withPrefix = "set") + static class Builder implements CallUpdateRequest.Builder { + OptionalValue> instructions = OptionalValue.empty(); + OptionalValue action = OptionalValue.empty(); + + @JsonProperty(JSON_PROPERTY_INSTRUCTIONS) + public Builder setInstructions(Collection instructions) { + this.instructions = OptionalValue.of(instructions); + return this; + } + + @JsonProperty(JSON_PROPERTY_ACTION) + public Builder setAction(SvamlActionPatch action) { + this.action = OptionalValue.of(action); + return this; + } + + public CallUpdateRequest build() { + return new CallUpdateRequestImpl(instructions, action); + } + } +} diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/internal/SvamlActionPatchInternal.java b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/internal/SvamlActionPatchInternal.java new file mode 100644 index 000000000..8fcd49233 --- /dev/null +++ b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/internal/SvamlActionPatchInternal.java @@ -0,0 +1,17 @@ +/* + * Voice API | Sinch + * + * OpenAPI document version: 1.0.1 + * Contact: support@sinch.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit the class manually. + */ + +package com.sinch.sdk.domains.voice.models.v1.svaml.internal; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +@JsonDeserialize( + using = SvamlActionPatchInternalImpl.SvamlActionPatchInternalImplDeserializer.class) +public interface SvamlActionPatchInternal {} diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/internal/SvamlActionPatchInternalImpl.java b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/internal/SvamlActionPatchInternalImpl.java new file mode 100644 index 000000000..5fadaa722 --- /dev/null +++ b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/internal/SvamlActionPatchInternalImpl.java @@ -0,0 +1,366 @@ +package com.sinch.sdk.domains.voice.models.v1.svaml.internal; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import com.sinch.sdk.core.models.AbstractOpenApiSchema; +import com.sinch.sdk.core.utils.databind.JSONNavigator; +import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionContinueImpl; +import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionHangupImpl; +import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionParkImpl; +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +@JsonDeserialize( + using = SvamlActionPatchInternalImpl.SvamlActionPatchInternalImplDeserializer.class) +@JsonSerialize(using = SvamlActionPatchInternalImpl.SvamlActionPatchInternalImplSerializer.class) +public class SvamlActionPatchInternalImpl extends AbstractOpenApiSchema + implements SvamlActionPatchInternal { + private static final Logger log = Logger.getLogger(SvamlActionPatchInternalImpl.class.getName()); + + public static final class SvamlActionPatchInternalImplSerializer + extends StdSerializer { + private static final long serialVersionUID = 1L; + + public SvamlActionPatchInternalImplSerializer(Class t) { + super(t); + } + + public SvamlActionPatchInternalImplSerializer() { + this(null); + } + + @Override + public void serialize( + SvamlActionPatchInternalImpl value, JsonGenerator jgen, SerializerProvider provider) + throws IOException, JsonProcessingException { + jgen.writeObject(value.getActualInstance()); + } + } + + public static final class SvamlActionPatchInternalImplDeserializer + extends StdDeserializer { + + private static final long serialVersionUID = 1L; + + public SvamlActionPatchInternalImplDeserializer() { + this(SvamlActionPatchInternalImpl.class); + } + + public SvamlActionPatchInternalImplDeserializer(Class vc) { + super(vc); + } + + @Override + public SvamlActionPatchInternalImpl deserialize(JsonParser jp, DeserializationContext ctxt) + throws IOException, JsonProcessingException { + JsonNode tree = jp.readValueAsTree(); + Object deserialized = null; + SvamlActionPatchInternalImpl newSvamlActionPatchInternalImpl = + new SvamlActionPatchInternalImpl(); + Map result2 = + tree.traverse(jp.getCodec()).readValueAs(new TypeReference>() {}); + String discriminatorValue = (String) result2.get("name"); + switch (discriminatorValue) { + case "continue": + deserialized = tree.traverse(jp.getCodec()).readValueAs(SvamlActionContinueImpl.class); + newSvamlActionPatchInternalImpl.setActualInstance(deserialized); + return newSvamlActionPatchInternalImpl; + case "hangup": + deserialized = tree.traverse(jp.getCodec()).readValueAs(SvamlActionHangupImpl.class); + newSvamlActionPatchInternalImpl.setActualInstance(deserialized); + return newSvamlActionPatchInternalImpl; + case "park": + deserialized = tree.traverse(jp.getCodec()).readValueAs(SvamlActionParkImpl.class); + newSvamlActionPatchInternalImpl.setActualInstance(deserialized); + return newSvamlActionPatchInternalImpl; + default: + log.log( + Level.WARNING, + String.format( + "Failed to lookup discriminator value `%s` for SvamlActionPatchInternalImpl." + + " Possible values: continue hangup park", + discriminatorValue)); + } + + boolean typeCoercion = ctxt.isEnabled(MapperFeature.ALLOW_COERCION_OF_SCALARS); + int match = 0; + JsonToken token = tree.traverse(jp.getCodec()).nextToken(); + // deserialize SvamlActionContinueImpl + try { + boolean attemptParsing = true; + // ensure that we respect type coercion as set on the client ObjectMapper + if (SvamlActionContinueImpl.class.equals(Integer.class) + || SvamlActionContinueImpl.class.equals(Long.class) + || SvamlActionContinueImpl.class.equals(Float.class) + || SvamlActionContinueImpl.class.equals(Double.class) + || SvamlActionContinueImpl.class.equals(Boolean.class) + || SvamlActionContinueImpl.class.equals(String.class)) { + attemptParsing = typeCoercion; + if (!attemptParsing) { + attemptParsing |= + ((SvamlActionContinueImpl.class.equals(Integer.class) + || SvamlActionContinueImpl.class.equals(Long.class)) + && token == JsonToken.VALUE_NUMBER_INT); + attemptParsing |= + ((SvamlActionContinueImpl.class.equals(Float.class) + || SvamlActionContinueImpl.class.equals(Double.class)) + && token == JsonToken.VALUE_NUMBER_FLOAT); + attemptParsing |= + (SvamlActionContinueImpl.class.equals(Boolean.class) + && (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE)); + attemptParsing |= + (SvamlActionContinueImpl.class.equals(String.class) + && token == JsonToken.VALUE_STRING); + } + } + if (attemptParsing) { + deserialized = tree.traverse(jp.getCodec()).readValueAs(SvamlActionContinueImpl.class); + // TODO: there is no validation against JSON schema constraints + // (min, max, enum, pattern...), this does not perform a strict JSON + // validation, which means the 'match' count may be higher than it should be. + match++; + log.log(Level.FINER, "Input data matches schema 'SvamlActionContinueImpl'"); + } + } catch (Exception e) { + // deserialization failed, continue + log.log(Level.FINER, "Input data does not match schema 'SvamlActionContinueImpl'", e); + } + + // deserialize SvamlActionHangupImpl + try { + boolean attemptParsing = true; + // ensure that we respect type coercion as set on the client ObjectMapper + if (SvamlActionHangupImpl.class.equals(Integer.class) + || SvamlActionHangupImpl.class.equals(Long.class) + || SvamlActionHangupImpl.class.equals(Float.class) + || SvamlActionHangupImpl.class.equals(Double.class) + || SvamlActionHangupImpl.class.equals(Boolean.class) + || SvamlActionHangupImpl.class.equals(String.class)) { + attemptParsing = typeCoercion; + if (!attemptParsing) { + attemptParsing |= + ((SvamlActionHangupImpl.class.equals(Integer.class) + || SvamlActionHangupImpl.class.equals(Long.class)) + && token == JsonToken.VALUE_NUMBER_INT); + attemptParsing |= + ((SvamlActionHangupImpl.class.equals(Float.class) + || SvamlActionHangupImpl.class.equals(Double.class)) + && token == JsonToken.VALUE_NUMBER_FLOAT); + attemptParsing |= + (SvamlActionHangupImpl.class.equals(Boolean.class) + && (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE)); + attemptParsing |= + (SvamlActionHangupImpl.class.equals(String.class) + && token == JsonToken.VALUE_STRING); + } + } + if (attemptParsing) { + deserialized = tree.traverse(jp.getCodec()).readValueAs(SvamlActionHangupImpl.class); + // TODO: there is no validation against JSON schema constraints + // (min, max, enum, pattern...), this does not perform a strict JSON + // validation, which means the 'match' count may be higher than it should be. + match++; + log.log(Level.FINER, "Input data matches schema 'SvamlActionHangupImpl'"); + } + } catch (Exception e) { + // deserialization failed, continue + log.log(Level.FINER, "Input data does not match schema 'SvamlActionHangupImpl'", e); + } + + // deserialize SvamlActionParkImpl + try { + boolean attemptParsing = true; + // ensure that we respect type coercion as set on the client ObjectMapper + if (SvamlActionParkImpl.class.equals(Integer.class) + || SvamlActionParkImpl.class.equals(Long.class) + || SvamlActionParkImpl.class.equals(Float.class) + || SvamlActionParkImpl.class.equals(Double.class) + || SvamlActionParkImpl.class.equals(Boolean.class) + || SvamlActionParkImpl.class.equals(String.class)) { + attemptParsing = typeCoercion; + if (!attemptParsing) { + attemptParsing |= + ((SvamlActionParkImpl.class.equals(Integer.class) + || SvamlActionParkImpl.class.equals(Long.class)) + && token == JsonToken.VALUE_NUMBER_INT); + attemptParsing |= + ((SvamlActionParkImpl.class.equals(Float.class) + || SvamlActionParkImpl.class.equals(Double.class)) + && token == JsonToken.VALUE_NUMBER_FLOAT); + attemptParsing |= + (SvamlActionParkImpl.class.equals(Boolean.class) + && (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE)); + attemptParsing |= + (SvamlActionParkImpl.class.equals(String.class) && token == JsonToken.VALUE_STRING); + } + } + if (attemptParsing) { + deserialized = tree.traverse(jp.getCodec()).readValueAs(SvamlActionParkImpl.class); + // TODO: there is no validation against JSON schema constraints + // (min, max, enum, pattern...), this does not perform a strict JSON + // validation, which means the 'match' count may be higher than it should be. + match++; + log.log(Level.FINER, "Input data matches schema 'SvamlActionParkImpl'"); + } + } catch (Exception e) { + // deserialization failed, continue + log.log(Level.FINER, "Input data does not match schema 'SvamlActionParkImpl'", e); + } + + if (match == 1) { + SvamlActionPatchInternalImpl ret = new SvamlActionPatchInternalImpl(); + ret.setActualInstance(deserialized); + return ret; + } + throw new IOException( + String.format( + "Failed deserialization for SvamlActionPatchInternalImpl: %d classes match result," + + " expected 1", + match)); + } + + /** Handle deserialization of the 'null' value. */ + @Override + public SvamlActionPatchInternalImpl getNullValue(DeserializationContext ctxt) + throws JsonMappingException { + throw new JsonMappingException( + ctxt.getParser(), "SvamlActionPatchInternalImpl cannot be null"); + } + } + + // store a list of schema names defined in oneOf + public static final Map> schemas = new HashMap<>(); + + public SvamlActionPatchInternalImpl() { + super("oneOf", Boolean.FALSE); + } + + public SvamlActionPatchInternalImpl(SvamlActionContinueImpl o) { + super("oneOf", Boolean.FALSE); + setActualInstance(o); + } + + public SvamlActionPatchInternalImpl(SvamlActionHangupImpl o) { + super("oneOf", Boolean.FALSE); + setActualInstance(o); + } + + public SvamlActionPatchInternalImpl(SvamlActionParkImpl o) { + super("oneOf", Boolean.FALSE); + setActualInstance(o); + } + + static { + schemas.put("SvamlActionContinueImpl", SvamlActionContinueImpl.class); + schemas.put("SvamlActionHangupImpl", SvamlActionHangupImpl.class); + schemas.put("SvamlActionParkImpl", SvamlActionParkImpl.class); + JSONNavigator.registerDescendants( + SvamlActionPatchInternalImpl.class, Collections.unmodifiableMap(schemas)); + // Initialize and register the discriminator mappings. + Map> mappings = new HashMap>(); + mappings.put("continue", SvamlActionContinueImpl.class); + mappings.put("hangup", SvamlActionHangupImpl.class); + mappings.put("park", SvamlActionParkImpl.class); + mappings.put("svaml.action.patch", SvamlActionPatchInternalImpl.class); + JSONNavigator.registerDiscriminator(SvamlActionPatchInternalImpl.class, "name", mappings); + } + + @Override + public Map> getSchemas() { + return SvamlActionPatchInternalImpl.schemas; + } + + /** + * Set the instance that matches the oneOf child schema, check the instance parameter is valid + * against the oneOf child schemas: SvamlActionContinueImpl, SvamlActionHangupImpl, + * SvamlActionParkImpl + * + *

It could be an instance of the 'oneOf' schemas. The oneOf child schemas may themselves be a + * composed schema (allOf, anyOf, oneOf). + */ + @Override + public void setActualInstance(Object instance) { + if (JSONNavigator.isInstanceOf( + SvamlActionContinueImpl.class, instance, new HashSet>())) { + super.setActualInstance(instance); + return; + } + + if (JSONNavigator.isInstanceOf( + SvamlActionHangupImpl.class, instance, new HashSet>())) { + super.setActualInstance(instance); + return; + } + + if (JSONNavigator.isInstanceOf(SvamlActionParkImpl.class, instance, new HashSet>())) { + super.setActualInstance(instance); + return; + } + + throw new RuntimeException( + "Invalid instance type. Must be SvamlActionContinueImpl, SvamlActionHangupImpl," + + " SvamlActionParkImpl"); + } + + /** + * Get the actual instance, which can be the following: SvamlActionContinueImpl, + * SvamlActionHangupImpl, SvamlActionParkImpl + * + * @return The actual instance (SvamlActionContinueImpl, SvamlActionHangupImpl, + * SvamlActionParkImpl) + */ + @Override + public Object getActualInstance() { + return super.getActualInstance(); + } + + /** + * Get the actual instance of `SvamlActionContinueImpl`. If the actual instance is not + * `SvamlActionContinueImpl`, the ClassCastException will be thrown. + * + * @return The actual instance of `SvamlActionContinueImpl` + * @throws ClassCastException if the instance is not `SvamlActionContinueImpl` + */ + public SvamlActionContinueImpl getSvamlActionContinueImpl() throws ClassCastException { + return (SvamlActionContinueImpl) super.getActualInstance(); + } + + /** + * Get the actual instance of `SvamlActionHangupImpl`. If the actual instance is not + * `SvamlActionHangupImpl`, the ClassCastException will be thrown. + * + * @return The actual instance of `SvamlActionHangupImpl` + * @throws ClassCastException if the instance is not `SvamlActionHangupImpl` + */ + public SvamlActionHangupImpl getSvamlActionHangupImpl() throws ClassCastException { + return (SvamlActionHangupImpl) super.getActualInstance(); + } + + /** + * Get the actual instance of `SvamlActionParkImpl`. If the actual instance is not + * `SvamlActionParkImpl`, the ClassCastException will be thrown. + * + * @return The actual instance of `SvamlActionParkImpl` + * @throws ClassCastException if the instance is not `SvamlActionParkImpl` + */ + public SvamlActionParkImpl getSvamlActionParkImpl() throws ClassCastException { + return (SvamlActionParkImpl) super.getActualInstance(); + } +} diff --git a/openapi-contracts/src/test/java/com/sinch/sdk/domains/voice/models/v1/calls/request/CallUpdateRequestTest.java b/openapi-contracts/src/test/java/com/sinch/sdk/domains/voice/models/v1/calls/request/CallUpdateRequestTest.java new file mode 100644 index 000000000..5da9707ad --- /dev/null +++ b/openapi-contracts/src/test/java/com/sinch/sdk/domains/voice/models/v1/calls/request/CallUpdateRequestTest.java @@ -0,0 +1,38 @@ +package com.sinch.sdk.domains.voice.models.v1.calls.request; + +import com.adelean.inject.resources.junit.jupiter.GivenTextResource; +import com.adelean.inject.resources.junit.jupiter.TestWithResources; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.sinch.sdk.BaseTest; +import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionHangup; +import com.sinch.sdk.domains.voice.models.v1.svaml.instruction.SvamlInstructionSay; +import java.util.Arrays; +import org.json.JSONException; +import org.junit.jupiter.api.Test; +import org.skyscreamer.jsonassert.JSONAssert; + +@TestWithResources +public class CallUpdateRequestTest extends BaseTest { + + public static CallUpdateRequest expectedCallUpdateRequest = + CallUpdateRequest.builder() + .setAction(SvamlActionHangup.SVAML_ACTION_HANGUP) + .setInstructions( + Arrays.asList( + SvamlInstructionSay.builder() + .setText("Sorry, the conference has been cancelled. The call will end now.") + .setLocale("en-US") + .build())) + .build(); + + @GivenTextResource("/domains/voice/v1/calls/request/CallUpdateRequestDto.json") + String jsonCallUpdateRequestDto; + + @Test + void serializeCallUpdateRequest() throws JsonProcessingException, JSONException { + + String serializedString = objectMapper.writeValueAsString(expectedCallUpdateRequest); + + JSONAssert.assertEquals(jsonCallUpdateRequestDto, serializedString, true); + } +} diff --git a/openapi-contracts/src/test/resources/domains/voice/v1/calls/request/CallUpdateRequestDto.json b/openapi-contracts/src/test/resources/domains/voice/v1/calls/request/CallUpdateRequestDto.json new file mode 100644 index 000000000..1640c9049 --- /dev/null +++ b/openapi-contracts/src/test/resources/domains/voice/v1/calls/request/CallUpdateRequestDto.json @@ -0,0 +1,12 @@ +{ + "instructions": [ + { + "name": "say", + "text": "Sorry, the conference has been cancelled. The call will end now.", + "locale": "en-US" + } + ], + "action": { + "name": "hangup" + } +} From 896879d7df21f40e69cc890c671467656113bfc2 Mon Sep 17 00:00:00 2001 From: Eduardo San Segundo Date: Fri, 19 Jun 2026 09:17:36 +0200 Subject: [PATCH 4/4] Voice: rename SvamlActionPatch to ManagedCallSvamlAction, generated sources and remove duplicated test --- .../svaml/action/ManagedCallSvamlAction.java | 12 + .../v1/svaml/action/SvamlActionPatch.java | 9 - .../java/voice/calls/ManageWithCallLeg.java | 4 +- .../src/main/java/voice/calls/Update.java | 4 +- .../v1/calls/request/CallUpdateRequest.java | 6 +- .../calls/request/CallUpdateRequestImpl.java | 14 +- .../v1/calls/request/SvamlActionPatch.java | 16 - .../calls/request/SvamlActionPatchImpl.java | 362 ------------------ .../v1/calls/request/SvamlControlPatch.java | 78 ---- .../calls/request/SvamlControlPatchImpl.java | 124 ------ .../v1/svaml/action/SvamlActionContinue.java | 2 +- .../svaml/action/SvamlActionContinueImpl.java | 2 +- .../v1/svaml/action/SvamlActionHangup.java | 2 +- .../svaml/action/SvamlActionHangupImpl.java | 2 +- .../v1/svaml/action/SvamlActionPark.java | 2 +- .../v1/svaml/action/SvamlActionParkImpl.java | 2 +- .../v1/svaml/SvamlControlPatchTest.java | 39 -- .../voice/v1/svaml/SvamlControlPatchDto.json | 12 - 18 files changed, 32 insertions(+), 660 deletions(-) create mode 100644 client/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/ManagedCallSvamlAction.java delete mode 100644 client/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionPatch.java delete mode 100644 openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlActionPatch.java delete mode 100644 openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlActionPatchImpl.java delete mode 100644 openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlControlPatch.java delete mode 100644 openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlControlPatchImpl.java delete mode 100644 openapi-contracts/src/test/java/com/sinch/sdk/domains/voice/models/v1/svaml/SvamlControlPatchTest.java delete mode 100644 openapi-contracts/src/test/resources/domains/voice/v1/svaml/SvamlControlPatchDto.json diff --git a/client/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/ManagedCallSvamlAction.java b/client/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/ManagedCallSvamlAction.java new file mode 100644 index 000000000..dbc22d00a --- /dev/null +++ b/client/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/ManagedCallSvamlAction.java @@ -0,0 +1,12 @@ +package com.sinch.sdk.domains.voice.models.v1.svaml.action; + +/** + * Base class related to SVAML actions available for managing ongoing, connected calls (updateCall + * and manageCallWithCallLeg). + * + * @see SvamlActionHangup + * @see SvamlActionContinue + * @see SvamlActionPark + * @since 2.1 + */ +public interface ManagedCallSvamlAction {} diff --git a/client/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionPatch.java b/client/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionPatch.java deleted file mode 100644 index aac08730d..000000000 --- a/client/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionPatch.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.sinch.sdk.domains.voice.models.v1.svaml.action; - -/** - * Base class related to SVAML actions available for PATCH call operations (updateCall and - * manageCallWithCallLeg). Only hangup, continue and park actions are supported. - * - * @since 2.1 - */ -public interface SvamlActionPatch {} diff --git a/examples/snippets/src/main/java/voice/calls/ManageWithCallLeg.java b/examples/snippets/src/main/java/voice/calls/ManageWithCallLeg.java index d03127cb1..56207a989 100644 --- a/examples/snippets/src/main/java/voice/calls/ManageWithCallLeg.java +++ b/examples/snippets/src/main/java/voice/calls/ManageWithCallLeg.java @@ -11,8 +11,8 @@ import com.sinch.sdk.domains.voice.api.v1.CallsService; import com.sinch.sdk.domains.voice.models.v1.calls.request.CallLeg; import com.sinch.sdk.domains.voice.models.v1.calls.request.CallUpdateRequest; +import com.sinch.sdk.domains.voice.models.v1.svaml.action.ManagedCallSvamlAction; import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionHangup; -import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionPatch; import com.sinch.sdk.domains.voice.models.v1.svaml.instruction.SvamlInstruction; import com.sinch.sdk.domains.voice.models.v1.svaml.instruction.SvamlInstructionSay; import com.sinch.sdk.models.Configuration; @@ -47,7 +47,7 @@ public static void main(String[] args) { LOGGER.info(String.format("Manage call with ID '%s'", callId)); - SvamlActionPatch action = SvamlActionHangup.SVAML_ACTION_HANGUP; + ManagedCallSvamlAction action = SvamlActionHangup.SVAML_ACTION_HANGUP; Collection instructions = Collections.singletonList( diff --git a/examples/snippets/src/main/java/voice/calls/Update.java b/examples/snippets/src/main/java/voice/calls/Update.java index a25d298c6..bcd6c03c2 100644 --- a/examples/snippets/src/main/java/voice/calls/Update.java +++ b/examples/snippets/src/main/java/voice/calls/Update.java @@ -10,8 +10,8 @@ import com.sinch.sdk.SinchClient; import com.sinch.sdk.domains.voice.api.v1.CallsService; import com.sinch.sdk.domains.voice.models.v1.calls.request.CallUpdateRequest; +import com.sinch.sdk.domains.voice.models.v1.svaml.action.ManagedCallSvamlAction; import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionHangup; -import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionPatch; import com.sinch.sdk.domains.voice.models.v1.svaml.instruction.SvamlInstruction; import com.sinch.sdk.domains.voice.models.v1.svaml.instruction.SvamlInstructionSay; import com.sinch.sdk.models.Configuration; @@ -34,7 +34,7 @@ public static void main(String[] args) { // The instruction to be performed SvamlInstruction instruction = SvamlInstructionSay.builder().setText("Goodbye").build(); // The instruction to add to the call - SvamlActionPatch action = SvamlActionHangup.SVAML_ACTION_HANGUP; + ManagedCallSvamlAction action = SvamlActionHangup.SVAML_ACTION_HANGUP; Configuration configuration = Configuration.builder() diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/CallUpdateRequest.java b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/CallUpdateRequest.java index 39221bc4d..6d8645fc6 100644 --- a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/CallUpdateRequest.java +++ b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/CallUpdateRequest.java @@ -11,7 +11,7 @@ package com.sinch.sdk.domains.voice.models.v1.calls.request; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionPatch; +import com.sinch.sdk.domains.voice.models.v1.svaml.action.ManagedCallSvamlAction; import com.sinch.sdk.domains.voice.models.v1.svaml.instruction.SvamlInstruction; import java.util.Collection; @@ -36,7 +36,7 @@ public interface CallUpdateRequest { * * @return action */ - SvamlActionPatch getAction(); + ManagedCallSvamlAction getAction(); /** * Getting builder @@ -66,7 +66,7 @@ interface Builder { * @return Current builder * @see #getAction */ - Builder setAction(SvamlActionPatch action); + Builder setAction(ManagedCallSvamlAction action); /** * Create instance diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/CallUpdateRequestImpl.java b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/CallUpdateRequestImpl.java index 7ba595fa6..86be341d7 100644 --- a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/CallUpdateRequestImpl.java +++ b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/CallUpdateRequestImpl.java @@ -7,7 +7,7 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; import com.sinch.sdk.core.models.OptionalValue; -import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionPatch; +import com.sinch.sdk.domains.voice.models.v1.svaml.action.ManagedCallSvamlAction; import com.sinch.sdk.domains.voice.models.v1.svaml.instruction.SvamlInstruction; import java.util.Collection; import java.util.Objects; @@ -27,13 +27,13 @@ public class CallUpdateRequestImpl implements CallUpdateRequest { public static final String JSON_PROPERTY_ACTION = "action"; - private OptionalValue action; + private OptionalValue action; public CallUpdateRequestImpl() {} protected CallUpdateRequestImpl( OptionalValue> instructions, - OptionalValue action) { + OptionalValue action) { this.instructions = instructions; this.action = action; } @@ -50,13 +50,13 @@ public OptionalValue> instructions() { } @JsonIgnore - public SvamlActionPatch getAction() { + public ManagedCallSvamlAction getAction() { return action.orElse(null); } @JsonProperty(JSON_PROPERTY_ACTION) @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public OptionalValue action() { + public OptionalValue action() { return action; } @@ -102,7 +102,7 @@ private String toIndentedString(Object o) { @JsonPOJOBuilder(withPrefix = "set") static class Builder implements CallUpdateRequest.Builder { OptionalValue> instructions = OptionalValue.empty(); - OptionalValue action = OptionalValue.empty(); + OptionalValue action = OptionalValue.empty(); @JsonProperty(JSON_PROPERTY_INSTRUCTIONS) public Builder setInstructions(Collection instructions) { @@ -111,7 +111,7 @@ public Builder setInstructions(Collection instructions) { } @JsonProperty(JSON_PROPERTY_ACTION) - public Builder setAction(SvamlActionPatch action) { + public Builder setAction(ManagedCallSvamlAction action) { this.action = OptionalValue.of(action); return this; } diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlActionPatch.java b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlActionPatch.java deleted file mode 100644 index c618d66f4..000000000 --- a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlActionPatch.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Voice API | Sinch - * - * OpenAPI document version: 1.0.1 - * Contact: support@sinch.com - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * Do not edit the class manually. - */ - -package com.sinch.sdk.domains.voice.models.v1.calls.request; - -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -@JsonDeserialize(using = SvamlActionPatchImpl.SvamlActionPatchImplDeserializer.class) -public interface SvamlActionPatch {} diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlActionPatchImpl.java b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlActionPatchImpl.java deleted file mode 100644 index 98f6e10bf..000000000 --- a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlActionPatchImpl.java +++ /dev/null @@ -1,362 +0,0 @@ -package com.sinch.sdk.domains.voice.models.v1.calls.request; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.MapperFeature; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.deser.std.StdDeserializer; -import com.fasterxml.jackson.databind.ser.std.StdSerializer; -import com.sinch.sdk.core.models.AbstractOpenApiSchema; -import com.sinch.sdk.core.utils.databind.JSONNavigator; -import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionContinueImpl; -import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionHangupImpl; -import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionParkImpl; -import java.io.IOException; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; - -@JsonDeserialize(using = SvamlActionPatchImpl.SvamlActionPatchImplDeserializer.class) -@JsonSerialize(using = SvamlActionPatchImpl.SvamlActionPatchImplSerializer.class) -public class SvamlActionPatchImpl extends AbstractOpenApiSchema implements SvamlActionPatch { - private static final Logger log = Logger.getLogger(SvamlActionPatchImpl.class.getName()); - - public static final class SvamlActionPatchImplSerializer - extends StdSerializer { - private static final long serialVersionUID = 1L; - - public SvamlActionPatchImplSerializer(Class t) { - super(t); - } - - public SvamlActionPatchImplSerializer() { - this(null); - } - - @Override - public void serialize( - SvamlActionPatchImpl value, JsonGenerator jgen, SerializerProvider provider) - throws IOException, JsonProcessingException { - jgen.writeObject(value.getActualInstance()); - } - } - - public static final class SvamlActionPatchImplDeserializer - extends StdDeserializer { - - private static final long serialVersionUID = 1L; - - public SvamlActionPatchImplDeserializer() { - this(SvamlActionPatchImpl.class); - } - - public SvamlActionPatchImplDeserializer(Class vc) { - super(vc); - } - - @Override - public SvamlActionPatchImpl deserialize(JsonParser jp, DeserializationContext ctxt) - throws IOException, JsonProcessingException { - JsonNode tree = jp.readValueAsTree(); - Object deserialized = null; - SvamlActionPatchImpl newSvamlActionPatchImpl = new SvamlActionPatchImpl(); - Map result2 = - tree.traverse(jp.getCodec()).readValueAs(new TypeReference>() {}); - String discriminatorValue = (String) result2.get("name"); - switch (discriminatorValue) { - case "continue": - deserialized = tree.traverse(jp.getCodec()).readValueAs(SvamlActionContinueImpl.class); - newSvamlActionPatchImpl.setActualInstance(deserialized); - return newSvamlActionPatchImpl; - case "hangup": - deserialized = tree.traverse(jp.getCodec()).readValueAs(SvamlActionHangupImpl.class); - newSvamlActionPatchImpl.setActualInstance(deserialized); - return newSvamlActionPatchImpl; - case "park": - deserialized = tree.traverse(jp.getCodec()).readValueAs(SvamlActionParkImpl.class); - newSvamlActionPatchImpl.setActualInstance(deserialized); - return newSvamlActionPatchImpl; - default: - log.log( - Level.WARNING, - String.format( - "Failed to lookup discriminator value `%s` for SvamlActionPatchImpl. Possible" - + " values: continue hangup park", - discriminatorValue)); - } - - boolean typeCoercion = ctxt.isEnabled(MapperFeature.ALLOW_COERCION_OF_SCALARS); - int match = 0; - JsonToken token = tree.traverse(jp.getCodec()).nextToken(); - // deserialize SvamlActionContinueImpl - try { - boolean attemptParsing = true; - // ensure that we respect type coercion as set on the client ObjectMapper - if (SvamlActionContinueImpl.class.equals(Integer.class) - || SvamlActionContinueImpl.class.equals(Long.class) - || SvamlActionContinueImpl.class.equals(Float.class) - || SvamlActionContinueImpl.class.equals(Double.class) - || SvamlActionContinueImpl.class.equals(Boolean.class) - || SvamlActionContinueImpl.class.equals(String.class)) { - attemptParsing = typeCoercion; - if (!attemptParsing) { - attemptParsing |= - ((SvamlActionContinueImpl.class.equals(Integer.class) - || SvamlActionContinueImpl.class.equals(Long.class)) - && token == JsonToken.VALUE_NUMBER_INT); - attemptParsing |= - ((SvamlActionContinueImpl.class.equals(Float.class) - || SvamlActionContinueImpl.class.equals(Double.class)) - && token == JsonToken.VALUE_NUMBER_FLOAT); - attemptParsing |= - (SvamlActionContinueImpl.class.equals(Boolean.class) - && (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE)); - attemptParsing |= - (SvamlActionContinueImpl.class.equals(String.class) - && token == JsonToken.VALUE_STRING); - } - } - if (attemptParsing) { - deserialized = tree.traverse(jp.getCodec()).readValueAs(SvamlActionContinueImpl.class); - // TODO: there is no validation against JSON schema constraints - // (min, max, enum, pattern...), this does not perform a strict JSON - // validation, which means the 'match' count may be higher than it should be. - match++; - log.log(Level.FINER, "Input data matches schema 'SvamlActionContinueImpl'"); - } - } catch (Exception e) { - // deserialization failed, continue - log.log(Level.FINER, "Input data does not match schema 'SvamlActionContinueImpl'", e); - } - - // deserialize SvamlActionHangupImpl - try { - boolean attemptParsing = true; - // ensure that we respect type coercion as set on the client ObjectMapper - if (SvamlActionHangupImpl.class.equals(Integer.class) - || SvamlActionHangupImpl.class.equals(Long.class) - || SvamlActionHangupImpl.class.equals(Float.class) - || SvamlActionHangupImpl.class.equals(Double.class) - || SvamlActionHangupImpl.class.equals(Boolean.class) - || SvamlActionHangupImpl.class.equals(String.class)) { - attemptParsing = typeCoercion; - if (!attemptParsing) { - attemptParsing |= - ((SvamlActionHangupImpl.class.equals(Integer.class) - || SvamlActionHangupImpl.class.equals(Long.class)) - && token == JsonToken.VALUE_NUMBER_INT); - attemptParsing |= - ((SvamlActionHangupImpl.class.equals(Float.class) - || SvamlActionHangupImpl.class.equals(Double.class)) - && token == JsonToken.VALUE_NUMBER_FLOAT); - attemptParsing |= - (SvamlActionHangupImpl.class.equals(Boolean.class) - && (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE)); - attemptParsing |= - (SvamlActionHangupImpl.class.equals(String.class) - && token == JsonToken.VALUE_STRING); - } - } - if (attemptParsing) { - deserialized = tree.traverse(jp.getCodec()).readValueAs(SvamlActionHangupImpl.class); - // TODO: there is no validation against JSON schema constraints - // (min, max, enum, pattern...), this does not perform a strict JSON - // validation, which means the 'match' count may be higher than it should be. - match++; - log.log(Level.FINER, "Input data matches schema 'SvamlActionHangupImpl'"); - } - } catch (Exception e) { - // deserialization failed, continue - log.log(Level.FINER, "Input data does not match schema 'SvamlActionHangupImpl'", e); - } - - // deserialize SvamlActionParkImpl - try { - boolean attemptParsing = true; - // ensure that we respect type coercion as set on the client ObjectMapper - if (SvamlActionParkImpl.class.equals(Integer.class) - || SvamlActionParkImpl.class.equals(Long.class) - || SvamlActionParkImpl.class.equals(Float.class) - || SvamlActionParkImpl.class.equals(Double.class) - || SvamlActionParkImpl.class.equals(Boolean.class) - || SvamlActionParkImpl.class.equals(String.class)) { - attemptParsing = typeCoercion; - if (!attemptParsing) { - attemptParsing |= - ((SvamlActionParkImpl.class.equals(Integer.class) - || SvamlActionParkImpl.class.equals(Long.class)) - && token == JsonToken.VALUE_NUMBER_INT); - attemptParsing |= - ((SvamlActionParkImpl.class.equals(Float.class) - || SvamlActionParkImpl.class.equals(Double.class)) - && token == JsonToken.VALUE_NUMBER_FLOAT); - attemptParsing |= - (SvamlActionParkImpl.class.equals(Boolean.class) - && (token == JsonToken.VALUE_FALSE || token == JsonToken.VALUE_TRUE)); - attemptParsing |= - (SvamlActionParkImpl.class.equals(String.class) && token == JsonToken.VALUE_STRING); - } - } - if (attemptParsing) { - deserialized = tree.traverse(jp.getCodec()).readValueAs(SvamlActionParkImpl.class); - // TODO: there is no validation against JSON schema constraints - // (min, max, enum, pattern...), this does not perform a strict JSON - // validation, which means the 'match' count may be higher than it should be. - match++; - log.log(Level.FINER, "Input data matches schema 'SvamlActionParkImpl'"); - } - } catch (Exception e) { - // deserialization failed, continue - log.log(Level.FINER, "Input data does not match schema 'SvamlActionParkImpl'", e); - } - - if (match == 1) { - SvamlActionPatchImpl ret = new SvamlActionPatchImpl(); - ret.setActualInstance(deserialized); - return ret; - } - throw new IOException( - String.format( - "Failed deserialization for SvamlActionPatchImpl: %d classes match result, expected" - + " 1", - match)); - } - - /** Handle deserialization of the 'null' value. */ - @Override - public SvamlActionPatchImpl getNullValue(DeserializationContext ctxt) - throws JsonMappingException { - throw new JsonMappingException(ctxt.getParser(), "SvamlActionPatchImpl cannot be null"); - } - } - - // store a list of schema names defined in oneOf - public static final Map> schemas = new HashMap<>(); - - public SvamlActionPatchImpl() { - super("oneOf", Boolean.FALSE); - } - - public SvamlActionPatchImpl(SvamlActionContinueImpl o) { - super("oneOf", Boolean.FALSE); - setActualInstance(o); - } - - public SvamlActionPatchImpl(SvamlActionHangupImpl o) { - super("oneOf", Boolean.FALSE); - setActualInstance(o); - } - - public SvamlActionPatchImpl(SvamlActionParkImpl o) { - super("oneOf", Boolean.FALSE); - setActualInstance(o); - } - - static { - schemas.put("SvamlActionContinueImpl", SvamlActionContinueImpl.class); - schemas.put("SvamlActionHangupImpl", SvamlActionHangupImpl.class); - schemas.put("SvamlActionParkImpl", SvamlActionParkImpl.class); - JSONNavigator.registerDescendants( - SvamlActionPatchImpl.class, Collections.unmodifiableMap(schemas)); - // Initialize and register the discriminator mappings. - Map> mappings = new HashMap>(); - mappings.put("continue", SvamlActionContinueImpl.class); - mappings.put("hangup", SvamlActionHangupImpl.class); - mappings.put("park", SvamlActionParkImpl.class); - mappings.put("svaml.action.patch", SvamlActionPatchImpl.class); - JSONNavigator.registerDiscriminator(SvamlActionPatchImpl.class, "name", mappings); - } - - @Override - public Map> getSchemas() { - return SvamlActionPatchImpl.schemas; - } - - /** - * Set the instance that matches the oneOf child schema, check the instance parameter is valid - * against the oneOf child schemas: SvamlActionContinueImpl, SvamlActionHangupImpl, - * SvamlActionParkImpl - * - *

It could be an instance of the 'oneOf' schemas. The oneOf child schemas may themselves be a - * composed schema (allOf, anyOf, oneOf). - */ - @Override - public void setActualInstance(Object instance) { - if (JSONNavigator.isInstanceOf( - SvamlActionContinueImpl.class, instance, new HashSet>())) { - super.setActualInstance(instance); - return; - } - - if (JSONNavigator.isInstanceOf( - SvamlActionHangupImpl.class, instance, new HashSet>())) { - super.setActualInstance(instance); - return; - } - - if (JSONNavigator.isInstanceOf(SvamlActionParkImpl.class, instance, new HashSet>())) { - super.setActualInstance(instance); - return; - } - - throw new RuntimeException( - "Invalid instance type. Must be SvamlActionContinueImpl, SvamlActionHangupImpl," - + " SvamlActionParkImpl"); - } - - /** - * Get the actual instance, which can be the following: SvamlActionContinueImpl, - * SvamlActionHangupImpl, SvamlActionParkImpl - * - * @return The actual instance (SvamlActionContinueImpl, SvamlActionHangupImpl, - * SvamlActionParkImpl) - */ - @Override - public Object getActualInstance() { - return super.getActualInstance(); - } - - /** - * Get the actual instance of `SvamlActionContinueImpl`. If the actual instance is not - * `SvamlActionContinueImpl`, the ClassCastException will be thrown. - * - * @return The actual instance of `SvamlActionContinueImpl` - * @throws ClassCastException if the instance is not `SvamlActionContinueImpl` - */ - public SvamlActionContinueImpl getSvamlActionContinueImpl() throws ClassCastException { - return (SvamlActionContinueImpl) super.getActualInstance(); - } - - /** - * Get the actual instance of `SvamlActionHangupImpl`. If the actual instance is not - * `SvamlActionHangupImpl`, the ClassCastException will be thrown. - * - * @return The actual instance of `SvamlActionHangupImpl` - * @throws ClassCastException if the instance is not `SvamlActionHangupImpl` - */ - public SvamlActionHangupImpl getSvamlActionHangupImpl() throws ClassCastException { - return (SvamlActionHangupImpl) super.getActualInstance(); - } - - /** - * Get the actual instance of `SvamlActionParkImpl`. If the actual instance is not - * `SvamlActionParkImpl`, the ClassCastException will be thrown. - * - * @return The actual instance of `SvamlActionParkImpl` - * @throws ClassCastException if the instance is not `SvamlActionParkImpl` - */ - public SvamlActionParkImpl getSvamlActionParkImpl() throws ClassCastException { - return (SvamlActionParkImpl) super.getActualInstance(); - } -} diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlControlPatch.java b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlControlPatch.java deleted file mode 100644 index b48ca0ffb..000000000 --- a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlControlPatch.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Voice API | Sinch - * - * OpenAPI document version: 1.0.1 - * Contact: support@sinch.com - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * Do not edit the class manually. - */ - -package com.sinch.sdk.domains.voice.models.v1.calls.request; - -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionPatch; -import com.sinch.sdk.domains.voice.models.v1.svaml.instruction.SvamlInstruction; -import java.util.Collection; - -/** - * SVAML is a call control markup language. When a server receives a callback event from the Sinch - * platform, it can respond with a SVAML object to control the voice call. The following is an - * example of a SVAML object type and its contents. - */ -@JsonDeserialize(builder = SvamlControlPatchImpl.Builder.class) -public interface SvamlControlPatch extends com.sinch.sdk.domains.voice.models.v1.svaml.Control { - - /** - * The collection of instructions that can perform various tasks during the call. You can include - * as many instructions as necessary. - * - * @return instructions - */ - Collection getInstructions(); - - /** - * Get action - * - * @return action - */ - SvamlActionPatch getAction(); - - /** - * Getting builder - * - * @return New Builder instance - */ - static Builder builder() { - return new SvamlControlPatchImpl.Builder(); - } - - /** Dedicated Builder */ - interface Builder { - - /** - * see getter - * - * @param instructions see getter - * @return Current builder - * @see #getInstructions - */ - Builder setInstructions(Collection instructions); - - /** - * see getter - * - * @param action see getter - * @return Current builder - * @see #getAction - */ - Builder setAction(SvamlActionPatch action); - - /** - * Create instance - * - * @return The instance build with current builder values - */ - SvamlControlPatch build(); - } -} diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlControlPatchImpl.java b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlControlPatchImpl.java deleted file mode 100644 index 8bff22441..000000000 --- a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/calls/request/SvamlControlPatchImpl.java +++ /dev/null @@ -1,124 +0,0 @@ -package com.sinch.sdk.domains.voice.models.v1.calls.request; - -import com.fasterxml.jackson.annotation.JsonFilter; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; -import com.sinch.sdk.core.models.OptionalValue; -import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionPatch; -import com.sinch.sdk.domains.voice.models.v1.svaml.instruction.SvamlInstruction; -import java.util.Collection; -import java.util.Objects; - -@JsonPropertyOrder({ - SvamlControlPatchImpl.JSON_PROPERTY_INSTRUCTIONS, - SvamlControlPatchImpl.JSON_PROPERTY_ACTION -}) -@JsonFilter("uninitializedFilter") -@JsonInclude(value = JsonInclude.Include.CUSTOM) -public class SvamlControlPatchImpl - implements SvamlControlPatch, com.sinch.sdk.domains.voice.models.v1.svaml.Control { - private static final long serialVersionUID = 1L; - - public static final String JSON_PROPERTY_INSTRUCTIONS = "instructions"; - - private OptionalValue> instructions; - - public static final String JSON_PROPERTY_ACTION = "action"; - - private OptionalValue action; - - public SvamlControlPatchImpl() {} - - protected SvamlControlPatchImpl( - OptionalValue> instructions, - OptionalValue action) { - this.instructions = instructions; - this.action = action; - } - - @JsonIgnore - public Collection getInstructions() { - return instructions.orElse(null); - } - - @JsonProperty(JSON_PROPERTY_INSTRUCTIONS) - @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public OptionalValue> instructions() { - return instructions; - } - - @JsonIgnore - public SvamlActionPatch getAction() { - return action.orElse(null); - } - - @JsonProperty(JSON_PROPERTY_ACTION) - @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) - public OptionalValue action() { - return action; - } - - /** Return true if this UpdateCallSVAMLRequestBody object is equal to o. */ - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - SvamlControlPatchImpl updateCallSVAMLRequestBody = (SvamlControlPatchImpl) o; - return Objects.equals(this.instructions, updateCallSVAMLRequestBody.instructions) - && Objects.equals(this.action, updateCallSVAMLRequestBody.action); - } - - @Override - public int hashCode() { - return Objects.hash(instructions, action); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class SvamlControlPatchImpl {\n"); - sb.append(" instructions: ").append(toIndentedString(instructions)).append("\n"); - sb.append(" action: ").append(toIndentedString(action)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - @JsonPOJOBuilder(withPrefix = "set") - static class Builder implements SvamlControlPatch.Builder { - OptionalValue> instructions = OptionalValue.empty(); - OptionalValue action = OptionalValue.empty(); - - @JsonProperty(JSON_PROPERTY_INSTRUCTIONS) - public Builder setInstructions(Collection instructions) { - this.instructions = OptionalValue.of(instructions); - return this; - } - - @JsonProperty(JSON_PROPERTY_ACTION) - public Builder setAction(SvamlActionPatch action) { - this.action = OptionalValue.of(action); - return this; - } - - public SvamlControlPatch build() { - return new SvamlControlPatchImpl(instructions, action); - } - } -} diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionContinue.java b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionContinue.java index 784c2b6e9..8c9ed6c40 100644 --- a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionContinue.java +++ b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionContinue.java @@ -24,7 +24,7 @@ @JsonDeserialize(builder = SvamlActionContinueImpl.Builder.class) public interface SvamlActionContinue extends com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlAction, - com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionPatch { + com.sinch.sdk.domains.voice.models.v1.svaml.action.ManagedCallSvamlAction { /** ready to use action to send a `continue` */ SvamlActionContinue SVAML_ACTION_CONTINUE = SvamlActionContinue.builder().build(); diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionContinueImpl.java b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionContinueImpl.java index 91f182b55..54b1c9b2c 100644 --- a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionContinueImpl.java +++ b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionContinueImpl.java @@ -15,7 +15,7 @@ public class SvamlActionContinueImpl implements SvamlActionContinue, com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlAction, - com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionPatch { + com.sinch.sdk.domains.voice.models.v1.svaml.action.ManagedCallSvamlAction { private static final long serialVersionUID = 1L; public static final String JSON_PROPERTY_NAME = "name"; diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionHangup.java b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionHangup.java index 419dbc3b6..9433b1099 100644 --- a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionHangup.java +++ b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionHangup.java @@ -26,7 +26,7 @@ @JsonDeserialize(builder = SvamlActionHangupImpl.Builder.class) public interface SvamlActionHangup extends com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlAction, - com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionPatch { + com.sinch.sdk.domains.voice.models.v1.svaml.action.ManagedCallSvamlAction { /** ready to use action to send a `hangup` */ SvamlActionHangup SVAML_ACTION_HANGUP = SvamlActionHangup.builder().build(); diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionHangupImpl.java b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionHangupImpl.java index 3d938e358..abdf61e9b 100644 --- a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionHangupImpl.java +++ b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionHangupImpl.java @@ -15,7 +15,7 @@ public class SvamlActionHangupImpl implements SvamlActionHangup, com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlAction, - com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionPatch { + com.sinch.sdk.domains.voice.models.v1.svaml.action.ManagedCallSvamlAction { private static final long serialVersionUID = 1L; public static final String JSON_PROPERTY_NAME = "name"; diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionPark.java b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionPark.java index 69b131dfb..74161aa2a 100644 --- a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionPark.java +++ b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionPark.java @@ -25,7 +25,7 @@ @JsonDeserialize(builder = SvamlActionParkImpl.Builder.class) public interface SvamlActionPark extends com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlAction, - com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionPatch { + com.sinch.sdk.domains.voice.models.v1.svaml.action.ManagedCallSvamlAction { /** The name property. Must have the value park. */ public class NameEnum extends EnumDynamic { diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionParkImpl.java b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionParkImpl.java index 72fe17653..73577fdc3 100644 --- a/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionParkImpl.java +++ b/openapi-contracts/src/main/com/sinch/sdk/domains/voice/models/v1/svaml/action/SvamlActionParkImpl.java @@ -21,7 +21,7 @@ public class SvamlActionParkImpl implements SvamlActionPark, com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlAction, - com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionPatch { + com.sinch.sdk.domains.voice.models.v1.svaml.action.ManagedCallSvamlAction { private static final long serialVersionUID = 1L; public static final String JSON_PROPERTY_NAME = "name"; diff --git a/openapi-contracts/src/test/java/com/sinch/sdk/domains/voice/models/v1/svaml/SvamlControlPatchTest.java b/openapi-contracts/src/test/java/com/sinch/sdk/domains/voice/models/v1/svaml/SvamlControlPatchTest.java deleted file mode 100644 index 3ffb58741..000000000 --- a/openapi-contracts/src/test/java/com/sinch/sdk/domains/voice/models/v1/svaml/SvamlControlPatchTest.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.sinch.sdk.domains.voice.models.v1.svaml; - -import com.adelean.inject.resources.junit.jupiter.GivenTextResource; -import com.adelean.inject.resources.junit.jupiter.TestWithResources; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.sinch.sdk.BaseTest; -import com.sinch.sdk.domains.voice.models.v1.calls.request.SvamlControlPatch; -import com.sinch.sdk.domains.voice.models.v1.svaml.action.SvamlActionHangup; -import com.sinch.sdk.domains.voice.models.v1.svaml.instruction.SvamlInstructionSay; -import java.util.Arrays; -import org.json.JSONException; -import org.junit.jupiter.api.Test; -import org.skyscreamer.jsonassert.JSONAssert; - -@TestWithResources -public class SvamlControlPatchTest extends BaseTest { - - public static SvamlControlPatch expectedSvamlControlPatch = - SvamlControlPatch.builder() - .setAction(SvamlActionHangup.SVAML_ACTION_HANGUP) - .setInstructions( - Arrays.asList( - SvamlInstructionSay.builder() - .setText("Sorry, the conference has been cancelled. The call will end now.") - .setLocale("en-US") - .build())) - .build(); - - @GivenTextResource("/domains/voice/v1/svaml/SvamlControlPatchDto.json") - String jsonSvamlControlPatchDto; - - @Test - void serializeSVAMLResponse() throws JsonProcessingException, JSONException { - - String serializedString = objectMapper.writeValueAsString(expectedSvamlControlPatch); - - JSONAssert.assertEquals(jsonSvamlControlPatchDto, serializedString, true); - } -} diff --git a/openapi-contracts/src/test/resources/domains/voice/v1/svaml/SvamlControlPatchDto.json b/openapi-contracts/src/test/resources/domains/voice/v1/svaml/SvamlControlPatchDto.json deleted file mode 100644 index 1640c9049..000000000 --- a/openapi-contracts/src/test/resources/domains/voice/v1/svaml/SvamlControlPatchDto.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "instructions": [ - { - "name": "say", - "text": "Sorry, the conference has been cancelled. The call will end now.", - "locale": "en-US" - } - ], - "action": { - "name": "hangup" - } -}