Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import java.util.concurrent.CompletionStage;
import org.eclipse.uprotocol.communication.CallOptions;
import org.eclipse.uprotocol.communication.RpcClient;
import org.eclipse.uprotocol.communication.RpcMapper;
import org.eclipse.uprotocol.communication.UPayload;
import org.eclipse.uprotocol.communication.UStatusException;
import org.eclipse.uprotocol.core.utwin.v2.GetLastMessagesRequest;
Expand All @@ -34,33 +33,34 @@
/**
* The uTwin client implementation using the RpcClient uP-L2 communication layer interface.
*/
public class SimpleUTwinClient implements UTwinClient {
private final RpcClient rpcClient;
public class RpcClientBasedUTwinClient implements UTwinClient {

private static final ServiceDescriptor UTWIN = UTwinProto.getDescriptor().getServices().get(0);
static final ServiceDescriptor UTWIN = UTwinProto.getDescriptor().getServices().get(0);

// TODO: The following items eventually need to be pulled from generated code
private static final UUri GETLASTMESSAGE_METHOD = UriFactory.fromProto(UTWIN, 1);
static final UUri GETLASTMESSAGE_METHOD = UriFactory.fromProto(UTWIN, 1);

private final RpcClient rpcClient;

/**
* Create a new instance of the uTwin client passing in the RPCClient to use for communication.
* Creates a new client for the uTwin service.
*
* @param rpcClient The RPC client to use for communication.
*/
public SimpleUTwinClient(RpcClient rpcClient) {
public RpcClientBasedUTwinClient(RpcClient rpcClient) {
this.rpcClient = rpcClient;
}


/**
* Fetch the last messages for a batch of topics.
* Fetches the last messages for a batch of topics.
*
* @param topics {@link UUriBatch} batch of 1 or more topics to fetch the last messages for.
* @param options The call options.
* @return CompletionStage completes successfully with {@link GetLastMessagesResponse} if uTwin was able
* to fetch the topics or completes exceptionally with {@link UStatus} with the failure reason.
* such as {@code UCode.NOT_FOUND}, {@code UCode.PERMISSION_DENIED} etc...
* @throws NullPointerException if topics or options is {@code null}.
*/
@Override
public CompletionStage<GetLastMessagesResponse> getLastMessages(UUriBatch topics, CallOptions options) {
Expand All @@ -73,8 +73,8 @@ public CompletionStage<GetLastMessagesResponse> getLastMessages(UUriBatch topics
new UStatusException(UCode.INVALID_ARGUMENT, "topics must not be empty"));
}

GetLastMessagesRequest request = GetLastMessagesRequest.newBuilder().setTopics(topics).build();
return RpcMapper.mapResponse(rpcClient.invokeMethod(
GETLASTMESSAGE_METHOD, UPayload.pack(request), options), GetLastMessagesResponse.class);
}
final var request = GetLastMessagesRequest.newBuilder().setTopics(topics).build();
return rpcClient.invokeMethod(GETLASTMESSAGE_METHOD, UPayload.pack(request), options)
.thenApply(response -> UPayload.unpackOrDefaultInstance(response, GetLastMessagesResponse.class));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/**
* SPDX-FileCopyrightText: 2024 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*/

package org.eclipse.uprotocol.client.utwin.v2;

import static org.junit.Assert.assertThrows;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.eclipse.uprotocol.communication.CallOptions;
import org.eclipse.uprotocol.communication.RpcClient;
import org.eclipse.uprotocol.communication.UPayload;
import org.eclipse.uprotocol.communication.UStatusException;
import org.eclipse.uprotocol.core.utwin.v2.GetLastMessagesResponse;
import org.eclipse.uprotocol.v1.UCode;
import org.eclipse.uprotocol.v1.UUri;
import org.eclipse.uprotocol.v1.UUriBatch;

/**
* The uTwin client implementation using RpcClient uP-L2 communication layer interface.
* This is the test code for said implementation.
*/
@ExtendWith(MockitoExtension.class)
class RpcClientBasedUTwinClientTest {

private static final UUri TOPIC = UUri.newBuilder()
.setAuthorityName("hartley")
.setUeId(0x0003)
.setUeVersionMajor(0x01)
.setResourceId(0x8000)
.build();

@Mock
private RpcClient rpcClient;
private UTwinClient twinClient;

@BeforeEach
void setUp() {
twinClient = new RpcClientBasedUTwinClient(rpcClient);
}

@Test
@DisplayName("Test calling getLastMessages() with valid topics")
void testGetLastMessages() {
when(rpcClient.invokeMethod(
eq(RpcClientBasedUTwinClient.GETLASTMESSAGE_METHOD),
any(UPayload.class),
any(CallOptions.class)))
.thenReturn(CompletableFuture.completedFuture(UPayload.pack(GetLastMessagesResponse.getDefaultInstance())));

UUriBatch topics = UUriBatch.newBuilder().addUris(TOPIC).build();
var response = twinClient.getLastMessages(topics).toCompletableFuture().join();
assertEquals(0, response.getResponsesCount());
}


@Test
@DisplayName("Test calling getLastMessages() with empty topics")
void testGetLastMessagesEmptyTopics() {
UUriBatch topics = UUriBatch.getDefaultInstance();
var exception = assertThrows(CompletionException.class, () -> {
twinClient.getLastMessages(topics).toCompletableFuture().join();
});
assertInstanceOf(UStatusException.class, exception.getCause());
assertEquals(UCode.INVALID_ARGUMENT, ((UStatusException) exception.getCause()).getCode());
}


@Test
@DisplayName("Test calling getLastMessages() when the RpcClient completes exceptionally")
void testGetLastMessagesException() {
when(rpcClient.invokeMethod(
eq(RpcClientBasedUTwinClient.GETLASTMESSAGE_METHOD),
any(UPayload.class),
any(CallOptions.class)))
.thenReturn(CompletableFuture.failedFuture(new UStatusException(UCode.NOT_FOUND, "Not found")));

UUriBatch topics = UUriBatch.newBuilder().addUris(TOPIC).build();
var exception = assertThrows(CompletionException.class, () -> {
twinClient.getLastMessages(topics).toCompletableFuture().join();
});
assertInstanceOf(UStatusException.class, exception.getCause());
assertEquals(UCode.NOT_FOUND, ((UStatusException) exception.getCause()).getCode());
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ void setUp() {
}

@Test
@SuppressWarnings("unchecked")
void testFactoryMethod() {
var transport = mock(UTransport.class);
when(transport.registerListener(any(UUri.class), any(Optional.class), any(UListener.class)))
Expand Down