Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validate parameters passed to UMessageBuilder #170

Merged
merged 1 commit into from
Jul 25, 2024
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 @@ -24,7 +24,10 @@
import com.google.protobuf.ByteString;

import org.eclipse.uprotocol.communication.UPayload;
import org.eclipse.uprotocol.transport.validate.UAttributesValidator;
import org.eclipse.uprotocol.uri.validator.UriValidator;
import org.eclipse.uprotocol.uuid.factory.UuidFactory;
import org.eclipse.uprotocol.uuid.validate.UuidValidator;

import java.util.Objects;
import java.util.Optional;
Expand Down Expand Up @@ -57,6 +60,11 @@ public class UMessageBuilder {
*/
public static UMessageBuilder publish(UUri source) {
Objects.requireNonNull(source, "source cannot be null.");

// Validate the source
if (!UriValidator.isTopic(source)) {
throw new IllegalArgumentException("source must be a topic.");
}
return new UMessageBuilder(source, UuidFactory.Factories.UPROTOCOL.factory().create(),
UMessageType.UMESSAGE_TYPE_PUBLISH);
}
Expand All @@ -72,6 +80,11 @@ public static UMessageBuilder publish(UUri source) {
public static UMessageBuilder notification(UUri source, UUri sink) {
Objects.requireNonNull(source, "source cannot be null.");
Objects.requireNonNull(sink, "sink cannot be null.");

// Validate the source and sink
if (!UriValidator.isTopic(source) || !UriValidator.isRpcResponse(sink)) {
throw new IllegalArgumentException("source must be a topic and sink must be a response.");
}

return new UMessageBuilder(source, UuidFactory.Factories.UPROTOCOL.factory().create(),
UMessageType.UMESSAGE_TYPE_NOTIFICATION).withSink(sink);
Expand All @@ -93,6 +106,15 @@ public static UMessageBuilder request(UUri source, UUri sink, Integer ttl) {
Objects.requireNonNull(ttl, "ttl cannot be null.");
Objects.requireNonNull(sink, "sink cannot be null.");

// Validate the source and sink
if (!UriValidator.isRpcMethod(sink) || !UriValidator.isRpcResponse(source)) {
throw new IllegalArgumentException("source must be an rpc method and sink must be a request.");
}

// Validate the ttl
if (ttl <= 0) {
throw new IllegalArgumentException("ttl must be greater than 0.");
}
return new UMessageBuilder(source, UuidFactory.Factories.UPROTOCOL.factory().create(),
UMessageType.UMESSAGE_TYPE_REQUEST).withTtl(ttl).withSink(sink);
}
Expand All @@ -112,6 +134,15 @@ public static UMessageBuilder response(UUri source, UUri sink, UUID reqid) {
Objects.requireNonNull(sink, "sink cannot be null for Response.");
Objects.requireNonNull(reqid, "reqid cannot be null.");

// Validate the source and sink
if (!UriValidator.isRpcResponse(sink) || !UriValidator.isRpcMethod(source)) {
throw new IllegalArgumentException("sink must be a response and source must be an rpc method.");
}

if (UuidValidator.Validators.UPROTOCOL.validator().validate(reqid).getCode() != UCode.OK) {
throw new IllegalArgumentException("reqid is not a valid UUID.");
}

return new UMessageBuilder(source, UuidFactory.Factories.UPROTOCOL.factory().create(),
UMessageType.UMESSAGE_TYPE_RESPONSE).withSink(sink).withReqId(reqid);
}
Expand All @@ -126,6 +157,12 @@ public static UMessageBuilder response(UUri source, UUri sink, UUID reqid) {
*/
public static UMessageBuilder response(UAttributes request) {
Objects.requireNonNull(request, "request cannot be null.");

// Validate the request
if (UAttributesValidator.Validators.REQUEST.validator().validate(request).isFailure()) {
throw new IllegalArgumentException("request must contain valid request attributes.");
}

return new UMessageBuilder(
request.getSink(),
UuidFactory.Factories.UPROTOCOL.factory().create(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@ public void testHandleResponseForNonResponseMessage() {
UTransport transport = new TestUTransport() {
@Override
public UMessage buildResponse(UMessage request) {
return UMessageBuilder.publish(createMethodUri()).build();
UUri topic = UUri.newBuilder(getSource()).setResourceId(0x8000).build();
return UMessageBuilder.publish(topic).build();
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.eclipse.uprotocol.v1.UMessage;
import org.eclipse.uprotocol.v1.UMessageType;
import org.eclipse.uprotocol.v1.UUID;
import org.eclipse.uprotocol.uuid.factory.UuidFactory;
import org.eclipse.uprotocol.v1.UAttributes;

import org.junit.jupiter.api.DisplayName;
Expand All @@ -26,12 +27,13 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;

public class UMessageBuilderTest {

@Test
public void testPublish() {
UMessage publish = UMessageBuilder.publish(buildSource()).build();
UMessage publish = UMessageBuilder.publish(buildTopic()).build();
assertNotNull(publish);
assertEquals(UMessageType.UMESSAGE_TYPE_PUBLISH, publish.getAttributes().getType());
assertEquals(UPriority.UPRIORITY_CS1, publish.getAttributes().getPriority());
Expand All @@ -40,7 +42,7 @@ public void testPublish() {
@Test
public void testNotification() {
UUri sink = buildSink();
UMessage notification = UMessageBuilder.notification(buildSource(), sink).build();
UMessage notification = UMessageBuilder.notification(buildTopic(), sink).build();
assertNotNull(notification);
assertEquals(UMessageType.UMESSAGE_TYPE_NOTIFICATION, notification.getAttributes().getType());
assertEquals(UPriority.UPRIORITY_CS1, notification.getAttributes().getPriority());
Expand All @@ -49,7 +51,7 @@ public void testNotification() {

@Test
public void testRequest() {
UUri sink = buildSink();
UUri sink = buildMethod();
Integer ttl = 1000;
UMessage request = UMessageBuilder.request(buildSource(), sink, ttl).build();
assertNotNull(request);
Expand All @@ -62,8 +64,8 @@ public void testRequest() {
@Test
public void testResponse() {
UUri sink = buildSink();
UUID reqId = getUUID();
UMessage response = UMessageBuilder.response(buildSource(), sink, reqId).build();
UUID reqId = UuidFactory.Factories.UPROTOCOL.factory().create();
UMessage response = UMessageBuilder.response(buildMethod(), sink, reqId).build();
assertNotNull(response);
assertEquals(UMessageType.UMESSAGE_TYPE_RESPONSE, response.getAttributes().getType());
assertEquals(UPriority.UPRIORITY_CS4, response.getAttributes().getPriority());
Expand All @@ -74,7 +76,7 @@ public void testResponse() {
@Test
@DisplayName("Test response with existing request")
public void testResponseWithExistingRequest() {
UMessage request = UMessageBuilder.request(buildSource(), buildSink(), 1000).build();
UMessage request = UMessageBuilder.request(buildSource(), buildMethod(), 1000).build();
UMessage response = UMessageBuilder.response(request.getAttributes()).build();
assertNotNull(response);
assertEquals(UMessageType.UMESSAGE_TYPE_RESPONSE, response.getAttributes().getType());
Expand All @@ -87,7 +89,7 @@ public void testResponseWithExistingRequest() {

@Test
public void testBuild() {
UMessageBuilder builder = UMessageBuilder.publish(buildSource())
UMessageBuilder builder = UMessageBuilder.publish(buildTopic())
.withToken("test_token")
.withPermissionLevel(2)
.withCommStatus(UCode.CANCELLED)
Expand All @@ -109,7 +111,7 @@ public void testBuild() {
@Test
@DisplayName("Test building UMessage with empty payload")
public void testBuildWithAnyPayload() {
UMessage message = UMessageBuilder.publish(buildSource())
UMessage message = UMessageBuilder.publish(buildTopic())
.build();
assertNotNull(message);
assertFalse(message.hasPayload());
Expand All @@ -120,8 +122,8 @@ public void testBuildWithAnyPayload() {
@DisplayName("Test building response message with the wrong priority value of UPRIORITY_CS3")
public void testBuildResponseWithWrongPriority() {
UUri sink = buildSink();
UUID reqId = getUUID();
UMessage response = UMessageBuilder.response(buildSource(), sink, reqId)
UUID reqId = UuidFactory.Factories.UPROTOCOL.factory().create();
UMessage response = UMessageBuilder.response(buildMethod(), sink, reqId)
.withPriority(UPriority.UPRIORITY_CS3)
.build();
assertNotNull(response);
Expand All @@ -134,7 +136,7 @@ public void testBuildResponseWithWrongPriority() {
@Test
@DisplayName("Test building request message with the wrong priority value of UPRIORITY_CS3")
public void testBuildRequestWithWrongPriority() {
UUri sink = buildSink();
UUri sink = buildMethod();
Integer ttl = 1000;
UMessage request = UMessageBuilder.request(buildSource(), sink, ttl)
.withPriority(UPriority.UPRIORITY_CS3)
Expand All @@ -150,7 +152,7 @@ public void testBuildRequestWithWrongPriority() {
@DisplayName("Test building notification message with the wrong priority value of UPRIORITY_CS0")
public void testBuildNotificationWithWrongPriority() {
UUri sink = buildSink();
UMessage notification = UMessageBuilder.notification(buildSource(), sink)
UMessage notification = UMessageBuilder.notification(buildTopic(), sink)
.withPriority(UPriority.UPRIORITY_CS0)
.build();
assertNotNull(notification);
Expand All @@ -162,7 +164,7 @@ public void testBuildNotificationWithWrongPriority() {
@Test
@DisplayName("Test building publish message with the wrong priority value of UPRIORITY_CS0")
public void testBuildPublishWithWrongPriority() {
UMessage publish = UMessageBuilder.publish(buildSource())
UMessage publish = UMessageBuilder.publish(buildTopic())
.withPriority(UPriority.UPRIORITY_CS0)
.build();
assertNotNull(publish);
Expand All @@ -173,7 +175,7 @@ public void testBuildPublishWithWrongPriority() {
@Test
@DisplayName("Test building publish message with the priority value of UPRIORITY_CS4")
public void testBuildPublishWithPriority() {
UMessage publish = UMessageBuilder.publish(buildSource())
UMessage publish = UMessageBuilder.publish(buildTopic())
.withPriority(UPriority.UPRIORITY_CS4)
.build();
assertNotNull(publish);
Expand All @@ -189,13 +191,136 @@ private UUri buildSink() {
.setResourceId(0).build();
}

private UUID getUUID() {
java.util.UUID uuid_java = java.util.UUID.randomUUID();
return UUID.newBuilder().setMsb(uuid_java.getMostSignificantBits()).setLsb(uuid_java.getLeastSignificantBits())
.build();

@Test
@DisplayName("Test publish when source is not a valid topic")
public void testPublishWithInvalidSource() {
assertThrows(IllegalArgumentException.class,
() -> UMessageBuilder.publish(buildSource()).build());
}


@Test
@DisplayName("Test notification when source is not a valid topic")
public void testNotificationWithInvalidSource() {
assertThrows(IllegalArgumentException.class,
() -> UMessageBuilder.notification(buildSource(), buildSink()).build());
}


@Test
@DisplayName("Test notification when sink is not a valid UUri")
public void testNotificationWithInvalidSink() {
assertThrows(IllegalArgumentException.class,
() -> UMessageBuilder.notification(buildTopic(), buildTopic()).build());
}


@Test
@DisplayName("Test request when source is not valid")
public void testRequestWithInvalidSource() {
assertThrows(IllegalArgumentException.class,
() -> UMessageBuilder.request(buildMethod(), buildMethod(), 1000).build());
}

@Test
@DisplayName("Test request when sink is not valid")
public void testRequestWithInvalidSink() {
assertThrows(IllegalArgumentException.class,
() -> UMessageBuilder.request(buildSource(), buildSource(), 1000).build());
}

@Test
@DisplayName("Test request when source and sink are not valid")
public void testRequestWithInvalidSourceAndSink() {
assertThrows(IllegalArgumentException.class,
() -> UMessageBuilder.request(buildMethod(), buildSource(), 1000).build());
}


@Test
@DisplayName("Test request when the ttl is null")
public void testRequestWithNullTtl() {
assertThrows(NullPointerException.class,
() -> UMessageBuilder.request(buildSource(), buildMethod(), null).build());
}


@Test
@DisplayName("Test request when ttl is negative")
public void testRequestWithNegativeTtl() {
assertThrows(IllegalArgumentException.class,
() -> UMessageBuilder.request(buildSource(), buildMethod(), -1).build());
}


@Test
@DisplayName("Test response when source is not valid")
public void testResponseWithInvalidSource() {
assertThrows(IllegalArgumentException.class,
() -> UMessageBuilder.response(buildSink(), buildSink(),
UuidFactory.Factories.UPROTOCOL.factory().create()).build());
}


@Test
@DisplayName("Test response when sink is not valid")
public void testResponseWithInvalidSink() {
assertThrows(IllegalArgumentException.class,
() -> UMessageBuilder.response(buildMethod(), buildMethod(),
UuidFactory.Factories.UPROTOCOL.factory().create()).build());
}

@Test
@DisplayName("Test response when source and sink are not valid")
public void testResponseWithInvalidSourceAndSink() {
assertThrows(IllegalArgumentException.class,
() -> UMessageBuilder.response(buildSource(), buildSource(),
UuidFactory.Factories.UPROTOCOL.factory().create()).build());
}


@Test
@DisplayName("Test response when reqId is null")
public void testResponseWithNullReqId() {
assertThrows(NullPointerException.class,
() -> UMessageBuilder.response(buildMethod(), buildSink(), null).build());
}


@Test
@DisplayName("Test response when we pass an invalid reqid")
public void testResponseWithInvalidReqId() {
assertThrows(IllegalArgumentException.class,
() -> UMessageBuilder.response(buildMethod(), buildSink(), UUID.getDefaultInstance()).build());
}


@Test
@DisplayName("Test notification when source is not a valid topic and and sink is not valid")
public void testNotificationWithInvalidSourceAndSink() {
assertThrows(IllegalArgumentException.class,
() -> UMessageBuilder.notification(buildSink(), buildSource()).build());
}


@Test
@DisplayName("Test response builder when we pass UAttributes that is not a valid request type")
public void testResponseBuilderWithInvalidRequestType() {
assertThrows(IllegalArgumentException.class,
() -> UMessageBuilder.response(UAttributes.getDefaultInstance()).build());
}


private UUri buildSource() {
return UUri.newBuilder().setUeId(2).setUeVersionMajor(1).setResourceId(0).build();
}

private UUri buildTopic() {
return UUri.newBuilder().setUeId(2).setUeVersionMajor(1).setResourceId(0x8000).build();
}

private UUri buildMethod() {
return UUri.newBuilder().setUeId(2).setUeVersionMajor(1).setResourceId(1).build();
}
}
Loading
Loading