Skip to content

Commit 1a210eb

Browse files
Add MoveParticipants Functionality API and Event Handling Support (#45653)
* Adding Move Participants Functionality * Updating the revapi checks to check in to the feature branch * Update sdk/communication/azure-communication-callautomation/pom.xml --------- Co-authored-by: Wes Haggard <[email protected]>
1 parent 312c6b4 commit 1a210eb

File tree

14 files changed

+861
-0
lines changed

14 files changed

+861
-0
lines changed

sdk/communication/azure-communication-callautomation/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
<checkstyle.suppressionsLocation>checkstyle-suppressions.xml</checkstyle.suppressionsLocation>
5454
<spotbugs.skip>false</spotbugs.skip>
5555
<spotbugs.excludeFilterFile>spotbugs-exclude.xml</spotbugs.excludeFilterFile>
56+
<revapi.skip>true</revapi.skip> <!--Disabling RevAPI checks for this feature branch as it currently compares against the GA version, which is not relevant for these changes. Note: Do not apply this flag to the main branch -->
5657
</properties>
5758

5859
<dependencies>

sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallAutomationEventParser.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
import com.azure.communication.callautomation.models.events.MediaStreamingFailed;
4141
import com.azure.communication.callautomation.models.events.MediaStreamingStarted;
4242
import com.azure.communication.callautomation.models.events.MediaStreamingStopped;
43+
import com.azure.communication.callautomation.models.events.MoveParticipantFailed;
44+
import com.azure.communication.callautomation.models.events.MoveParticipantSucceeded;
4345
import com.azure.communication.callautomation.models.events.ParticipantsUpdated;
4446
import com.azure.communication.callautomation.models.events.PlayCanceled;
4547
import com.azure.communication.callautomation.models.events.PlayCompleted;
@@ -161,6 +163,10 @@ private static CallAutomationEventBase parseSingleCloudEvent(String data, String
161163
ret = RemoveParticipantFailed.fromJson(jsonReader);
162164
} else if (Objects.equals(eventType, "Microsoft.Communication.RemoveParticipantSucceeded")) {
163165
ret = RemoveParticipantSucceeded.fromJson(jsonReader);
166+
} else if (Objects.equals(eventType, "Microsoft.Communication.MoveParticipantFailed")) {
167+
ret = MoveParticipantFailed.fromJson(jsonReader);
168+
} else if (Objects.equals(eventType, "Microsoft.Communication.MoveParticipantSucceeded")) {
169+
ret = MoveParticipantSucceeded.fromJson(jsonReader);
164170
} else if (Objects.equals(eventType, "Microsoft.Communication.ContinuousDtmfRecognitionToneReceived")) {
165171
ret = ContinuousDtmfRecognitionToneReceived.fromJson(jsonReader);
166172
} else if (Objects.equals(eventType, "Microsoft.Communication.ContinuousDtmfRecognitionToneFailed")) {

sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallConnection.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
import com.azure.communication.callautomation.models.AddParticipantResult;
1111
import com.azure.communication.callautomation.models.CallConnectionProperties;
1212
import com.azure.communication.callautomation.models.CallInvite;
13+
import com.azure.communication.callautomation.models.MoveParticipantsOptions;
14+
import com.azure.communication.callautomation.models.MoveParticipantsResult;
1315
import com.azure.communication.callautomation.models.MuteParticipantOptions;
1416
import com.azure.communication.callautomation.models.MuteParticipantResult;
1517
import com.azure.communication.callautomation.models.RemoveParticipantOptions;
@@ -25,6 +27,7 @@
2527
import com.azure.core.http.rest.Response;
2628
import com.azure.core.util.Context;
2729
import com.azure.core.exception.HttpResponseException;
30+
import java.util.List;
2831

2932
/**
3033
* CallConnection for mid-call actions
@@ -226,6 +229,48 @@ public RemoveParticipantResult removeParticipant(CommunicationIdentifier partici
226229
return callConnectionAsync.removeParticipantWithResponseInternal(removeParticipantOptions, context).block();
227230
}
228231

232+
/**
233+
* Move participants from one call to another.
234+
*
235+
* @param targetParticipants participants to move.
236+
* @param fromCall The CallConnectionId for the call you want to move the participant from.
237+
* @throws HttpResponseException thrown if the request is rejected by server.
238+
* @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
239+
* @return Result of moving participants to the call.
240+
*/
241+
@ServiceMethod(returns = ReturnType.SINGLE)
242+
public MoveParticipantsResult moveParticipants(List<CommunicationIdentifier> targetParticipants, String fromCall) {
243+
return callConnectionAsync.moveParticipants(targetParticipants, fromCall).block();
244+
}
245+
246+
/**
247+
* Move participants from one call to another.
248+
*
249+
* @param moveParticipantsOptions Options bag for moveParticipants
250+
* @throws HttpResponseException thrown if the request is rejected by server.
251+
* @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
252+
* @return Result of moving participants to the call.
253+
*/
254+
@ServiceMethod(returns = ReturnType.SINGLE)
255+
public MoveParticipantsResult moveParticipants(MoveParticipantsOptions moveParticipantsOptions) {
256+
return callConnectionAsync.moveParticipants(moveParticipantsOptions).block();
257+
}
258+
259+
/**
260+
* Move participants from one call to another.
261+
*
262+
* @param moveParticipantsOptions Options bag for moveParticipants
263+
* @param context A {@link Context} representing the request context.
264+
* @throws HttpResponseException thrown if the request is rejected by server.
265+
* @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
266+
* @return Response with result of moving participants to the call.
267+
*/
268+
@ServiceMethod(returns = ReturnType.SINGLE)
269+
public Response<MoveParticipantsResult>
270+
moveParticipantsWithResponse(MoveParticipantsOptions moveParticipantsOptions, Context context) {
271+
return callConnectionAsync.moveParticipantsWithResponseInternal(moveParticipantsOptions, context).block();
272+
}
273+
229274
/**
230275
* Mutes a participant in the call.
231276
*

sdk/communication/azure-communication-callautomation/src/main/java/com/azure/communication/callautomation/CallConnectionAsync.java

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.azure.communication.callautomation.implementation.accesshelpers.AddParticipantResponseConstructorProxy;
1010
import com.azure.communication.callautomation.implementation.accesshelpers.CallConnectionPropertiesConstructorProxy;
1111
import com.azure.communication.callautomation.implementation.accesshelpers.CancelAddParticipantResponseConstructorProxy;
12+
import com.azure.communication.callautomation.implementation.accesshelpers.MoveParticipantsResponseConstructorProxy;
1213
import com.azure.communication.callautomation.implementation.accesshelpers.MuteParticipantsResponseConstructorProxy;
1314
import com.azure.communication.callautomation.implementation.accesshelpers.RemoveParticipantResponseConstructorProxy;
1415
import com.azure.communication.callautomation.implementation.accesshelpers.TransferCallResponseConstructorProxy;
@@ -19,6 +20,7 @@
1920
import com.azure.communication.callautomation.implementation.models.AddParticipantRequestInternal;
2021
import com.azure.communication.callautomation.implementation.models.CancelAddParticipantRequest;
2122
import com.azure.communication.callautomation.implementation.models.CustomCallingContext;
23+
import com.azure.communication.callautomation.implementation.models.MoveParticipantsRequest;
2224
import com.azure.communication.callautomation.implementation.models.MuteParticipantsRequestInternal;
2325
import com.azure.communication.callautomation.implementation.models.RemoveParticipantRequestInternal;
2426
import com.azure.communication.callautomation.implementation.models.TransferToParticipantRequestInternal;
@@ -30,6 +32,8 @@
3032
import com.azure.communication.callautomation.models.CallParticipant;
3133
import com.azure.communication.callautomation.models.CancelAddParticipantOperationOptions;
3234
import com.azure.communication.callautomation.models.CancelAddParticipantOperationResult;
35+
import com.azure.communication.callautomation.models.MoveParticipantsOptions;
36+
import com.azure.communication.callautomation.models.MoveParticipantsResult;
3337
import com.azure.communication.callautomation.models.MuteParticipantOptions;
3438
import com.azure.communication.callautomation.models.MuteParticipantResult;
3539
import com.azure.communication.callautomation.models.RemoveParticipantOptions;
@@ -59,6 +63,8 @@
5963
import java.net.URLEncoder;
6064
import java.nio.charset.StandardCharsets;
6165
import java.util.Collections;
66+
import java.util.List;
67+
import java.util.stream.Collectors;
6268

6369
import static com.azure.core.util.FluxUtil.monoError;
6470
import static com.azure.core.util.FluxUtil.withContext;
@@ -441,6 +447,74 @@ public Mono<RemoveParticipantResult> removeParticipant(CommunicationIdentifier p
441447
}
442448
}
443449

450+
/**
451+
* Move participants from one call to another.
452+
*
453+
* @param targetParticipants participants to move.
454+
* @param fromCall The CallConnectionId for the call you want to move the participant from.
455+
* @throws HttpResponseException thrown if the request is rejected by server.
456+
* @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
457+
* @return Result of moving participants to the call.
458+
*/
459+
@ServiceMethod(returns = ReturnType.SINGLE)
460+
public Mono<MoveParticipantsResult> moveParticipants(List<CommunicationIdentifier> targetParticipants,
461+
String fromCall) {
462+
return moveParticipants(new MoveParticipantsOptions(targetParticipants, fromCall));
463+
}
464+
465+
/**
466+
* Move participants from one call to another.
467+
*
468+
* @param moveParticipantsOptions Options bag for moveParticipants
469+
* @throws HttpResponseException thrown if the request is rejected by server.
470+
* @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
471+
* @return Result of moving participants to the call.
472+
*/
473+
@ServiceMethod(returns = ReturnType.SINGLE)
474+
public Mono<MoveParticipantsResult> moveParticipants(MoveParticipantsOptions moveParticipantsOptions) {
475+
return moveParticipantsWithResponse(moveParticipantsOptions).flatMap(FluxUtil::toMono);
476+
}
477+
478+
/**
479+
* Move participants from one call to another.
480+
*
481+
* @param moveParticipantsOptions Options bag for moveParticipants
482+
* @throws HttpResponseException thrown if the request is rejected by server.
483+
* @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
484+
* @return Response with result of moving participants to the call.
485+
*/
486+
@ServiceMethod(returns = ReturnType.SINGLE)
487+
public Mono<Response<MoveParticipantsResult>>
488+
moveParticipantsWithResponse(MoveParticipantsOptions moveParticipantsOptions) {
489+
return withContext(context -> moveParticipantsWithResponseInternal(moveParticipantsOptions, context));
490+
}
491+
492+
Mono<Response<MoveParticipantsResult>>
493+
moveParticipantsWithResponseInternal(MoveParticipantsOptions moveParticipantsOptions, Context context) {
494+
try {
495+
context = context == null ? Context.NONE : context;
496+
497+
MoveParticipantsRequest request = new MoveParticipantsRequest()
498+
.setTargetParticipants(moveParticipantsOptions.getTargetParticipants()
499+
.stream()
500+
.map(CommunicationIdentifierConverter::convert)
501+
.collect(Collectors.toList()))
502+
.setFromCall(moveParticipantsOptions.getFromCall())
503+
.setOperationContext(moveParticipantsOptions.getOperationContext())
504+
.setOperationCallbackUri(moveParticipantsOptions.getOperationCallbackUrl());
505+
506+
return callConnectionInternal.moveParticipantsWithResponseAsync(callConnectionId, request, context)
507+
.map(response -> {
508+
MoveParticipantsResult result
509+
= MoveParticipantsResponseConstructorProxy.create(response.getValue());
510+
result.setEventProcessor(eventProcessor, callConnectionId, result.getOperationContext());
511+
return new SimpleResponse<>(response, result);
512+
});
513+
} catch (RuntimeException ex) {
514+
return monoError(logger, ex);
515+
}
516+
}
517+
444518
/**
445519
* Mutes a participant in the call.
446520
*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
package com.azure.communication.callautomation.implementation.accesshelpers;
5+
6+
import com.azure.communication.callautomation.implementation.models.MoveParticipantsResponse;
7+
import com.azure.communication.callautomation.models.MoveParticipantsResult;
8+
9+
/**
10+
* Helper class to access private values of {@link MoveParticipantsResult} across package boundaries.
11+
*/
12+
public final class MoveParticipantsResponseConstructorProxy {
13+
private static MoveParticipantsResponseConstructorAccessor accessor;
14+
15+
private MoveParticipantsResponseConstructorProxy() {
16+
}
17+
18+
/**
19+
* Type defining the methods to set the non-public properties of a {@link MoveParticipantsResponseConstructorAccessor}
20+
* instance.
21+
*/
22+
public interface MoveParticipantsResponseConstructorAccessor {
23+
/**
24+
* Creates a new instance of {@link MoveParticipantsResult} backed by an internal instance of
25+
* {@link MoveParticipantsResult}.
26+
*
27+
* @param internalResponse The internal response.
28+
* @return A new instance of {@link MoveParticipantsResult}.
29+
*/
30+
MoveParticipantsResult create(MoveParticipantsResponse internalResponse);
31+
}
32+
33+
/**
34+
* The method called from {@link MoveParticipantsResult} to set it's accessor.
35+
*
36+
* @param accessor The accessor.
37+
*/
38+
public static void setAccessor(final MoveParticipantsResponseConstructorAccessor accessor) {
39+
MoveParticipantsResponseConstructorProxy.accessor = accessor;
40+
}
41+
42+
/**
43+
* Creates a new instance of {@link MoveParticipantsResult} backed by an internal instance of
44+
* {@link MoveParticipantsResult}.
45+
*
46+
* @param internalResponse The internal response.
47+
* @return A new instance of {@link MoveParticipantsResult}.
48+
*/
49+
public static MoveParticipantsResult create(MoveParticipantsResponse internalResponse) {
50+
// This looks odd but is necessary, it is possible to engage the access helper before anywhere else in the
51+
// application accesses MoveParticipantsResult which triggers the accessor to be configured. So, if the accessor
52+
// is null this effectively pokes the class to set up the accessor.
53+
if (accessor == null) {
54+
new MoveParticipantsResult();
55+
}
56+
57+
assert accessor != null;
58+
return accessor.create(internalResponse);
59+
}
60+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
package com.azure.communication.callautomation.models;
5+
6+
import com.azure.communication.callautomation.models.events.MoveParticipantFailed;
7+
import com.azure.communication.callautomation.models.events.MoveParticipantSucceeded;
8+
import com.azure.communication.common.CommunicationIdentifier;
9+
import com.azure.core.annotation.Immutable;
10+
11+
/**
12+
* The result of a move participant event.
13+
*/
14+
@Immutable
15+
public final class MoveParticipantEventResult {
16+
private final boolean isSuccess;
17+
private final MoveParticipantSucceeded successResult;
18+
private final MoveParticipantFailed failureResult;
19+
private final CommunicationIdentifier participant;
20+
private final String fromCall;
21+
22+
/**
23+
* Initializes a new instance of MoveParticipantEventResult.
24+
*
25+
* @param isSuccess the success status of the move participant operation.
26+
* @param successResult the move participant succeeded event.
27+
* @param failureResult the move participant failed event.
28+
* @param participant the participant.
29+
* @param fromCall the call connection id for the call to move the participant from.
30+
*/
31+
MoveParticipantEventResult(boolean isSuccess, MoveParticipantSucceeded successResult,
32+
MoveParticipantFailed failureResult, CommunicationIdentifier participant, String fromCall) {
33+
this.isSuccess = isSuccess;
34+
this.successResult = successResult;
35+
this.failureResult = failureResult;
36+
this.participant = participant;
37+
this.fromCall = fromCall;
38+
}
39+
40+
/**
41+
* Gets the success status of the move participant operation.
42+
*
43+
* @return the success status of the move participant operation.
44+
*/
45+
public boolean isSuccess() {
46+
return isSuccess;
47+
}
48+
49+
/**
50+
* Gets the move participant succeeded event.
51+
*
52+
* @return the move participant succeeded event.
53+
*/
54+
public MoveParticipantSucceeded getSuccessResult() {
55+
return successResult;
56+
}
57+
58+
/**
59+
* Gets the move participant failed event.
60+
*
61+
* @return the move participant failed event.
62+
*/
63+
public MoveParticipantFailed getFailureResult() {
64+
return failureResult;
65+
}
66+
67+
/**
68+
* Gets the participant.
69+
*
70+
* @return the participant.
71+
*/
72+
public CommunicationIdentifier getParticipant() {
73+
return participant;
74+
}
75+
76+
/**
77+
* Gets the call connection id for the call to move the participant from.
78+
*
79+
* @return the from call connection id.
80+
*/
81+
public String getFromCall() {
82+
return fromCall;
83+
}
84+
}

0 commit comments

Comments
 (0)