diff --git a/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallAutomationAsyncClient.java b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallAutomationAsyncClient.java index 463fff7b41a92..7364c21e4f767 100644 --- a/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallAutomationAsyncClient.java +++ b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallAutomationAsyncClient.java @@ -11,6 +11,7 @@ import com.azure.communication.callautomation.implementation.accesshelpers.CallConnectionPropertiesConstructorProxy; import com.azure.communication.callautomation.implementation.converters.CommunicationIdentifierConverter; import com.azure.communication.callautomation.implementation.converters.CommunicationUserIdentifierConverter; +import com.azure.communication.callautomation.implementation.converters.MicrosoftTeamsAppIdentifierConverter; import com.azure.communication.callautomation.implementation.converters.PhoneNumberIdentifierConverter; import com.azure.communication.callautomation.implementation.models.AnswerCallRequestInternal; import com.azure.communication.callautomation.implementation.models.CallIntelligenceOptionsInternal; @@ -23,6 +24,7 @@ import com.azure.communication.callautomation.implementation.models.MediaStreamingConfigurationInternal; import com.azure.communication.callautomation.implementation.models.MediaStreamingContentTypeInternal; import com.azure.communication.callautomation.implementation.models.MediaStreamingTransportTypeInternal; +import com.azure.communication.callautomation.implementation.models.MicrosoftTeamsAppIdentifierModel; import com.azure.communication.callautomation.implementation.models.RedirectCallRequestInternal; import com.azure.communication.callautomation.implementation.models.RejectCallRequestInternal; import com.azure.communication.callautomation.implementation.models.TranscriptionConfigurationInternal; @@ -39,6 +41,7 @@ import com.azure.communication.callautomation.models.TranscriptionOptions; import com.azure.communication.common.CommunicationIdentifier; import com.azure.communication.common.CommunicationUserIdentifier; +import com.azure.communication.common.MicrosoftTeamsAppIdentifier; import com.azure.core.annotation.ReturnType; import com.azure.core.annotation.ServiceClient; import com.azure.core.annotation.ServiceMethod; @@ -80,10 +83,12 @@ public final class CallAutomationAsyncClient { private final HttpPipeline httpPipelineInternal; private final String resourceUrl; private final CommunicationUserIdentifierModel sourceIdentity; + private final MicrosoftTeamsAppIdentifierModel opsSourceIdentity; private final CallAutomationEventProcessor eventProcessor; CallAutomationAsyncClient(AzureCommunicationCallAutomationServiceImpl callServiceClient, - CommunicationUserIdentifier sourceIdentity, CallAutomationEventProcessor eventProcessor) { + CommunicationUserIdentifier sourceIdentity, MicrosoftTeamsAppIdentifier opsSourceIdentity, + CallAutomationEventProcessor eventProcessor) { this.callConnectionsInternal = callServiceClient.getCallConnections(); this.azureCommunicationCallAutomationServiceInternal = callServiceClient; this.callRecordingsInternal = callServiceClient.getCallRecordings(); @@ -97,6 +102,8 @@ public final class CallAutomationAsyncClient { this.resourceUrl = callServiceClient.getEndpoint(); this.sourceIdentity = sourceIdentity == null ? null : CommunicationUserIdentifierConverter.convert(sourceIdentity); + this.opsSourceIdentity + = opsSourceIdentity == null ? null : MicrosoftTeamsAppIdentifierConverter.convert(opsSourceIdentity); } /** @@ -115,6 +122,14 @@ public CommunicationUserIdentifier getSourceIdentity() { return sourceIdentity == null ? null : CommunicationUserIdentifierConverter.convert(sourceIdentity); } + /** + * Get OPS Source Identity that is used for create OPS call + * @return {@link CommunicationUserIdentifier} represent source + */ + public MicrosoftTeamsAppIdentifier getOPSSourceIdentity() { + return opsSourceIdentity == null ? null : MicrosoftTeamsAppIdentifierConverter.convert(opsSourceIdentity); + } + //region Pre-call Actions /** * Create a call connection request from a source identity to a target identity. @@ -224,6 +239,7 @@ private CreateCallRequestInternal getCreateCallRequestInternal(CreateCallOptions PhoneNumberIdentifierConverter.convert(createCallOptions.getCallInvite().getSourceCallerIdNumber())) .setSourceDisplayName(createCallOptions.getCallInvite().getSourceDisplayName()) .setSource(sourceIdentity) + .setOpsSource(opsSourceIdentity) .setTargets(targetsModel) .setCallbackUri(createCallOptions.getCallbackUrl()) .setCallIntelligenceOptions(callIntelligenceOptionsInternal) @@ -272,6 +288,7 @@ private CreateCallRequestInternal getCreateCallRequestInternal(CreateGroupCallOp PhoneNumberIdentifierConverter.convert(createCallGroupOptions.getSourceCallIdNumber())) .setSourceDisplayName(createCallGroupOptions.getSourceDisplayName()) .setSource(sourceIdentity) + .setOpsSource(opsSourceIdentity) .setTargets(targetsModel) .setCallbackUri(createCallGroupOptions.getCallbackUrl()) .setCallIntelligenceOptions(callIntelligenceOptionsInternal) diff --git a/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallAutomationClientBuilder.java b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallAutomationClientBuilder.java index a5b953a118175..4f7dddb1c03c8 100644 --- a/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallAutomationClientBuilder.java +++ b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallAutomationClientBuilder.java @@ -8,6 +8,7 @@ import com.azure.communication.callautomation.implementation.CustomBearerTokenAuthenticationPolicy; import com.azure.communication.callautomation.implementation.CustomHmacAuthenticationPolicy; import com.azure.communication.common.CommunicationUserIdentifier; +import com.azure.communication.common.MicrosoftTeamsAppIdentifier; import com.azure.communication.common.implementation.CommunicationConnectionString; import com.azure.communication.common.implementation.HmacAuthenticationPolicy; import com.azure.core.annotation.ServiceClientBuilder; @@ -81,6 +82,7 @@ public final class CallAutomationClientBuilder private RetryPolicy retryPolicy; private RetryOptions retryOptions; private CommunicationUserIdentifier sourceIdentity; + private MicrosoftTeamsAppIdentifier opsSourceIdentity; /** * Public default constructor @@ -185,6 +187,16 @@ public CallAutomationClientBuilder sourceIdentity(CommunicationUserIdentifier so return this; } + /** + * Set One Phone System Source Identity used to create call + * @param opsSourceIdentity {@link MicrosoftTeamsAppIdentifier} to used to create call. + * @return {@link CallAutomationClientBuilder} object. + */ + public CallAutomationClientBuilder opsSourceIdentity(MicrosoftTeamsAppIdentifier opsSourceIdentity) { + this.opsSourceIdentity = opsSourceIdentity; + return this; + } + /** * Sets the retry policy to use (using the RetryPolicy type). *

@@ -319,7 +331,8 @@ public CallAutomationClientBuilder addPolicy(HttpPipelinePolicy customPolicy) { * and {@link #retryPolicy(RetryPolicy)} have been set. */ public CallAutomationAsyncClient buildAsyncClient() { - return new CallAutomationAsyncClient(createServiceImpl(), sourceIdentity, new CallAutomationEventProcessor()); + return new CallAutomationAsyncClient(createServiceImpl(), sourceIdentity, opsSourceIdentity, + new CallAutomationEventProcessor()); } /** diff --git a/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/implementation/CallDialogsImpl.java b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/implementation/CallDialogsImpl.java index 35612891cf6a7..62ca65b817153 100644 --- a/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/implementation/CallDialogsImpl.java +++ b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/implementation/CallDialogsImpl.java @@ -211,11 +211,11 @@ public DialogStateResponse startDialog(String callConnectionId, String dialogId, } /** - * Stop a dialog. + * The stopDialog operation. * - * @param callConnectionId The call connection id. - * @param dialogId The dialog id. - * @param operationCallbackUri Operation callback URI. + * @param callConnectionId The callConnectionId parameter. + * @param dialogId The dialogId parameter. + * @param operationCallbackUri The operationCallbackUri parameter. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws CommunicationErrorResponseException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. @@ -230,11 +230,11 @@ public Mono> stopDialogWithResponseAsync(String callConnectionId, } /** - * Stop a dialog. + * The stopDialog operation. * - * @param callConnectionId The call connection id. - * @param dialogId The dialog id. - * @param operationCallbackUri Operation callback URI. + * @param callConnectionId The callConnectionId parameter. + * @param dialogId The dialogId parameter. + * @param operationCallbackUri The operationCallbackUri parameter. * @param context The context to associate with this operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws CommunicationErrorResponseException thrown if the request is rejected by server. @@ -250,11 +250,11 @@ public Mono> stopDialogWithResponseAsync(String callConnectionId, } /** - * Stop a dialog. + * The stopDialog operation. * - * @param callConnectionId The call connection id. - * @param dialogId The dialog id. - * @param operationCallbackUri Operation callback URI. + * @param callConnectionId The callConnectionId parameter. + * @param dialogId The dialogId parameter. + * @param operationCallbackUri The operationCallbackUri parameter. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws CommunicationErrorResponseException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. @@ -267,11 +267,11 @@ public Mono stopDialogAsync(String callConnectionId, String dialogId, Stri } /** - * Stop a dialog. + * The stopDialog operation. * - * @param callConnectionId The call connection id. - * @param dialogId The dialog id. - * @param operationCallbackUri Operation callback URI. + * @param callConnectionId The callConnectionId parameter. + * @param dialogId The dialogId parameter. + * @param operationCallbackUri The operationCallbackUri parameter. * @param context The context to associate with this operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws CommunicationErrorResponseException thrown if the request is rejected by server. @@ -286,11 +286,11 @@ public Mono stopDialogAsync(String callConnectionId, String dialogId, Stri } /** - * Stop a dialog. + * The stopDialog operation. * - * @param callConnectionId The call connection id. - * @param dialogId The dialog id. - * @param operationCallbackUri Operation callback URI. + * @param callConnectionId The callConnectionId parameter. + * @param dialogId The dialogId parameter. + * @param operationCallbackUri The operationCallbackUri parameter. * @param context The context to associate with this operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws CommunicationErrorResponseException thrown if the request is rejected by server. @@ -304,11 +304,11 @@ public Response stopDialogWithResponse(String callConnectionId, String dia } /** - * Stop a dialog. + * The stopDialog operation. * - * @param callConnectionId The call connection id. - * @param dialogId The dialog id. - * @param operationCallbackUri Operation callback URI. + * @param callConnectionId The callConnectionId parameter. + * @param dialogId The dialogId parameter. + * @param operationCallbackUri The operationCallbackUri parameter. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws CommunicationErrorResponseException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. diff --git a/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/implementation/converters/MicrosoftTeamsAppIdentifierConverter.java b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/implementation/converters/MicrosoftTeamsAppIdentifierConverter.java new file mode 100644 index 0000000000000..5d10d7fc34fc9 --- /dev/null +++ b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/implementation/converters/MicrosoftTeamsAppIdentifierConverter.java @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.communication.callautomation.implementation.converters; + +import com.azure.communication.callautomation.implementation.models.MicrosoftTeamsAppIdentifierModel; +import com.azure.communication.common.MicrosoftTeamsAppIdentifier; + +/** + * A converter for {@link MicrosoftTeamsAppIdentifier} and {@link MicrosoftTeamsAppIdentifierModel} + */ +public final class MicrosoftTeamsAppIdentifierConverter { + + /** + * Converts to {@link MicrosoftTeamsAppIdentifierModel}. + */ + public static MicrosoftTeamsAppIdentifierModel convert(MicrosoftTeamsAppIdentifier microsoftTeamsAppIdentifier) { + + MicrosoftTeamsAppIdentifierModel microsoftTeamsAppIdentifierModel + = (microsoftTeamsAppIdentifier == null || microsoftTeamsAppIdentifier.getAppId().isEmpty()) + ? null + : CommunicationIdentifierConverter + .convert(new MicrosoftTeamsAppIdentifier(microsoftTeamsAppIdentifier.getAppId())) + .getMicrosoftTeamsApp(); + return microsoftTeamsAppIdentifierModel; + } + + /** + * Converts to {@link MicrosoftTeamsAppIdentifier}. + */ + public static MicrosoftTeamsAppIdentifier + convert(MicrosoftTeamsAppIdentifierModel microsoftTeamsAppIdentifierModel) { + + MicrosoftTeamsAppIdentifier microsoftTeamsAppIdentifier + = (microsoftTeamsAppIdentifierModel == null || microsoftTeamsAppIdentifierModel.getAppId().isEmpty()) + ? null + : new MicrosoftTeamsAppIdentifier(microsoftTeamsAppIdentifierModel.getAppId()); + + return microsoftTeamsAppIdentifier; + } + + private MicrosoftTeamsAppIdentifierConverter() { + } +} diff --git a/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/implementation/models/AnswerCallRequestInternal.java b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/implementation/models/AnswerCallRequestInternal.java index d6fa330de3523..09f81c06d932d 100644 --- a/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/implementation/models/AnswerCallRequestInternal.java +++ b/sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/implementation/models/AnswerCallRequestInternal.java @@ -26,6 +26,11 @@ public final class AnswerCallRequestInternal implements JsonSerializable(Collections.singletonList( + new AbstractMap.SimpleEntry<>(generateOPSCallProperties(CALL_CONNECTION_ID, CALL_SERVER_CALL_ID, + PHONE_NUMBER, CALL_CONNECTION_STATE, CALL_CALLBACK_URL, MICROSOFT_TEAMS_APP_ID), 201)))); + List targets + = new ArrayList<>(Collections.singletonList(new PhoneNumberIdentifier(PHONE_NUMBER))); + + CreateCallResult createCallResult + = callAutomationAsyncClient.createGroupCall(targets, CALL_CALLBACK_URL).block(); + assertNotNull(createCallResult); + assertEquals(MICROSOFT_TEAMS_APP_ID, + ((MicrosoftTeamsAppIdentifier) createCallResult.getCallConnectionProperties().getSource()).getAppId()); + assertEquals(PHONE_NUMBER, + ((PhoneNumberIdentifier) createCallResult.getCallConnectionProperties().getTargetParticipants().get(0)) + .getPhoneNumber()); + } + @Test public void createGroupCallWithResponse() { CallAutomationAsyncClient callAutomationAsyncClient = getCallAutomationAsyncClient(new ArrayList<>( diff --git a/sdk/communication/azure-communication-callautomation/src/test/java/com/azure/communication/callautomation/CallAutomationUnitTestBase.java b/sdk/communication/azure-communication-callautomation/src/test/java/com/azure/communication/callautomation/CallAutomationUnitTestBase.java index 8d0a743f905fa..b9304ce4f0434 100644 --- a/sdk/communication/azure-communication-callautomation/src/test/java/com/azure/communication/callautomation/CallAutomationUnitTestBase.java +++ b/sdk/communication/azure-communication-callautomation/src/test/java/com/azure/communication/callautomation/CallAutomationUnitTestBase.java @@ -16,8 +16,13 @@ import com.azure.communication.callautomation.implementation.models.CallConnectionPropertiesInternal; import com.azure.communication.callautomation.implementation.models.CallConnectionStateModelInternal; import com.azure.communication.callautomation.implementation.models.CallParticipantInternal; +import com.azure.communication.callautomation.implementation.models.CommunicationCloudEnvironmentModel; +import com.azure.communication.callautomation.implementation.models.CommunicationIdentifierModel; +import com.azure.communication.callautomation.implementation.models.CommunicationIdentifierModelKind; import com.azure.communication.callautomation.implementation.models.GetParticipantsResponseInternal; import com.azure.communication.callautomation.implementation.models.DialogStateResponse; +import com.azure.communication.callautomation.implementation.models.MicrosoftTeamsAppIdentifierModel; +import com.azure.communication.callautomation.implementation.models.PhoneNumberIdentifierModel; import com.azure.communication.callautomation.models.MediaStreamingAudioChannel; import com.azure.communication.callautomation.models.MediaStreamingOptions; import com.azure.communication.callautomation.models.MediaStreamingContent; @@ -55,6 +60,8 @@ public class CallAutomationUnitTestBase { static final String DATA_SUBSCRIPTION_ID = "dataSubscriptionId"; static final String DIALOG_ID = "dialogId"; static final String BOT_APP_ID = "botAppId"; + static final String MICROSOFT_TEAMS_APP_ID = "28:acs:redacted"; + static final String PHONE_NUMBER = "+18001234567"; static final MediaStreamingOptions MEDIA_STREAMING_CONFIGURATION = new MediaStreamingOptions("https://websocket.url.com", MediaStreamingTransport.WEBSOCKET, @@ -84,6 +91,25 @@ public static String generateCallProperties(String callConnectionId, String serv return serializeObject(result); } + public static String generateOPSCallProperties(String callConnectionId, String serverCallId, String targetId, + String connectionState, String callbackUri, String opsSourceId) { + CallConnectionPropertiesInternal result = new CallConnectionPropertiesInternal() + .setCallConnectionId(callConnectionId) + .setServerCallId(serverCallId) + .setCallbackUri(callbackUri) + .setCallConnectionState(CallConnectionStateModelInternal.fromString(connectionState)) + .setSource(new CommunicationIdentifierModel().setRawId(opsSourceId) + .setKind(CommunicationIdentifierModelKind.MICROSOFT_TEAMS_APP) + .setMicrosoftTeamsApp(new MicrosoftTeamsAppIdentifierModel().setAppId(opsSourceId) + .setCloud(CommunicationCloudEnvironmentModel.PUBLIC))) + .setTargets( + new ArrayList<>(Collections.singletonList(new CommunicationIdentifierModel().setRawId("+4:" + targetId) + .setKind(CommunicationIdentifierModelKind.PHONE_NUMBER) + .setPhoneNumber(new PhoneNumberIdentifierModel().setValue(targetId))))); + + return serializeObject(result); + } + public static String generateGetParticipantResponse(String callerId, boolean isMuted, boolean isHold) { CallParticipantInternal callParticipant = ModelGenerator.generateAcsCallParticipantInternal(callerId, isMuted, isHold); diff --git a/sdk/communication/azure-communication-callautomation/swagger/README.md b/sdk/communication/azure-communication-callautomation/swagger/README.md index e71dd1c9ec59b..9b564754c221f 100644 --- a/sdk/communication/azure-communication-callautomation/swagger/README.md +++ b/sdk/communication/azure-communication-callautomation/swagger/README.md @@ -21,7 +21,7 @@ There is one swagger for Calling management APIs. ```ps cd -autorest README.md --java --v4 --use=@autorest/java@4.0.20 --use=@autorest/modelerfour@4.15.442 +autorest README.md --java --v4 ``` ### Code generation settings @@ -29,7 +29,7 @@ autorest README.md --java --v4 --use=@autorest/java@4.0.20 --use=@autorest/model tag: package-2023-10-03-preview use: '@autorest/java@4.1.29' require: - - https://github.com/Azure/azure-rest-api-specs/blob/156ff363e44f764ddd8a0a6adcd371610240ba15/specification/communication/data-plane/CallAutomation/readme.md + - https://github.com/Azure/azure-rest-api-specs/blob/be2a0fa68829fcb15c4e6b47aa6bc4bdd566c1cf/specification/communication/data-plane/CallAutomation/readme.md java: true output-folder: ../ license-header: MICROSOFT_MIT_SMALL