Skip to content

Commit

Permalink
Fix uTransport doc & test coverage & add UEntityBuilder
Browse files Browse the repository at this point in the history
  • Loading branch information
czfdcn committed Jan 26, 2024
1 parent 152e445 commit ae5d2fa
Show file tree
Hide file tree
Showing 6 changed files with 372 additions and 28 deletions.
4 changes: 3 additions & 1 deletion src/main/java/org/eclipse/uprotocol/transport/UListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ public interface UListener {
* @return Returns an Ack every time a message is received and processed.
*/
default void onReceive(UMessage message) {
onReceive(message.getSource(), message.getPayload(), message.getAttributes());
if (message != null) {
onReceive(message.getSource(), message.getPayload(), message.getAttributes());
}
}

}
55 changes: 28 additions & 27 deletions src/main/java/org/eclipse/uprotocol/transport/UTransport.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,54 +27,55 @@
import org.eclipse.uprotocol.v1.*;

/**
* UTransport is the uP-L1 interface that provides a common API for uE developers to send and receive messages.
* UTransport is the uP-L1 interface that provides a common API for uE developers to send and receive messages.
* UTransport implementations contain the details for connecting to the underlying transport technology and
* sending UMessage using the configured technology. For more information please refer to
* https://github.com/eclipse-uprotocol/uprotocol-spec/blob/main/up-l1/README.adoc.
* https://github.com/eclipse-uprotocol/up-spec/blob/main/up-l1/README.adoc.
*/

public interface UTransport {

/**
* Transmit UPayload to the topic using the attributes defined in UTransportAttributes.
* @param topic Resolved UUri topic to send the payload to.
* @param payload Actual payload.
* @param attributes Additional transport attributes.
* @return Returns OKSTATUS if the payload has been successfully sent (ACK'ed), otherwise it
* returns FAILSTATUS with the appropriate failure.
* Send a message (in parts) over the transport.
* @param source The source address for the message, (ex. publish topic, the return address
* for rpc-request, or the rpc method for rpc response
* @param payload Actual message payload.
* @param attributes uProtocol header attributes.
* @return Returns {@link UStatus} with {@link UCode} set to the status code (successful or failure).
*/
UStatus send(UUri topic, UPayload payload, UAttributes attributes);
UStatus send(UUri source, UPayload payload, UAttributes attributes);


/**
* Transmit UPayload to the topic using the attributes defined in UTransportAttributes.
* @param topic Resolved UUri topic to send the payload to.
* @param payload Actual payload.
* @param attributes Additional transport attributes.
* @return Returns OKSTATUS if the payload has been successfully sent (ACK'ed), otherwise it
* returns FAILSTATUS with the appropriate failure.
* Send a message over the transport.
* @param message the {@link UMessage} to be sent.
* @return Returns {@link UStatus} with {@link UCode} set to the status code (successful or failure).
*/
default UStatus send(UMessage message) {
if (message == null) {
return UStatus.newBuilder().setCode(UCode.INVALID_ARGUMENT).build();
}
return send(message.getSource(), message.getPayload(), message.getAttributes());
}

/**
* Register listener to be called when UPayload is received for the specific topic.
* @param topic Resolved UUri for where the message arrived via the underlying transport technology.
* @param listener The method to execute to process the date for the topic.
* @return Returns OKSTATUS if the listener is unregistered correctly, otherwise it returns FAILSTATUS
* with the appropriate failure.
* Register {@code UListener} for {@code UUri} topic to be called when a message is received.
* @param topic {@code UUri} to listen for messages from.
* @param listener The {@code UListener} that will be execute when the message is
* received on the given {@code UUri}.
* @return Returns {@link UStatus} with {@link UCode.OK} if the listener is registered
* correctly, otherwise it returns with the appropriate failure.
*/
UStatus registerListener(UUri topic, UListener listener);

/**
* Unregister a listener for a given topic. Messages arriving on this topic will no longer be processed
* by this listener.
* @param topic Resolved UUri for where the listener was registered to receive messages from.
* @param listener The method to execute to process the date for the topic.
* @return Returns OKSTATUS if the listener is unregistered correctly, otherwise it returns FAILSTATUS
* with the appropriate failure.
*
* Unregister {@code UListener} for {@code UUri} topic. Messages arriving on this topic will
* no longer be processed by this listener.
* @param topic {@code UUri} to the listener was registered for.
* @param listener The {@code UListener} that will no longer want to be registered to receive
* messages.
* @return Returns {@link UStatus} with {@link UCode.OK} if the listener is unregistered
* correctly, otherwise it returns with the appropriate failure.
*/
UStatus unregisterListener(UUri topic, UListener listener);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2024 General Motors GTO LLC
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
* SPDX-FileType: SOURCE
* SPDX-FileCopyrightText: 2024 General Motors GTO LLC
* SPDX-License-Identifier: Apache-2.0
*/

package org.eclipse.uprotocol.uri.builder;

import org.eclipse.uprotocol.UprotocolOptions;
import org.eclipse.uprotocol.v1.UEntity;

import com.google.protobuf.DescriptorProtos.ServiceOptions;
import com.google.protobuf.Descriptors.ServiceDescriptor;

/**
* Builder interface for UEntity to help to build UEntity from common use cases
*/
public interface UEntityBuilder {
/**
* Builds a UEntity for an protobuf generated code Service Descriptor.
* @param descriptor The protobuf generated code Service Descriptor.
* @return Returns a UEntity for an protobuf generated code Service Descriptor.
*/
static UEntity fromProto(ServiceDescriptor descriptor) {
if (descriptor == null) {
return UEntity.getDefaultInstance();
}

ServiceOptions options = descriptor.getOptions();

return UEntity.newBuilder()
.setName(options.<String>getExtension(UprotocolOptions.name))
.setId(options.<Integer>getExtension(UprotocolOptions.id))
.setVersionMajor(options.<Integer>getExtension(UprotocolOptions.versionMajor))
.build();
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
/*
* Copyright (c) 2024 General Motors GTO LLC
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
* SPDX-FileType: SOURCE
* SPDX-FileCopyrightText: 2024 General Motors GTO LLC
* SPDX-License-Identifier: Apache-2.0
*/
package org.eclipse.uprotocol.uri.builder;

import java.util.Objects;
Expand Down
168 changes: 168 additions & 0 deletions src/test/java/org/eclipse/uprotocol/transport/UTransportTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
/*
* Copyright (c) 2024 General Motors GTO LLC
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
* SPDX-FileType: SOURCE
* SPDX-FileCopyrightText: 2024 General Motors GTO LLC
* SPDX-License-Identifier: Apache-2.0
*/

package org.eclipse.uprotocol.transport;

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.eclipse.uprotocol.v1.UAttributes;
import org.eclipse.uprotocol.v1.UCode;
import org.eclipse.uprotocol.v1.UMessage;
import org.eclipse.uprotocol.v1.UPayload;
import org.eclipse.uprotocol.v1.UStatus;
import org.eclipse.uprotocol.v1.UUri;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

/**
* Test implementing and using uTransport API
*/
public class UTransportTest {
@Test
@DisplayName("Test happy path send message parts")
public void test_happy_send_message_parts() {
UTransport transport = new HappyUTransport();

UStatus status = transport.send(
UUri.getDefaultInstance(),
UPayload.getDefaultInstance(),
UAttributes.getDefaultInstance());

assertEquals(status.getCode(), UCode.OK);
}

@Test
@DisplayName("Test happy path send message")
public void test_happy_send_message() {
UTransport transport = new HappyUTransport();
UStatus status = transport.send(UMessage.getDefaultInstance());
assertEquals(status.getCode(), UCode.OK);
}

@Test
@DisplayName("Test happy path register listener")
public void test_happy_register_listener() {
UTransport transport = new HappyUTransport();
UStatus status = transport.registerListener(UUri.getDefaultInstance(), new MyListener());
assertEquals(status.getCode(), UCode.OK);
}

@Test
@DisplayName("Test happy path unregister listener")
public void test_happy_register_unlistener() {
UTransport transport = new HappyUTransport();
UStatus status = transport.unregisterListener(UUri.getDefaultInstance(), new MyListener());
assertEquals(status.getCode(), UCode.OK);
}

@Test
@DisplayName("Test sending null message")
public void test_sending_null_message() {
UTransport transport = new HappyUTransport();
UStatus status = transport.send(null);
assertEquals(status.getCode(), UCode.INVALID_ARGUMENT);
}


@Test
@DisplayName("Test unhappy path send message parts")
public void test_unhappy_send_message_parts() {
UTransport transport = new SadUTransport();

UStatus status = transport.send(
UUri.getDefaultInstance(),
UPayload.getDefaultInstance(),
UAttributes.getDefaultInstance());

assertEquals(status.getCode(), UCode.INTERNAL);
}

@Test
@DisplayName("Test unhappy path send message")
public void test_unhappy_send_message() {
UTransport transport = new SadUTransport();
UStatus status = transport.send(UMessage.getDefaultInstance());
assertEquals(status.getCode(), UCode.INTERNAL);
}

@Test
@DisplayName("Test unhappy path register listener")
public void test_unhappy_register_listener() {
UTransport transport = new SadUTransport();
UStatus status = transport.registerListener(UUri.getDefaultInstance(), new MyListener());
assertEquals(status.getCode(), UCode.INTERNAL);
}

@Test
@DisplayName("Test unhappy path unregister listener")
public void test_unhappy_register_unlistener() {
UTransport transport = new SadUTransport();
UStatus status = transport.unregisterListener(UUri.getDefaultInstance(), new MyListener());
assertEquals(status.getCode(), UCode.INTERNAL);
}

final class MyListener implements UListener {
@Override
public void onReceive(UUri topic, UPayload payload, UAttributes attributes) {}
}

private class HappyUTransport implements UTransport {
@Override
public UStatus send(UUri source, UPayload payload, UAttributes attributes) {
return UStatus.newBuilder().setCode(UCode.OK).build();
}


@Override
public UStatus registerListener(UUri topic, UListener listener) {
listener.onReceive(UMessage.getDefaultInstance());
return UStatus.newBuilder().setCode(UCode.OK).build();
}

@Override
public UStatus unregisterListener(UUri topic, UListener listener) {
return UStatus.newBuilder().setCode(UCode.OK).build();
}
}

private class SadUTransport implements UTransport {
@Override
public UStatus send(UUri source, UPayload payload, UAttributes attributes) {
return UStatus.newBuilder().setCode(UCode.INTERNAL).build();
}

@Override
public UStatus registerListener(UUri topic, UListener listener) {
listener.onReceive(null);
return UStatus.newBuilder().setCode(UCode.INTERNAL).build();
}

@Override
public UStatus unregisterListener(UUri topic, UListener listener) {
return UStatus.newBuilder().setCode(UCode.INTERNAL).build();
}

}
}
Loading

0 comments on commit ae5d2fa

Please sign in to comment.