From 985434862fa43d6f38a27f7783be8914b01b9189 Mon Sep 17 00:00:00 2001 From: Durgesh Suryawanshi Date: Thu, 12 Dec 2024 11:14:34 +0530 Subject: [PATCH 1/3] Added interruptAudioAndAnnounce api --- .../CallAutomationEventParser.java | 18 ++ .../callautomation/CallMedia.java | 33 ++++ .../callautomation/CallMediaAsync.java | 60 ++++++ .../implementation/models/IncomingCall.java | 186 ++++++++++++++++++ .../InterruptAudioAndAnnounceOptions.java | 89 +++++++++ .../models/events/HoldAudioCompleted.java | 51 +++++ .../models/events/HoldAudioPaused.java | 51 +++++ .../models/events/HoldAudioResumed.java | 51 +++++ .../models/events/HoldAudioStarted.java | 51 +++++ .../models/events/PlayPaused.java | 51 +++++ .../models/events/PlayResumed.java | 51 +++++ ...ationEventParserAndProcessorUnitTests.java | 120 +++++++++++ .../CallMediaAsyncUnitTests.java | 12 ++ .../callautomation/CallMediaUnitTests.java | 9 + .../swagger/README.md | 8 +- 15 files changed, 840 insertions(+), 1 deletion(-) create mode 100644 sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/implementation/models/IncomingCall.java create mode 100644 sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/models/InterruptAudioAndAnnounceOptions.java create mode 100644 sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/models/events/HoldAudioCompleted.java create mode 100644 sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/models/events/HoldAudioPaused.java create mode 100644 sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/models/events/HoldAudioResumed.java create mode 100644 sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/models/events/HoldAudioStarted.java create mode 100644 sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/models/events/PlayPaused.java create mode 100644 sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/models/events/PlayResumed.java diff --git a/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallAutomationEventParser.java b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallAutomationEventParser.java index 7ed499ce6b5b0..cad0d1636555b 100644 --- a/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallAutomationEventParser.java +++ b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallAutomationEventParser.java @@ -26,10 +26,16 @@ import com.azure.communication.callautomation.models.events.DialogSensitivityUpdate; import com.azure.communication.callautomation.models.events.DialogStarted; import com.azure.communication.callautomation.models.events.DialogTransfer; +import com.azure.communication.callautomation.models.events.HoldAudioCompleted; +import com.azure.communication.callautomation.models.events.HoldAudioPaused; +import com.azure.communication.callautomation.models.events.HoldAudioResumed; +import com.azure.communication.callautomation.models.events.HoldAudioStarted; import com.azure.communication.callautomation.models.events.HoldFailed; import com.azure.communication.callautomation.models.events.ParticipantsUpdated; import com.azure.communication.callautomation.models.events.PlayCanceled; import com.azure.communication.callautomation.models.events.PlayCompleted; +import com.azure.communication.callautomation.models.events.PlayPaused; +import com.azure.communication.callautomation.models.events.PlayResumed; import com.azure.communication.callautomation.models.events.PlayFailed; import com.azure.communication.callautomation.models.events.PlayStarted; import com.azure.communication.callautomation.models.events.RecognizeCanceled; @@ -135,6 +141,10 @@ private static CallAutomationEventBase parseSingleCloudEvent(String data, String ret = PlayStarted.fromJson(jsonReader); } else if (Objects.equals(eventType, "Microsoft.Communication.PlayCanceled")) { ret = PlayCanceled.fromJson(jsonReader); + } else if (Objects.equals(eventType, "Microsoft.Communication.PlayPaused")) { + ret = PlayPaused.fromJson(jsonReader); + } else if (Objects.equals(eventType, "Microsoft.Communication.PlayResumed")) { + ret = PlayResumed.fromJson(jsonReader); } else if (Objects.equals(eventType, "Microsoft.Communication.RecognizeCompleted")) { ret = RecognizeCompleted.fromJson(jsonReader); } else if (Objects.equals(eventType, "Microsoft.Communication.RecognizeFailed")) { @@ -189,6 +199,14 @@ private static CallAutomationEventBase parseSingleCloudEvent(String data, String ret = AnswerFailed.fromJson(jsonReader); } else if (Objects.equals(eventType, "Microsoft.Communication.CreateCallFailed")) { ret = CreateCallFailed.fromJson(jsonReader); + } else if (Objects.equals(eventType, "Microsoft.Communication.HoldAudioCompleted")) { + ret = HoldAudioCompleted.fromJson(jsonReader); + } else if (Objects.equals(eventType, "Microsoft.Communication.HoldAudioStarted")) { + ret = HoldAudioStarted.fromJson(jsonReader); + } else if (Objects.equals(eventType, "Microsoft.Communication.HoldAudioPaused")) { + ret = HoldAudioPaused.fromJson(jsonReader); + } else if (Objects.equals(eventType, "Microsoft.Communication.HoldAudioResumed")) { + ret = HoldAudioResumed.fromJson(jsonReader); } else if (Objects.equals(eventType, "Microsoft.Communication.HoldFailed")) { ret = HoldFailed.fromJson(jsonReader); } else if (Objects.equals(eventType, "Microsoft.Communication.ConnectFailed")) { diff --git a/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallMedia.java b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallMedia.java index 77ecdc15e54d9..aee66863c9458 100644 --- a/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallMedia.java +++ b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallMedia.java @@ -7,6 +7,7 @@ import com.azure.communication.callautomation.models.ContinuousDtmfRecognitionOptions; import com.azure.communication.callautomation.models.DtmfTone; import com.azure.communication.callautomation.models.HoldOptions; +import com.azure.communication.callautomation.models.InterruptAudioAndAnnounceOptions; import com.azure.communication.callautomation.models.UnholdOptions; import com.azure.communication.callautomation.models.PlayOptions; import com.azure.communication.callautomation.models.PlayToAllOptions; @@ -386,4 +387,36 @@ public void stopMediaStreaming() { public Response stopMediaStreamingWithResponse(StopMediaStreamingOptions options, Context context) { return callMediaAsync.stopMediaStreamingWithResponseInternal(options, context).block(); } + + /** + * Interrupt audio and play announment to the participant in call. + * @param playSources A {@link PlaySource} representing the list of source to play. + * @param playTo the target. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public void interruptAudioAndAnnounce(List playSources, CommunicationIdentifier playTo) { + callMediaAsync.interruptAudioAndAnnounce(playSources, playTo).block(); + } + + /** + * Interrupt audio and play announment to the participant in call. + * @param playSource A {@link PlaySource} representing the source to play. + * @param playTo the target. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public void interruptAudioAndAnnounce(PlaySource playSource, CommunicationIdentifier playTo) { + callMediaAsync.interruptAudioAndAnnounce(playSource, playTo).block(); + } + + /** + * Interrupt audio and play announment to the participant in call. + * @param options - Different options to pass to the request. + * @param context Context + * @return Response for successful operation. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Response interruptAudioAndAnnounceWithResponse(InterruptAudioAndAnnounceOptions options, + Context context) { + return callMediaAsync.interruptAudioAndAnnounceWithResponseInternal(options, context).block(); + } } diff --git a/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallMediaAsync.java b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallMediaAsync.java index 1c0d459263978..6f1b504abb761 100644 --- a/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallMediaAsync.java +++ b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallMediaAsync.java @@ -11,6 +11,7 @@ import com.azure.communication.callautomation.implementation.models.DtmfToneInternal; import com.azure.communication.callautomation.implementation.models.FileSourceInternal; import com.azure.communication.callautomation.implementation.models.HoldRequest; +import com.azure.communication.callautomation.implementation.models.InterruptAudioAndAnnounceRequest; import com.azure.communication.callautomation.implementation.models.PlayOptionsInternal; import com.azure.communication.callautomation.implementation.models.PlayRequest; import com.azure.communication.callautomation.implementation.models.PlaySourceInternal; @@ -39,6 +40,7 @@ import com.azure.communication.callautomation.models.DtmfTone; import com.azure.communication.callautomation.models.FileSource; import com.azure.communication.callautomation.models.HoldOptions; +import com.azure.communication.callautomation.models.InterruptAudioAndAnnounceOptions; import com.azure.communication.callautomation.models.PlayOptions; import com.azure.communication.callautomation.models.PlaySource; import com.azure.communication.callautomation.models.PlayToAllOptions; @@ -1009,4 +1011,62 @@ Mono> stopMediaStreamingWithResponseInternal(StopMediaStreamingOp return monoError(logger, ex); } } + + /** + * Interrupt audio and play announment to the participant in call. + * @param playSources the list of play source. + * @param playTo the target. + * @return Response for successful operation. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono interruptAudioAndAnnounce(List playSources, CommunicationIdentifier playTo) { + return interruptAudioAndAnnounceWithResponse(new InterruptAudioAndAnnounceOptions(playSources, playTo)) + .flatMap(FluxUtil::toMono); + } + + /** + * Interrupt audio and play announment to the participant in call. + * @param playTo the target. + * @param playSource the play source. + * @return Response for successful operation. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono interruptAudioAndAnnounce(PlaySource playSource, CommunicationIdentifier playTo) { + return interruptAudioAndAnnounceWithResponse(new InterruptAudioAndAnnounceOptions(playSource, playTo)) + .flatMap(FluxUtil::toMono); + } + + /** + * Interrupt audio and play announment to the participant in call. + * @param options - Different options to pass to the request. + * @return Response for successful operation. + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public Mono> interruptAudioAndAnnounceWithResponse(InterruptAudioAndAnnounceOptions options) { + return withContext(context -> interruptAudioAndAnnounceWithResponseInternal(options, context)); + } + + Mono> interruptAudioAndAnnounceWithResponseInternal(InterruptAudioAndAnnounceOptions options, + Context context) { + try { + context = context == null ? Context.NONE : context; + List playSourcesInternal = new ArrayList<>(); + InterruptAudioAndAnnounceRequest request = new InterruptAudioAndAnnounceRequest() + .setPlayTo(CommunicationIdentifierConverter.convert(options.getPlayTo())) + .setOperationContext(options.getOperationContext()); + + if (options.getPlaySources() != null) { + for (PlaySource playSource : options.getPlaySources()) { + if (playSource != null) { + playSourcesInternal.add(convertPlaySourceToPlaySourceInternal(playSource)); + } + } + } + request.setPlaySources(playSourcesInternal); + + return contentsInternal.interruptAudioAndAnnounceWithResponseAsync(callConnectionId, request, context); + } catch (RuntimeException ex) { + return monoError(logger, ex); + } + } } diff --git a/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/implementation/models/IncomingCall.java b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/implementation/models/IncomingCall.java new file mode 100644 index 0000000000000..c7972b479bc53 --- /dev/null +++ b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/implementation/models/IncomingCall.java @@ -0,0 +1,186 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// Code generated by Microsoft (R) AutoRest Code Generator. + +package com.azure.communication.callautomation.implementation.models; + +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonSerializable; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; +import java.io.IOException; + +/** + * The incoming call event. + */ +@Immutable +public final class IncomingCall implements JsonSerializable { + /* + * The communication identifier of the target user. + */ + private CommunicationIdentifierModel to; + + /* + * The communication identifier of the user who initiated the call. + */ + private CommunicationIdentifierModel from; + + /* + * Display name of caller. + */ + private String callerDisplayName; + + /* + * The server call id. + */ + private String serverCallId; + + /* + * Custom Context of Incoming Call + */ + private CustomCallingContext customContext; + + /* + * Incoming call context. + */ + private String incomingCallContext; + + /* + * The communication identifier of the user on behalf of whom the call is made. + */ + private CommunicationIdentifierModel onBehalfOfCallee; + + /* + * Correlation ID for event to call correlation. Also called ChainId for skype chain ID. + */ + private String correlationId; + + /** + * Creates an instance of IncomingCall class. + */ + public IncomingCall() { + } + + /** + * Get the to property: The communication identifier of the target user. + * + * @return the to value. + */ + public CommunicationIdentifierModel getTo() { + return this.to; + } + + /** + * Get the from property: The communication identifier of the user who initiated the call. + * + * @return the from value. + */ + public CommunicationIdentifierModel getFrom() { + return this.from; + } + + /** + * Get the callerDisplayName property: Display name of caller. + * + * @return the callerDisplayName value. + */ + public String getCallerDisplayName() { + return this.callerDisplayName; + } + + /** + * Get the serverCallId property: The server call id. + * + * @return the serverCallId value. + */ + public String getServerCallId() { + return this.serverCallId; + } + + /** + * Get the customContext property: Custom Context of Incoming Call. + * + * @return the customContext value. + */ + public CustomCallingContext getCustomContext() { + return this.customContext; + } + + /** + * Get the incomingCallContext property: Incoming call context. + * + * @return the incomingCallContext value. + */ + public String getIncomingCallContext() { + return this.incomingCallContext; + } + + /** + * Get the onBehalfOfCallee property: The communication identifier of the user on behalf of whom the call is made. + * + * @return the onBehalfOfCallee value. + */ + public CommunicationIdentifierModel getOnBehalfOfCallee() { + return this.onBehalfOfCallee; + } + + /** + * Get the correlationId property: Correlation ID for event to call correlation. Also called ChainId for skype chain + * ID. + * + * @return the correlationId value. + */ + public String getCorrelationId() { + return this.correlationId; + } + + /** + * {@inheritDoc} + */ + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of IncomingCall from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of IncomingCall if the JsonReader was pointing to an instance of it, or null if it was + * pointing to JSON null. + * @throws IOException If an error occurs while reading the IncomingCall. + */ + public static IncomingCall fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + IncomingCall deserializedIncomingCall = new IncomingCall(); + while (reader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + + if ("to".equals(fieldName)) { + deserializedIncomingCall.to = CommunicationIdentifierModel.fromJson(reader); + } else if ("from".equals(fieldName)) { + deserializedIncomingCall.from = CommunicationIdentifierModel.fromJson(reader); + } else if ("callerDisplayName".equals(fieldName)) { + deserializedIncomingCall.callerDisplayName = reader.getString(); + } else if ("serverCallId".equals(fieldName)) { + deserializedIncomingCall.serverCallId = reader.getString(); + } else if ("customContext".equals(fieldName)) { + deserializedIncomingCall.customContext = CustomCallingContext.fromJson(reader); + } else if ("incomingCallContext".equals(fieldName)) { + deserializedIncomingCall.incomingCallContext = reader.getString(); + } else if ("onBehalfOfCallee".equals(fieldName)) { + deserializedIncomingCall.onBehalfOfCallee = CommunicationIdentifierModel.fromJson(reader); + } else if ("correlationId".equals(fieldName)) { + deserializedIncomingCall.correlationId = reader.getString(); + } else { + reader.skipChildren(); + } + } + + return deserializedIncomingCall; + }); + } +} diff --git a/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/models/InterruptAudioAndAnnounceOptions.java b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/models/InterruptAudioAndAnnounceOptions.java new file mode 100644 index 0000000000000..e2b89e5047c36 --- /dev/null +++ b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/models/InterruptAudioAndAnnounceOptions.java @@ -0,0 +1,89 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.communication.callautomation.models; + +import com.azure.communication.common.CommunicationIdentifier; +import com.azure.core.annotation.Fluent; + +import java.util.ArrayList; +import java.util.List; + +/** The InterruptAudioAndAnnounceOptions model. */ +@Fluent +public final class InterruptAudioAndAnnounceOptions { + /* + * A List of {@link PlaySource} representing the sources to play. + * Currently only single play source per request is supported. + */ + private final List playSources; + + /* + * The targets to play to + */ + private final CommunicationIdentifier playTo; + + /* + * The operation context + */ + private String operationContext; + + /** + * Constructor + * @param playSources A List of {@link PlaySource} representing the sources to play. + * @param playTo The target to play to. + */ + public InterruptAudioAndAnnounceOptions(List playSources, CommunicationIdentifier playTo) { + this.playSources = playSources; + this.playTo = playTo; + } + + /** + * Constructor + * @param playSource A {@link PlaySource} representing the source to play. + * @param playTo The target to play to. + */ + public InterruptAudioAndAnnounceOptions(PlaySource playSource, CommunicationIdentifier playTo) { + this.playSources = new ArrayList<>(); + this.playSources.add(playSource); + this.playTo = playTo; + } + + /** + * Get the play sources. + * + * @return the playSources value. + */ + public List getPlaySources() { + return this.playSources; + } + + /** + * Get the target to play to. + * + * @return the playTo value. + */ + public CommunicationIdentifier getPlayTo() { + return this.playTo; + } + + /** + * Get the operationContext property. + * + * @return the operationContext value. + */ + public String getOperationContext() { + return this.operationContext; + } + + /** + * Set the operationContext property. + * + * @param operationContext the operationContext value to set. + * @return the InterruptAudioAndAnnounceOptions object itself. + */ + public InterruptAudioAndAnnounceOptions setOperationContext(String operationContext) { + this.operationContext = operationContext; + return this; + } +} diff --git a/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/models/events/HoldAudioCompleted.java b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/models/events/HoldAudioCompleted.java new file mode 100644 index 0000000000000..014044a82f5b9 --- /dev/null +++ b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/models/events/HoldAudioCompleted.java @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.communication.callautomation.models.events; + +import java.io.IOException; + +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; + +/** The HoldAudioCompleted model. */ +@Immutable +public final class HoldAudioCompleted extends CallAutomationEventBase { + + private HoldAudioCompleted() { + } + + /** + * {@inheritDoc} + */ + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + super.writeFields(jsonWriter); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of HoldAudioCompleted from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of HoldAudioCompleted if the JsonReader was pointing to an instance of it, or null + * if it was pointing to JSON null. + * @throws IOException If an error occurs while reading the HoldAudioCompleted. + */ + public static HoldAudioCompleted fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + final HoldAudioCompleted event = new HoldAudioCompleted(); + while (jsonReader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if (!event.readField(fieldName, reader)) { + reader.skipChildren(); + } + } + return event; + }); + } +} diff --git a/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/models/events/HoldAudioPaused.java b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/models/events/HoldAudioPaused.java new file mode 100644 index 0000000000000..23497dde03f47 --- /dev/null +++ b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/models/events/HoldAudioPaused.java @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.communication.callautomation.models.events; + +import java.io.IOException; + +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; + +/** The HoldAudioPaused model. */ +@Immutable +public final class HoldAudioPaused extends CallAutomationEventBase { + + private HoldAudioPaused() { + } + + /** + * {@inheritDoc} + */ + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + super.writeFields(jsonWriter); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of HoldAudioPaused from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of HoldAudioPaused if the JsonReader was pointing to an instance of it, or null + * if it was pointing to JSON null. + * @throws IOException If an error occurs while reading the HoldAudioPaused. + */ + public static HoldAudioPaused fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + final HoldAudioPaused event = new HoldAudioPaused(); + while (jsonReader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if (!event.readField(fieldName, reader)) { + reader.skipChildren(); + } + } + return event; + }); + } +} diff --git a/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/models/events/HoldAudioResumed.java b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/models/events/HoldAudioResumed.java new file mode 100644 index 0000000000000..86b80a6924e60 --- /dev/null +++ b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/models/events/HoldAudioResumed.java @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.communication.callautomation.models.events; + +import java.io.IOException; + +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; + +/** The HoldAudioResumed model. */ +@Immutable +public final class HoldAudioResumed extends CallAutomationEventBase { + + private HoldAudioResumed() { + } + + /** + * {@inheritDoc} + */ + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + super.writeFields(jsonWriter); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of HoldAudioResumed from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of HoldAudioResumed if the JsonReader was pointing to an instance of it, or null + * if it was pointing to JSON null. + * @throws IOException If an error occurs while reading the HoldAudioResumed. + */ + public static HoldAudioResumed fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + final HoldAudioResumed event = new HoldAudioResumed(); + while (jsonReader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if (!event.readField(fieldName, reader)) { + reader.skipChildren(); + } + } + return event; + }); + } +} diff --git a/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/models/events/HoldAudioStarted.java b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/models/events/HoldAudioStarted.java new file mode 100644 index 0000000000000..0a4aaf3ea8d33 --- /dev/null +++ b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/models/events/HoldAudioStarted.java @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.communication.callautomation.models.events; + +import java.io.IOException; + +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; + +/** The HoldAudioStarted model. */ +@Immutable +public final class HoldAudioStarted extends CallAutomationEventBase { + + private HoldAudioStarted() { + } + + /** + * {@inheritDoc} + */ + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + super.writeFields(jsonWriter); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of HoldAudioStarted from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of HoldAudioStarted if the JsonReader was pointing to an instance of it, or null + * if it was pointing to JSON null. + * @throws IOException If an error occurs while reading the HoldAudioStarted. + */ + public static HoldAudioStarted fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + final HoldAudioStarted event = new HoldAudioStarted(); + while (jsonReader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if (!event.readField(fieldName, reader)) { + reader.skipChildren(); + } + } + return event; + }); + } +} diff --git a/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/models/events/PlayPaused.java b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/models/events/PlayPaused.java new file mode 100644 index 0000000000000..d9db803df0a26 --- /dev/null +++ b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/models/events/PlayPaused.java @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.communication.callautomation.models.events; + +import java.io.IOException; + +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; + +/** The PlayPaused model. */ +@Immutable +public final class PlayPaused extends CallAutomationEventBase { + + private PlayPaused() { + } + + /** + * {@inheritDoc} + */ + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + super.writeFields(jsonWriter); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of PlayPaused from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of PlayPaused if the JsonReader was pointing to an instance of it, or null + * if it was pointing to JSON null. + * @throws IOException If an error occurs while reading the PlayPaused. + */ + public static PlayPaused fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + final PlayPaused event = new PlayPaused(); + while (jsonReader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if (!event.readField(fieldName, reader)) { + reader.skipChildren(); + } + } + return event; + }); + } +} diff --git a/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/models/events/PlayResumed.java b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/models/events/PlayResumed.java new file mode 100644 index 0000000000000..4e336c05d3bd9 --- /dev/null +++ b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/models/events/PlayResumed.java @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.communication.callautomation.models.events; + +import java.io.IOException; + +import com.azure.core.annotation.Immutable; +import com.azure.json.JsonReader; +import com.azure.json.JsonToken; +import com.azure.json.JsonWriter; + +/** The PlayResumed model. */ +@Immutable +public final class PlayResumed extends CallAutomationEventBase { + + private PlayResumed() { + } + + /** + * {@inheritDoc} + */ + @Override + public JsonWriter toJson(JsonWriter jsonWriter) throws IOException { + jsonWriter.writeStartObject(); + super.writeFields(jsonWriter); + return jsonWriter.writeEndObject(); + } + + /** + * Reads an instance of PlayResumed from the JsonReader. + * + * @param jsonReader The JsonReader being read. + * @return An instance of PlayPaused if the JsonReader was pointing to an instance of it, or null + * if it was pointing to JSON null. + * @throws IOException If an error occurs while reading the PlayResumed. + */ + public static PlayResumed fromJson(JsonReader jsonReader) throws IOException { + return jsonReader.readObject(reader -> { + final PlayResumed event = new PlayResumed(); + while (jsonReader.nextToken() != JsonToken.END_OBJECT) { + String fieldName = reader.getFieldName(); + reader.nextToken(); + if (!event.readField(fieldName, reader)) { + reader.skipChildren(); + } + } + return event; + }); + } +} diff --git a/sdk/communication/azure-communication-callautomation/src/test/java/com/azure/communication/callautomation/CallAutomationEventParserAndProcessorUnitTests.java b/sdk/communication/azure-communication-callautomation/src/test/java/com/azure/communication/callautomation/CallAutomationEventParserAndProcessorUnitTests.java index ed9a02b5ef418..a3662dbf5bef5 100644 --- a/sdk/communication/azure-communication-callautomation/src/test/java/com/azure/communication/callautomation/CallAutomationEventParserAndProcessorUnitTests.java +++ b/sdk/communication/azure-communication-callautomation/src/test/java/com/azure/communication/callautomation/CallAutomationEventParserAndProcessorUnitTests.java @@ -25,10 +25,16 @@ import com.azure.communication.callautomation.models.events.DialogSensitivityUpdate; import com.azure.communication.callautomation.models.events.DialogStarted; import com.azure.communication.callautomation.models.events.DialogTransfer; +import com.azure.communication.callautomation.models.events.HoldAudioCompleted; +import com.azure.communication.callautomation.models.events.HoldAudioPaused; +import com.azure.communication.callautomation.models.events.HoldAudioResumed; +import com.azure.communication.callautomation.models.events.HoldAudioStarted; import com.azure.communication.callautomation.models.events.HoldFailed; import com.azure.communication.callautomation.models.events.ParticipantsUpdated; import com.azure.communication.callautomation.models.events.PlayCanceled; import com.azure.communication.callautomation.models.events.PlayCompleted; +import com.azure.communication.callautomation.models.events.PlayPaused; +import com.azure.communication.callautomation.models.events.PlayResumed; import com.azure.communication.callautomation.models.events.PlayFailed; import com.azure.communication.callautomation.models.events.ReasonCode; import com.azure.communication.callautomation.models.events.ReasonCode.Recognize; @@ -1220,4 +1226,118 @@ public void parseMediaStreamingFailedEvent() { assertEquals(MediaStreamingStatusDetails.STREAM_CONNECTION_UNSUCCESSFUL, event.getMediaStreamingUpdateResult().getMediaStreamingStatusDetails()); } + + @Test + public void parsePlayPausedEvent() { + String receivedEvent = "[{\n" + "\"id\": \"704a7a96-4d74-4ebe-9cd0-b7cc39c3d7b1\",\n" + + "\"source\": \"calling/callConnections/callConnectionId/PlayPaused\",\n" + + "\"type\": \"Microsoft.Communication.PlayPaused\",\n" + "\"data\": {\n" + "\"resultInformation\": {\n" + + "\"code\": 200,\n" + "\"subCode\": 0,\n" + "\"message\": \"Action completed successfully.\"\n" + "},\n" + + "\"type\": \"PlayPaused\",\n" + "\"callConnectionId\": \"callConnectionId\",\n" + + "\"serverCallId\": \"serverCallId\",\n" + "\"correlationId\": \"correlationId\"\n" + "},\n" + + "\"time\": \"2022-08-12T03:13:25.0252763+00:00\",\n" + "\"specversion\": \"1.0\",\n" + + "\"datacontenttype\": \"application/json\",\n" + + "\"subject\": \"calling/callConnections/callConnectionId\"\n" + "}]"; + CallAutomationEventBase event = CallAutomationEventParser.parseEvents(receivedEvent).get(0); + assertNotNull(event); + PlayPaused playPaused = (PlayPaused) event; + assertNotNull(playPaused); + assertEquals("serverCallId", playPaused.getServerCallId()); + assertEquals(200, playPaused.getResultInformation().getCode()); + } + + @Test + public void parsePlayResumedEvent() { + String receivedEvent = "[{\n" + "\"id\": \"704a7a96-4d74-4ebe-9cd0-b7cc39c3d7b1\",\n" + + "\"source\": \"calling/callConnections/callConnectionId/PlayResumed\",\n" + + "\"type\": \"Microsoft.Communication.PlayResumed\",\n" + "\"data\": {\n" + "\"resultInformation\": {\n" + + "\"code\": 200,\n" + "\"subCode\": 0,\n" + "\"message\": \"Action completed successfully.\"\n" + "},\n" + + "\"type\": \"PlayResumed\",\n" + "\"callConnectionId\": \"callConnectionId\",\n" + + "\"serverCallId\": \"serverCallId\",\n" + "\"correlationId\": \"correlationId\"\n" + "},\n" + + "\"time\": \"2022-08-12T03:13:25.0252763+00:00\",\n" + "\"specversion\": \"1.0\",\n" + + "\"datacontenttype\": \"application/json\",\n" + + "\"subject\": \"calling/callConnections/callConnectionId\"\n" + "}]"; + CallAutomationEventBase event = CallAutomationEventParser.parseEvents(receivedEvent).get(0); + assertNotNull(event); + PlayResumed playResumed = (PlayResumed) event; + assertNotNull(playResumed); + assertEquals("serverCallId", playResumed.getServerCallId()); + assertEquals(200, playResumed.getResultInformation().getCode()); + } + + @Test + public void parseHoldAudioCompletedEvent() { + String receivedEvent = "[{\n" + "\"id\": \"704a7a96-4d74-4ebe-9cd0-b7cc39c3d7b1\",\n" + + "\"source\": \"calling/callConnections/callConnectionId/HoldAudioCompleted\",\n" + + "\"type\": \"Microsoft.Communication.HoldAudioCompleted\",\n" + "\"data\": {\n" + + "\"resultInformation\": {\n" + "\"code\": 200,\n" + "\"subCode\": 0,\n" + + "\"message\": \"Action completed successfully.\"\n" + "},\n" + "\"type\": \"HoldAudioCompleted\",\n" + + "\"callConnectionId\": \"callConnectionId\",\n" + "\"serverCallId\": \"serverCallId\",\n" + + "\"correlationId\": \"correlationId\"\n" + "},\n" + "\"time\": \"2022-08-12T03:13:25.0252763+00:00\",\n" + + "\"specversion\": \"1.0\",\n" + "\"datacontenttype\": \"application/json\",\n" + + "\"subject\": \"calling/callConnections/callConnectionId\"\n" + "}]"; + CallAutomationEventBase event = CallAutomationEventParser.parseEvents(receivedEvent).get(0); + assertNotNull(event); + HoldAudioCompleted holdAudioCompleted = (HoldAudioCompleted) event; + assertNotNull(holdAudioCompleted); + assertEquals("serverCallId", holdAudioCompleted.getServerCallId()); + assertEquals(200, holdAudioCompleted.getResultInformation().getCode()); + } + + @Test + public void parseHoldAudioStartedEvent() { + String receivedEvent = "[{\n" + "\"id\": \"704a7a96-4d74-4ebe-9cd0-b7cc39c3d7b1\",\n" + + "\"source\": \"calling/callConnections/callConnectionId/HoldAudioStarted\",\n" + + "\"type\": \"Microsoft.Communication.HoldAudioStarted\",\n" + "\"data\": {\n" + + "\"resultInformation\": {\n" + "\"code\": 200,\n" + "\"subCode\": 0,\n" + + "\"message\": \"Action completed successfully.\"\n" + "},\n" + "\"type\": \"HoldAudioStarted\",\n" + + "\"callConnectionId\": \"callConnectionId\",\n" + "\"serverCallId\": \"serverCallId\",\n" + + "\"correlationId\": \"correlationId\"\n" + "},\n" + "\"time\": \"2022-08-12T03:13:25.0252763+00:00\",\n" + + "\"specversion\": \"1.0\",\n" + "\"datacontenttype\": \"application/json\",\n" + + "\"subject\": \"calling/callConnections/callConnectionId\"\n" + "}]"; + CallAutomationEventBase event = CallAutomationEventParser.parseEvents(receivedEvent).get(0); + assertNotNull(event); + HoldAudioStarted holdAudioStarted = (HoldAudioStarted) event; + assertNotNull(holdAudioStarted); + assertEquals("serverCallId", holdAudioStarted.getServerCallId()); + assertEquals(200, holdAudioStarted.getResultInformation().getCode()); + } + + @Test + public void parseHoldAudioPausedEvent() { + String receivedEvent = "[{\n" + "\"id\": \"704a7a96-4d74-4ebe-9cd0-b7cc39c3d7b1\",\n" + + "\"source\": \"calling/callConnections/callConnectionId/HoldAudioPaused\",\n" + + "\"type\": \"Microsoft.Communication.HoldAudioPaused\",\n" + "\"data\": {\n" + + "\"resultInformation\": {\n" + "\"code\": 200,\n" + "\"subCode\": 0,\n" + + "\"message\": \"Action completed successfully.\"\n" + "},\n" + "\"type\": \"HoldAudioPaused\",\n" + + "\"callConnectionId\": \"callConnectionId\",\n" + "\"serverCallId\": \"serverCallId\",\n" + + "\"correlationId\": \"correlationId\"\n" + "},\n" + "\"time\": \"2022-08-12T03:13:25.0252763+00:00\",\n" + + "\"specversion\": \"1.0\",\n" + "\"datacontenttype\": \"application/json\",\n" + + "\"subject\": \"calling/callConnections/callConnectionId\"\n" + "}]"; + CallAutomationEventBase event = CallAutomationEventParser.parseEvents(receivedEvent).get(0); + assertNotNull(event); + HoldAudioPaused holdAudioPaused = (HoldAudioPaused) event; + assertNotNull(holdAudioPaused); + assertEquals("serverCallId", holdAudioPaused.getServerCallId()); + assertEquals(200, holdAudioPaused.getResultInformation().getCode()); + } + + @Test + public void parseHoldAudioResumedEvent() { + String receivedEvent = "[{\n" + "\"id\": \"704a7a96-4d74-4ebe-9cd0-b7cc39c3d7b1\",\n" + + "\"source\": \"calling/callConnections/callConnectionId/HoldAudioResumed\",\n" + + "\"type\": \"Microsoft.Communication.HoldAudioResumed\",\n" + "\"data\": {\n" + + "\"resultInformation\": {\n" + "\"code\": 200,\n" + "\"subCode\": 0,\n" + + "\"message\": \"Action completed successfully.\"\n" + "},\n" + "\"type\": \"HoldAudioResumed\",\n" + + "\"callConnectionId\": \"callConnectionId\",\n" + "\"serverCallId\": \"serverCallId\",\n" + + "\"correlationId\": \"correlationId\"\n" + "},\n" + "\"time\": \"2022-08-12T03:13:25.0252763+00:00\",\n" + + "\"specversion\": \"1.0\",\n" + "\"datacontenttype\": \"application/json\",\n" + + "\"subject\": \"calling/callConnections/callConnectionId\"\n" + "}]"; + CallAutomationEventBase event = CallAutomationEventParser.parseEvents(receivedEvent).get(0); + assertNotNull(event); + HoldAudioResumed holdAudioResumed = (HoldAudioResumed) event; + assertNotNull(holdAudioResumed); + assertEquals("serverCallId", holdAudioResumed.getServerCallId()); + assertEquals(200, holdAudioResumed.getResultInformation().getCode()); + } } diff --git a/sdk/communication/azure-communication-callautomation/src/test/java/com/azure/communication/callautomation/CallMediaAsyncUnitTests.java b/sdk/communication/azure-communication-callautomation/src/test/java/com/azure/communication/callautomation/CallMediaAsyncUnitTests.java index 4210f03113afd..0877974a5d008 100644 --- a/sdk/communication/azure-communication-callautomation/src/test/java/com/azure/communication/callautomation/CallMediaAsyncUnitTests.java +++ b/sdk/communication/azure-communication-callautomation/src/test/java/com/azure/communication/callautomation/CallMediaAsyncUnitTests.java @@ -12,6 +12,7 @@ import com.azure.communication.callautomation.models.DtmfTone; import com.azure.communication.callautomation.models.FileSource; import com.azure.communication.callautomation.models.HoldOptions; +import com.azure.communication.callautomation.models.InterruptAudioAndAnnounceOptions; import com.azure.communication.callautomation.models.PlayOptions; import com.azure.communication.callautomation.models.PlayToAllOptions; import com.azure.communication.callautomation.models.RecognitionChoice; @@ -565,4 +566,15 @@ public void stopMediaStreamingWithResponse() { .consumeNextWith(response -> assertEquals(202, response.getStatusCode())) .verifyComplete(); } + + @Test + public void interruptAudioAndAnnounceWithResponseTest() { + callMedia = getMockCallMedia(202); + InterruptAudioAndAnnounceOptions options + = new InterruptAudioAndAnnounceOptions(playTextSource, new CommunicationUserIdentifier("id")); + options.setOperationContext("operationContext"); + StepVerifier.create(callMedia.interruptAudioAndAnnounceWithResponse(options)) + .consumeNextWith(response -> assertEquals(202, response.getStatusCode())) + .verifyComplete(); + } } diff --git a/sdk/communication/azure-communication-callautomation/src/test/java/com/azure/communication/callautomation/CallMediaUnitTests.java b/sdk/communication/azure-communication-callautomation/src/test/java/com/azure/communication/callautomation/CallMediaUnitTests.java index c9083ddfa8849..14822d09c7b5b 100644 --- a/sdk/communication/azure-communication-callautomation/src/test/java/com/azure/communication/callautomation/CallMediaUnitTests.java +++ b/sdk/communication/azure-communication-callautomation/src/test/java/com/azure/communication/callautomation/CallMediaUnitTests.java @@ -271,4 +271,13 @@ public void stopMediaStremaingWithResponse() { Response response = callMedia.stopMediaStreamingWithResponse(options, Context.NONE); assertEquals(response.getStatusCode(), 202); } + + @Test + public void interruptAudioAndAnnounceWithResponseTest() { + InterruptAudioAndAnnounceOptions options + = new InterruptAudioAndAnnounceOptions(playTextSource, new CommunicationUserIdentifier("id")); + options.setOperationContext("operationContext"); + Response response = callMedia.interruptAudioAndAnnounceWithResponse(options, Context.NONE); + assertEquals(response.getStatusCode(), 202); + } } diff --git a/sdk/communication/azure-communication-callautomation/swagger/README.md b/sdk/communication/azure-communication-callautomation/swagger/README.md index 315b16c0365f5..287f04d59722b 100644 --- a/sdk/communication/azure-communication-callautomation/swagger/README.md +++ b/sdk/communication/azure-communication-callautomation/swagger/README.md @@ -32,7 +32,7 @@ autorest README.md --java --v4 tag: package-2024-09-01-preview use: '@autorest/java@4.1.29' require: - - https://github.com/Azure/azure-rest-api-specs/blob/7347874bc2794b2770c3e7618bd1a5ccab53cb54/specification/communication/data-plane/CallAutomation/readme.md + - https://github.com/Azure/azure-rest-api-specs/blob/b9e2d84df17975c0269246afb701eeba545958d0/specification/communication/data-plane/CallAutomation/readme.md java: true output-folder: ../ license-header: MICROSOFT_MIT_SMALL @@ -271,6 +271,12 @@ directive: - remove-model: CreateCallFailed - remove-model: AnswerFailed - remove-model: HoldFailed +- remove-model: HoldAudioStarted +- remove-model: HoldAudioComplteted +- remove-model: HoldAudioResumed +- remove-model: HoldAudioPaused +- remove-model: PlayPaused +- remove-model: PlayResumed ``` From bb64b5e9df0f95864812a968b5ee9a9f2dca53e8 Mon Sep 17 00:00:00 2001 From: Durgesh Suryawanshi Date: Mon, 16 Dec 2024 15:20:08 +0530 Subject: [PATCH 2/3] Added live test --- .../callautomation/CallMedia.java | 10 -- .../callautomation/CallMediaAsync.java | 12 -- .../CallMediaAsyncAutomatedLiveTests.java | 110 ++++++++++++++++++ 3 files changed, 110 insertions(+), 22 deletions(-) diff --git a/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallMedia.java b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallMedia.java index aee66863c9458..1f9a853b6ddb5 100644 --- a/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallMedia.java +++ b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallMedia.java @@ -388,16 +388,6 @@ public Response stopMediaStreamingWithResponse(StopMediaStreamingOptions o return callMediaAsync.stopMediaStreamingWithResponseInternal(options, context).block(); } - /** - * Interrupt audio and play announment to the participant in call. - * @param playSources A {@link PlaySource} representing the list of source to play. - * @param playTo the target. - */ - @ServiceMethod(returns = ReturnType.SINGLE) - public void interruptAudioAndAnnounce(List playSources, CommunicationIdentifier playTo) { - callMediaAsync.interruptAudioAndAnnounce(playSources, playTo).block(); - } - /** * Interrupt audio and play announment to the participant in call. * @param playSource A {@link PlaySource} representing the source to play. diff --git a/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallMediaAsync.java b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallMediaAsync.java index 6f1b504abb761..f502161d5ee43 100644 --- a/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallMediaAsync.java +++ b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallMediaAsync.java @@ -1012,18 +1012,6 @@ Mono> stopMediaStreamingWithResponseInternal(StopMediaStreamingOp } } - /** - * Interrupt audio and play announment to the participant in call. - * @param playSources the list of play source. - * @param playTo the target. - * @return Response for successful operation. - */ - @ServiceMethod(returns = ReturnType.SINGLE) - public Mono interruptAudioAndAnnounce(List playSources, CommunicationIdentifier playTo) { - return interruptAudioAndAnnounceWithResponse(new InterruptAudioAndAnnounceOptions(playSources, playTo)) - .flatMap(FluxUtil::toMono); - } - /** * Interrupt audio and play announment to the participant in call. * @param playTo the target. diff --git a/sdk/communication/azure-communication-callautomation/src/test/java/com/azure/communication/callautomation/CallMediaAsyncAutomatedLiveTests.java b/sdk/communication/azure-communication-callautomation/src/test/java/com/azure/communication/callautomation/CallMediaAsyncAutomatedLiveTests.java index 9d4a469c13b60..6362040c7592c 100644 --- a/sdk/communication/azure-communication-callautomation/src/test/java/com/azure/communication/callautomation/CallMediaAsyncAutomatedLiveTests.java +++ b/sdk/communication/azure-communication-callautomation/src/test/java/com/azure/communication/callautomation/CallMediaAsyncAutomatedLiveTests.java @@ -1196,4 +1196,114 @@ public void playMultipleCombinedSourcesWithPlayMediaAllTest(HttpClient httpClien } } } + + @ParameterizedTest + @MethodSource("com.azure.core.test.TestBase#getHttpClients") + @DisabledIfEnvironmentVariable( + named = "SKIP_LIVE_TEST", + matches = "(?i)(true)", + disabledReason = "Requires environment to be set up") + public void interruptAudioAndAnnounceToholdParticipantInACallTest(HttpClient httpClient) { + /* Test case: ACS to ACS call + * 1. create a CallAutomationClient. + * 2. create a call from source to one ACS target. + * 3. get updated call properties and check for the connected state. + * 4. hold the participant + * 5. interrupt audio and announce. + * 6. unhold the participant + * 7. hang up the call. + */ + + CommunicationIdentityAsyncClient identityAsyncClient + = getCommunicationIdentityClientUsingConnectionString(httpClient) + .addPolicy((context, next) -> logHeaders("interruptAudioAndAnnounceToholdParticipantInACallTest", next)) + .buildAsyncClient(); + + List callDestructors = new ArrayList<>(); + + try { + // create caller and receiver + CommunicationUserIdentifier caller = identityAsyncClient.createUser().block(); + CommunicationUserIdentifier receiver = identityAsyncClient.createUser().block(); + + CallAutomationAsyncClient callerAsyncClient = getCallAutomationClientUsingConnectionString(httpClient) + .addPolicy((context, next) -> logHeaders("interruptAudioAndAnnounceToholdParticipantInACallTest", next)) + .sourceIdentity(caller) + .buildAsyncClient(); + + // Create call automation client for receivers. + CallAutomationAsyncClient receiverAsyncClient = getCallAutomationClientUsingConnectionString(httpClient) + .addPolicy((context, next) -> logHeaders("interruptAudioAndAnnounceToholdParticipantInACallTest", next)) + .buildAsyncClient(); + + String uniqueId = serviceBusWithNewCall(caller, receiver); + + // create a call + List targets = Collections.singletonList(receiver); + CreateGroupCallOptions createCallOptions + = new CreateGroupCallOptions(targets, DISPATCHER_CALLBACK + String.format("?q=%s", uniqueId)); + Response createCallResultResponse + = callerAsyncClient.createGroupCallWithResponse(createCallOptions).block(); + assertNotNull(createCallResultResponse); + CreateCallResult createCallResult = createCallResultResponse.getValue(); + assertNotNull(createCallResult); + assertNotNull(createCallResult.getCallConnectionProperties()); + String callerConnectionId = createCallResult.getCallConnectionProperties().getCallConnectionId(); + assertNotNull(callerConnectionId); + + // wait for the incomingCallContext + String incomingCallContext = waitForIncomingCallContext(uniqueId, Duration.ofSeconds(10)); + assertNotNull(incomingCallContext); + + // answer the call + AnswerCallOptions answerCallOptions + = new AnswerCallOptions(incomingCallContext, DISPATCHER_CALLBACK + String.format("?q=%s", uniqueId)); + AnswerCallResult answerCallResult + = Objects.requireNonNull(receiverAsyncClient.answerCallWithResponse(answerCallOptions).block()) + .getValue(); + assertNotNull(answerCallResult); + assertNotNull(answerCallResult.getCallConnectionAsync()); + assertNotNull(answerCallResult.getCallConnectionProperties()); + callDestructors.add(answerCallResult.getCallConnectionAsync()); + + // wait for callConnected + CallConnected callConnected = waitForEvent(CallConnected.class, callerConnectionId, Duration.ofSeconds(10)); + assertNotNull(callConnected); + System.out.println("CALL CONNECTED: " + callConnected); + + // hold the participant + CallMediaAsync callMediaAsync = createCallResult.getCallConnectionAsync().getCallMediaAsync(); + callMediaAsync.hold(receiver).block(); + + sleepIfRunningAgainstService(3000); + CallConnectionAsync callConnectionAsync = callerAsyncClient.getCallConnectionAsync(callerConnectionId); + + CallParticipant participantResult = callConnectionAsync.getParticipant(receiver).block(); + assertNotNull(participantResult); + assertTrue(participantResult.isOnHold()); + + callMediaAsync.interruptAudioAndAnnounce(new FileSource().setUrl(MEDIA_SOURCE), receiver).block(); + + sleepIfRunningAgainstService(3000); + + // unhold the participant + callMediaAsync.unhold(receiver).block(); + + sleepIfRunningAgainstService(3000); + participantResult = callConnectionAsync.getParticipant(receiver).block(); + assertNotNull(participantResult); + assertFalse(participantResult.isOnHold()); + } catch (Exception ex) { + fail("Unexpected exception received", ex); + } finally { + if (!callDestructors.isEmpty()) { + try { + callDestructors.forEach(callConnection -> callConnection.hangUpWithResponse(true).block()); + } catch (Exception ignored) { + // Some call might have been terminated during the test, and it will cause exceptions here. + // Do nothing and iterate to next call connection. + } + } + } + } } From 151c5ef02aea8374d7118bdb4674cf10fafd7acd Mon Sep 17 00:00:00 2001 From: Vinothini Dharmaraj Date: Fri, 20 Dec 2024 10:28:30 -0800 Subject: [PATCH 3/3] updating the test record --- .../azure-communication-callautomation/assets.json | 2 +- .../interruptAudioAndAnnounceToholdParticipantInACallTest.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 sdk/communication/azure-communication-callautomation/src/test/resources/interruptAudioAndAnnounceToholdParticipantInACallTest.json diff --git a/sdk/communication/azure-communication-callautomation/assets.json b/sdk/communication/azure-communication-callautomation/assets.json index 9b09002cae9ec..f9b4280a9b17e 100644 --- a/sdk/communication/azure-communication-callautomation/assets.json +++ b/sdk/communication/azure-communication-callautomation/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "java", "TagPrefix": "java/communication/azure-communication-callautomation", - "Tag": "java/communication/azure-communication-callautomation_768622e9b4" + "Tag": "java/communication/azure-communication-callautomation_8eed475b32" } \ No newline at end of file diff --git a/sdk/communication/azure-communication-callautomation/src/test/resources/interruptAudioAndAnnounceToholdParticipantInACallTest.json b/sdk/communication/azure-communication-callautomation/src/test/resources/interruptAudioAndAnnounceToholdParticipantInACallTest.json new file mode 100644 index 0000000000000..7e306b4fa3743 --- /dev/null +++ b/sdk/communication/azure-communication-callautomation/src/test/resources/interruptAudioAndAnnounceToholdParticipantInACallTest.json @@ -0,0 +1 @@ +["{\"to\":{\"kind\":\"communicationUser\",\"rawId\":\"REDACTED\",\"communicationUser\":{\"id\":\"REDACTED\"}},\"from\":{\"kind\":\"communicationUser\",\"rawId\":\"REDACTED\",\"communicationUser\":{\"id\":\"REDACTED\"}},\"serverCallId\":\"REDACTED\",\"callerDisplayName\":\"\",\"incomingCallContext\":\"REDACTED\",\"correlationId\":\"bef88182-f4f9-4cb8-9a94-7c58ede238b1\"}","[{\"id\":\"REDACTED\",\"source\":\"calling/callConnections/2a002280-735b-49f6-9b04-f3e34728ad19\",\"type\":\"Microsoft.Communication.CallConnected\",\"data\":{\"version\":\"2024-09-01-preview\",\"resultInformation\":{\"code\":200,\"subCode\":0,\"message\":\"\"},\"callConnectionId\":\"2a002280-735b-49f6-9b04-f3e34728ad19\",\"serverCallId\":\"REDACTED\",\"correlationId\":\"bef88182-f4f9-4cb8-9a94-7c58ede238b1\",\"publicEventType\":\"Microsoft.Communication.CallConnected\"},\"time\":\"2024-12-20T18:25:09.7605863\\u002B00:00\",\"specversion\":\"1.0\",\"datacontenttype\":\"application/json\",\"subject\":\"calling/callConnections/2a002280-735b-49f6-9b04-f3e34728ad19\"}]","[{\"id\":\"REDACTED\",\"source\":\"calling/callConnections/2a002280-735b-49f6-9b04-f3e34728ad19\",\"type\":\"Microsoft.Communication.ParticipantsUpdated\",\"data\":{\"participants\":[{\"identifier\":{\"rawId\":\"REDACTED\",\"kind\":\"communicationUser\",\"communicationUser\":{\"id\":\"REDACTED\"}},\"isMuted\":false,\"isOnHold\":false},{\"identifier\":{\"rawId\":\"REDACTED\",\"kind\":\"communicationUser\",\"communicationUser\":{\"id\":\"REDACTED\"}},\"isMuted\":false,\"isOnHold\":false}],\"sequenceNumber\":1,\"resultInformation\":{\"code\":200,\"subCode\":0,\"message\":\"\"},\"version\":\"2024-09-01-preview\",\"callConnectionId\":\"2a002280-735b-49f6-9b04-f3e34728ad19\",\"serverCallId\":\"REDACTED\",\"correlationId\":\"bef88182-f4f9-4cb8-9a94-7c58ede238b1\",\"publicEventType\":\"Microsoft.Communication.ParticipantsUpdated\"},\"time\":\"2024-12-20T18:25:09.7195532\\u002B00:00\",\"specversion\":\"1.0\",\"datacontenttype\":\"application/json\",\"subject\":\"calling/callConnections/2a002280-735b-49f6-9b04-f3e34728ad19\"}]","[{\"id\":\"REDACTED\",\"source\":\"calling/callConnections/2a002280-ba93-4255-9f16-c3f0d32cbebb\",\"type\":\"Microsoft.Communication.ParticipantsUpdated\",\"data\":{\"participants\":[{\"identifier\":{\"rawId\":\"REDACTED\",\"kind\":\"communicationUser\",\"communicationUser\":{\"id\":\"REDACTED\"}},\"isMuted\":false,\"isOnHold\":false},{\"identifier\":{\"rawId\":\"REDACTED\",\"kind\":\"communicationUser\",\"communicationUser\":{\"id\":\"REDACTED\"}},\"isMuted\":false,\"isOnHold\":false}],\"sequenceNumber\":1,\"resultInformation\":{\"code\":200,\"subCode\":0,\"message\":\"\"},\"version\":\"2024-09-01-preview\",\"callConnectionId\":\"2a002280-ba93-4255-9f16-c3f0d32cbebb\",\"serverCallId\":\"REDACTED\",\"correlationId\":\"bef88182-f4f9-4cb8-9a94-7c58ede238b1\",\"publicEventType\":\"Microsoft.Communication.ParticipantsUpdated\"},\"time\":\"2024-12-20T18:25:09.7195532\\u002B00:00\",\"specversion\":\"1.0\",\"datacontenttype\":\"application/json\",\"subject\":\"calling/callConnections/2a002280-ba93-4255-9f16-c3f0d32cbebb\"}]","[{\"id\":\"REDACTED\",\"source\":\"calling/callConnections/2a002280-ba93-4255-9f16-c3f0d32cbebb\",\"type\":\"Microsoft.Communication.CallConnected\",\"data\":{\"version\":\"2024-09-01-preview\",\"resultInformation\":{\"code\":200,\"subCode\":0,\"message\":\"\"},\"callConnectionId\":\"2a002280-ba93-4255-9f16-c3f0d32cbebb\",\"serverCallId\":\"REDACTED\",\"correlationId\":\"bef88182-f4f9-4cb8-9a94-7c58ede238b1\",\"publicEventType\":\"Microsoft.Communication.CallConnected\"},\"time\":\"2024-12-20T18:25:09.836015\\u002B00:00\",\"specversion\":\"1.0\",\"datacontenttype\":\"application/json\",\"subject\":\"calling/callConnections/2a002280-ba93-4255-9f16-c3f0d32cbebb\"}]","[{\"id\":\"REDACTED\",\"source\":\"calling/callConnections/2a002280-ba93-4255-9f16-c3f0d32cbebb\",\"type\":\"Microsoft.Communication.ParticipantsUpdated\",\"data\":{\"participants\":[{\"identifier\":{\"rawId\":\"REDACTED\",\"kind\":\"communicationUser\",\"communicationUser\":{\"id\":\"REDACTED\"}},\"isMuted\":false,\"isOnHold\":false},{\"identifier\":{\"rawId\":\"REDACTED\",\"kind\":\"communicationUser\",\"communicationUser\":{\"id\":\"REDACTED\"}},\"isMuted\":false,\"isOnHold\":true}],\"sequenceNumber\":3,\"resultInformation\":{\"code\":200,\"subCode\":0,\"message\":\"\"},\"version\":\"2024-09-01-preview\",\"callConnectionId\":\"2a002280-ba93-4255-9f16-c3f0d32cbebb\",\"serverCallId\":\"REDACTED\",\"correlationId\":\"bef88182-f4f9-4cb8-9a94-7c58ede238b1\",\"publicEventType\":\"Microsoft.Communication.ParticipantsUpdated\"},\"time\":\"2024-12-20T18:25:15.741316\\u002B00:00\",\"specversion\":\"1.0\",\"datacontenttype\":\"application/json\",\"subject\":\"calling/callConnections/2a002280-ba93-4255-9f16-c3f0d32cbebb\"}]","[{\"id\":\"REDACTED\",\"source\":\"calling/callConnections/2a002280-735b-49f6-9b04-f3e34728ad19\",\"type\":\"Microsoft.Communication.ParticipantsUpdated\",\"data\":{\"participants\":[{\"identifier\":{\"rawId\":\"REDACTED\",\"kind\":\"communicationUser\",\"communicationUser\":{\"id\":\"REDACTED\"}},\"isMuted\":false,\"isOnHold\":false},{\"identifier\":{\"rawId\":\"REDACTED\",\"kind\":\"communicationUser\",\"communicationUser\":{\"id\":\"REDACTED\"}},\"isMuted\":false,\"isOnHold\":true}],\"sequenceNumber\":3,\"resultInformation\":{\"code\":200,\"subCode\":0,\"message\":\"\"},\"version\":\"2024-09-01-preview\",\"callConnectionId\":\"2a002280-735b-49f6-9b04-f3e34728ad19\",\"serverCallId\":\"REDACTED\",\"correlationId\":\"bef88182-f4f9-4cb8-9a94-7c58ede238b1\",\"publicEventType\":\"Microsoft.Communication.ParticipantsUpdated\"},\"time\":\"2024-12-20T18:25:15.741316\\u002B00:00\",\"specversion\":\"1.0\",\"datacontenttype\":\"application/json\",\"subject\":\"calling/callConnections/2a002280-735b-49f6-9b04-f3e34728ad19\"}]","[{\"id\":\"REDACTED\",\"source\":\"calling/callConnections/2a002280-ba93-4255-9f16-c3f0d32cbebb\",\"type\":\"Microsoft.Communication.PlayStarted\",\"data\":{\"version\":\"2024-09-01-preview\",\"resultInformation\":{\"code\":200,\"subCode\":0,\"message\":\"Action completed successfully.\"},\"callConnectionId\":\"2a002280-ba93-4255-9f16-c3f0d32cbebb\",\"serverCallId\":\"REDACTED\",\"correlationId\":\"bef88182-f4f9-4cb8-9a94-7c58ede238b1\",\"publicEventType\":\"Microsoft.Communication.PlayStarted\"},\"time\":\"2024-12-20T18:25:21.4972602\\u002B00:00\",\"specversion\":\"1.0\",\"datacontenttype\":\"application/json\",\"subject\":\"calling/callConnections/2a002280-ba93-4255-9f16-c3f0d32cbebb\"}]","[{\"id\":\"REDACTED\",\"source\":\"calling/callConnections/2a002280-ba93-4255-9f16-c3f0d32cbebb\",\"type\":\"Microsoft.Communication.PlayCanceled\",\"data\":{\"version\":\"2024-09-01-preview\",\"resultInformation\":{\"code\":400,\"subCode\":8508,\"message\":\"Action falied, the operation was cancelled.\"},\"callConnectionId\":\"2a002280-ba93-4255-9f16-c3f0d32cbebb\",\"serverCallId\":\"REDACTED\",\"correlationId\":\"bef88182-f4f9-4cb8-9a94-7c58ede238b1\",\"publicEventType\":\"Microsoft.Communication.PlayCanceled\"},\"time\":\"2024-12-20T18:25:24.4389091\\u002B00:00\",\"specversion\":\"1.0\",\"datacontenttype\":\"application/json\",\"subject\":\"calling/callConnections/2a002280-ba93-4255-9f16-c3f0d32cbebb\"}]","[{\"id\":\"REDACTED\",\"source\":\"calling/callConnections/2a002280-735b-49f6-9b04-f3e34728ad19\",\"type\":\"Microsoft.Communication.ParticipantsUpdated\",\"data\":{\"participants\":[{\"identifier\":{\"rawId\":\"REDACTED\",\"kind\":\"communicationUser\",\"communicationUser\":{\"id\":\"REDACTED\"}},\"isMuted\":false,\"isOnHold\":false},{\"identifier\":{\"rawId\":\"REDACTED\",\"kind\":\"communicationUser\",\"communicationUser\":{\"id\":\"REDACTED\"}},\"isMuted\":false,\"isOnHold\":false}],\"sequenceNumber\":5,\"resultInformation\":{\"code\":200,\"subCode\":0,\"message\":\"\"},\"version\":\"2024-09-01-preview\",\"callConnectionId\":\"2a002280-735b-49f6-9b04-f3e34728ad19\",\"serverCallId\":\"REDACTED\",\"correlationId\":\"bef88182-f4f9-4cb8-9a94-7c58ede238b1\",\"publicEventType\":\"Microsoft.Communication.ParticipantsUpdated\"},\"time\":\"2024-12-20T18:25:24.5361406\\u002B00:00\",\"specversion\":\"1.0\",\"datacontenttype\":\"application/json\",\"subject\":\"calling/callConnections/2a002280-735b-49f6-9b04-f3e34728ad19\"}]","[{\"id\":\"REDACTED\",\"source\":\"calling/callConnections/2a002280-ba93-4255-9f16-c3f0d32cbebb\",\"type\":\"Microsoft.Communication.ParticipantsUpdated\",\"data\":{\"participants\":[{\"identifier\":{\"rawId\":\"REDACTED\",\"kind\":\"communicationUser\",\"communicationUser\":{\"id\":\"REDACTED\"}},\"isMuted\":false,\"isOnHold\":false},{\"identifier\":{\"rawId\":\"REDACTED\",\"kind\":\"communicationUser\",\"communicationUser\":{\"id\":\"REDACTED\"}},\"isMuted\":false,\"isOnHold\":false}],\"sequenceNumber\":5,\"resultInformation\":{\"code\":200,\"subCode\":0,\"message\":\"\"},\"version\":\"2024-09-01-preview\",\"callConnectionId\":\"2a002280-ba93-4255-9f16-c3f0d32cbebb\",\"serverCallId\":\"REDACTED\",\"correlationId\":\"bef88182-f4f9-4cb8-9a94-7c58ede238b1\",\"publicEventType\":\"Microsoft.Communication.ParticipantsUpdated\"},\"time\":\"2024-12-20T18:25:24.5361406\\u002B00:00\",\"specversion\":\"1.0\",\"datacontenttype\":\"application/json\",\"subject\":\"calling/callConnections/2a002280-ba93-4255-9f16-c3f0d32cbebb\"}]"] \ No newline at end of file