diff --git a/.github/workflows/tck-test.yml b/.github/workflows/tck-test.yml index 06fcec10..41264e61 100644 --- a/.github/workflows/tck-test.yml +++ b/.github/workflows/tck-test.yml @@ -23,12 +23,16 @@ jobs: with: command: build args: --manifest-path test_agent/rust/Cargo.toml - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v3 with: - java-version: '11' + java-version: '17' distribution: 'temurin' cache: maven + - name: Install dependencies + run: | + cd scripts + python build_up_java_latest.py - name: Build up_client_socket_java with Maven working-directory: up_client_socket/java run: | diff --git a/.gitignore b/.gitignore index 2bdd34fe..9cffb876 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,7 @@ MANIFEST **/jar_files/** *.jar **/.DS_Store -**/target \ No newline at end of file +**/target +**/summary.json +**/up-java/ +**/up-python/ \ No newline at end of file diff --git a/screenshots/RegisterListenerv2.drawio.svg b/screenshots/RegisterListenerv2.drawio.svg index 0d07c840..d00c8222 100644 --- a/screenshots/RegisterListenerv2.drawio.svg +++ b/screenshots/RegisterListenerv2.drawio.svg @@ -1,4 +1,4 @@ -
Test Manager
Test Manager
CommandSender
CommandSender
Test Agent
Test Agent
up-client-xx
up-client-xx
CommandHandler
CommandHandler
                              Socket Command Communication
Socket Command Comm...
Send/RegisterListener/UnregisterListener
Send/RegisterListener/UnregisterListener
ResponseHandler
ResponseHandler
uStatus/onReceive(event)
uStatus/onReceive(event)
Test Scripting
Test Scripting
Text is not SVG - cannot display
\ No newline at end of file +
Test Manager
Test Manager
CommandSender
CommandSender
Test Agent
Test Agent
up-client-xx
up-client-xx
CommandHandler
CommandHandler
                              Socket Command Communication
Socket Command Comm...
Send/RegisterListener/UnregisterListener
Send/RegisterListener/UnregisterListener
ResponseHandler
ResponseHandler
uStatus/onReceive(event)
uStatus/onReceive(event)
Test Scripting
Test Scripting
Text is not SVG - cannot display
\ No newline at end of file diff --git a/screenshots/TestManagerTestAgentv2.drawio.svg b/screenshots/TestManagerTestAgentv2.drawio.svg index 4bc91ddd..e5352901 100644 --- a/screenshots/TestManagerTestAgentv2.drawio.svg +++ b/screenshots/TestManagerTestAgentv2.drawio.svg @@ -1,4 +1,4 @@ -
Test Manager
Test Manager
Dispatcher
Dispatcher
CommandSender
CommandSender
Test Agents (Java, Python, C++, etc.)
Test Agents (Java, Python, C++, etc.)
XTransport
XTransport
CommandHandler
CommandHandler
                              uTransport Communication


                              Socket Command Communication
uTransport Communic...
Dispatcher is specific to Socket uTransport, can be replaced with any transport (Zenoh, SOME/IP)
Dispatcher is specific to Socket uTransport,...
Text is not SVG - cannot display
\ No newline at end of file +
Test Manager
Test Manager
Dispatcher
Dispatcher
CommandSender
CommandSender
Test Agents (Java, Python, C++, etc.)
Test Agents (Java, Python, C++, etc.)
XTransport
XTransport
CommandHandler
CommandHandler
                              uTransport Communication


                              Socket Command Communication
uTransport Communic...
Dispatcher is specific to Socket uTransport, can be replaced with any transport (Zenoh, SOME/IP)
Dispatcher is specific to Socket uTransport,...
Text is not SVG - cannot display
\ No newline at end of file diff --git a/scripts/build_up_java_latest.py b/scripts/build_up_java_latest.py new file mode 100644 index 00000000..274c5dcc --- /dev/null +++ b/scripts/build_up_java_latest.py @@ -0,0 +1,56 @@ +""" +SPDX-FileCopyrightText: Copyright (c) 2024 Contributors to the Eclipse Foundation +See the NOTICE file(s) distributed with this work for additional +information regarding copyright ownership. +Licensed 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-License-Identifier: Apache-2.0 +""" + +import os +import subprocess +import sys + + +def run_command(command): + """Run a shell command and handle the output.""" + try: + result = subprocess.run( + command, + check=True, + shell=True, + text=True, # , stdout=subprocess.PIPE, stderr=subprocess.PIPE + ) + print(result.stdout) + except subprocess.CalledProcessError as e: + print("An error occurred while executing:", command) + print(e.stderr) + sys.exit(1) + + +def main(): + # Define the repository and desired branch or commit + repo_url = "https://github.com/eclipse-uprotocol/up-java.git" + + # Directory to be removed and cloned + repo_dir = "up-java" + + # Clone the repository + run_command(f"git clone {repo_url}") + + # Change directory into the repository + os.chdir(repo_dir) + + run_command("mvn clean install") + + +if __name__ == "__main__": + main() diff --git a/test_agent/cpp/include/Constants.h b/test_agent/cpp/include/Constants.h index e97d4841..439e1bc5 100644 --- a/test_agent/cpp/include/Constants.h +++ b/test_agent/cpp/include/Constants.h @@ -17,7 +17,7 @@ namespace Constants { constexpr static const char* TEST_MANAGER_IP = "127.0.0.5"; -constexpr static const int TEST_MANAGER_PORT = 12345; +constexpr static const int TEST_MANAGER_PORT = 33333; constexpr static const int BYTES_MSG_LENGTH = 32767; constexpr static const char* SEND_COMMAND = "send"; constexpr static const char* REGISTER_LISTENER_COMMAND = "registerlistener"; diff --git a/test_agent/java/src/main/java/org/eclipse/uprotocol/Constants/Constant.java b/test_agent/java/src/main/java/org/eclipse/uprotocol/Constants/Constant.java index 0dd6d0c0..87510237 100644 --- a/test_agent/java/src/main/java/org/eclipse/uprotocol/Constants/Constant.java +++ b/test_agent/java/src/main/java/org/eclipse/uprotocol/Constants/Constant.java @@ -26,7 +26,7 @@ public class Constant { public static final String TEST_MANAGER_IP = "127.0.0.5"; - public static final int TEST_MANAGER_PORT = 12345; + public static final int TEST_MANAGER_PORT = 33333; public static final int BYTES_MSG_LENGTH = 32767; } diff --git a/test_agent/java/src/main/java/org/eclipse/uprotocol/TestAgent.java b/test_agent/java/src/main/java/org/eclipse/uprotocol/TestAgent.java index 8d92f1c9..23f93828 100644 --- a/test_agent/java/src/main/java/org/eclipse/uprotocol/TestAgent.java +++ b/test_agent/java/src/main/java/org/eclipse/uprotocol/TestAgent.java @@ -23,18 +23,20 @@ import com.google.gson.Gson; import com.google.protobuf.Any; +import com.google.protobuf.ByteString; import com.google.protobuf.Message; import com.google.protobuf.StringValue; +import org.eclipse.uprotocol.communication.CallOptions; +import org.eclipse.uprotocol.communication.UPayload; import org.eclipse.uprotocol.Constants.ActionCommands; import org.eclipse.uprotocol.Constants.Constant; import org.eclipse.uprotocol.transport.UListener; -import org.eclipse.uprotocol.transport.builder.UAttributesBuilder; +import org.eclipse.uprotocol.transport.builder.UMessageBuilder; import org.eclipse.uprotocol.transport.validate.UAttributesValidator; -import org.eclipse.uprotocol.uri.serializer.LongUriSerializer; +import org.eclipse.uprotocol.uri.serializer.UriSerializer; import org.eclipse.uprotocol.uri.validator.UriValidator; import org.eclipse.uprotocol.validation.ValidationResult; -import org.eclipse.uprotocol.uuid.serializer.LongUuidSerializer; -import org.eclipse.uprotocol.uri.serializer.MicroUriSerializer; +import org.eclipse.uprotocol.uuid.serializer.UuidSerializer; import org.eclipse.uprotocol.uuid.factory.UuidFactory; import org.eclipse.uprotocol.uuid.factory.UuidUtils; import org.eclipse.uprotocol.uuid.validate.UuidValidator; @@ -75,8 +77,6 @@ public class TestAgent { actionHandlers.put(ActionCommands.SERIALIZE_UUID, TestAgent::handleLongSerializeUuidCommand); actionHandlers.put(ActionCommands.DESERIALIZE_UUID, TestAgent::handleLongDeserializeUuidCommand); actionHandlers.put(ActionCommands.VALIDATE_UATTRIBUTES, TestAgent::handleUAttributesValidateCommand); - actionHandlers.put(ActionCommands.MICRO_SERIALIZE_URI, TestAgent::handleMicroSerializeUuriCommand); - actionHandlers.put(ActionCommands.MICRO_DESERIALIZE_URI, TestAgent::handleMicroDeserializeUuriCommand); } static { @@ -139,7 +139,7 @@ private static void writeDataToTMSocket(JSONObject responseDict, String action) } } - private static UStatus handleSendCommand(Map jsonData) { + private static CompletionStage handleSendCommand(Map jsonData) { UMessage uMessage = (UMessage) ProtoConverter.dictToProto((Map) jsonData.get("data"), UMessage.newBuilder()); UAttributes uAttributesWithId = uMessage.getAttributes().toBuilder() @@ -148,12 +148,12 @@ private static UStatus handleSendCommand(Map jsonData) { return transport.send(uMessageWithId); } - private static UStatus handleRegisterListenerCommand(Map jsonData) { + private static CompletionStage handleRegisterListenerCommand(Map jsonData) { UUri uri = (UUri) ProtoConverter.dictToProto((Map) jsonData.get("data"), UUri.newBuilder()); return transport.registerListener(uri, listener); } - private static UStatus handleUnregisterListenerCommand(Map jsonData) { + private static CompletionStage handleUnregisterListenerCommand(Map jsonData) { UUri uri = (UUri) ProtoConverter.dictToProto((Map) jsonData.get("data"), UUri.newBuilder()); return transport.unregisterListener(uri, listener); } @@ -162,10 +162,11 @@ private static Object handleInvokeMethodCommand(Map jsonData) { Map data = (Map) jsonData.get("data"); // Convert data and payload to protocol buffers UUri uri = (UUri) ProtoConverter.dictToProto(data, UUri.newBuilder()); - UPayload payload = (UPayload) ProtoConverter.dictToProto((Map) data.get("payload"), - UPayload.newBuilder()); - CompletionStage responseFuture = transport.invokeMethod(uri, payload, - CallOptions.newBuilder().setTtl(10000).build()); + ByteString payloadBytes = (ByteString) data.get("data"); + UPayloadFormat format = (UPayloadFormat) data.get("format"); + UPayload payload = new UPayload(payloadBytes, format); + CompletionStage responseFuture = transport.invokeMethod(uri, payload, + CallOptions.DEFAULT); responseFuture.whenComplete((responseMessage, exception) -> { sendToTestManager(responseMessage, ActionCommands.INVOKE_METHOD_COMMAND, (String) jsonData.get("test_id")); }); @@ -175,14 +176,14 @@ private static Object handleInvokeMethodCommand(Map jsonData) { private static Object handleLongSerializeUriCommand(Map jsonData) { Map data = (Map) jsonData.get("data"); UUri uri = (UUri) ProtoConverter.dictToProto(data, UUri.newBuilder()); - String serializedUuri = LongUriSerializer.instance().serialize(uri); + String serializedUuri = UriSerializer.serialize(uri); String testID = (String) jsonData.get("test_id"); sendToTestManager(serializedUuri, ActionCommands.SERIALIZE_URI, testID); return null; } private static Object handleLongDeserializeUriCommand(Map jsonData) { - UUri uri = LongUriSerializer.instance().deserialize(jsonData.get("data").toString()); + UUri uri = UriSerializer.deserialize(jsonData.get("data").toString()); String testID = (String) jsonData.get("test_id"); sendToTestManager(uri, ActionCommands.DESERIALIZE_URI, testID); return null; @@ -195,42 +196,40 @@ private static Object handleValidateUriCommand(Map jsonData) { UUri uri = (UUri) ProtoConverter.dictToProto(uriValue, UUri.newBuilder()); - Function validatorFunc = null; + Function validatorFunc = null; Function validatorFuncBool = null; switch (valType) { - case "uri": - validatorFunc = UriValidator::validate; - break; - case "rpc_response": - validatorFunc = UriValidator::validateRpcResponse; + case "is_empty": + validatorFunc = UriValidator::isEmpty; break; - case "rpc_method": - validatorFunc = UriValidator::validateRpcMethod; + case "is_rpc_method": + validatorFunc = UriValidator::isRpcMethod; break; - case "is_empty": - validatorFuncBool = UriValidator::isEmpty; + case "is_rpc_response": + validatorFunc = UriValidator::isRpcResponse; break; - case "is_resolved": - validatorFuncBool = UriValidator::isResolved; + case "is_notification_destination": + validatorFunc = UriValidator::isRpcResponse; break; - case "is_micro_form": - validatorFuncBool = UriValidator::isMicroForm; + case "is_default_resource_id": + validatorFunc = UriValidator::isDefaultResourceId; break; - case "is_long_form": - validatorFuncBool = UriValidator::isLongForm; + case "is_topic": + validatorFunc = UriValidator::isTopic; break; } String testID = (String) jsonData.get("test_id"); if (validatorFunc != null) { - ValidationResult status = validatorFunc.apply(uri); - String result = status.isSuccess() ? "True" : "False"; - String message = status.getMessage(); - sendToTestManager(Map.of("result", result, "message", message), ActionCommands.VALIDATE_URI, testID); - } else if (validatorFuncBool != null) { - Boolean status = validatorFuncBool.apply(uri); - String result = status ? "True" : "False"; + Boolean status = validatorFunc.apply(uri); + String result = status.toString().equals("true") ? "True" : "False"; + sendToTestManager(Map.of("result", result, "message", ""), ActionCommands.VALIDATE_URI, testID); + } else if (valType.equals("matches")) { + String uriToMatch = (String) data.get("uuri_2"); + UUri convertedMatch = UriSerializer.deserialize(uriToMatch); + Boolean status = UriValidator.matches(uri, convertedMatch); + String result = status.toString().equals("true") ? "True" : "False"; sendToTestManager(Map.of("result", result, "message", ""), ActionCommands.VALIDATE_URI, testID); } @@ -246,7 +245,7 @@ public static Object handleUAttributesValidateCommand(Map jsonDa if (data.get("attributes") != null) { attributes = (UAttributes) ProtoConverter.dictToProto((Map) data.get("attributes"), UAttributes.newBuilder()); - if ("default".equals(attributes.getSink().getAuthority().getName())) { + if ("default".equals(attributes.getSink().getAuthorityName())) { attributes = attributes.toBuilder().setSink(UUri.getDefaultInstance()).build(); } } else { @@ -458,58 +457,29 @@ public static Object handleValidateUuidCommand(Map jsonData) { private static Object handleLongSerializeUuidCommand(Map jsonData) { Map data = (Map) jsonData.get("data"); UUID uuid = (UUID) ProtoConverter.dictToProto(data, UUID.newBuilder()); - String serializedUUid = LongUuidSerializer.instance().serialize(uuid); + String serializedUUid = UuidSerializer.serialize(uuid); String testID = (String) jsonData.get("test_id"); sendToTestManager(serializedUUid, ActionCommands.SERIALIZE_UUID, testID); return null; } private static Object handleLongDeserializeUuidCommand(Map jsonData) { - UUID uuid = LongUuidSerializer.instance().deserialize(jsonData.get("data").toString()); + UUID uuid = UuidSerializer.deserialize(jsonData.get("data").toString()); String testID = (String) jsonData.get("test_id"); sendToTestManager(uuid, ActionCommands.DESERIALIZE_UUID, testID); return null; } - private static Object handleMicroSerializeUuriCommand(Map jsonData) { - Map data = (Map) jsonData.get("data"); - UUri uri = (UUri) ProtoConverter.dictToProto(data, UUri.newBuilder()); - byte[] serializedUuri = MicroUriSerializer.instance().serialize(uri); - String serializedUuriAsStr = ""; - try { - serializedUuriAsStr = new String(serializedUuri, "ISO-8859-1"); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - return null; - } - String testID = (String) jsonData.get("test_id"); - sendToTestManager(serializedUuriAsStr, ActionCommands.MICRO_SERIALIZE_URI, testID); - return null; - } - - private static Object handleMicroDeserializeUuriCommand(Map jsonData) { - String microSerializedUuriAsStr = (String) jsonData.get("data"); - byte[] microSerializedUuri = microSerializedUuriAsStr.getBytes(StandardCharsets.ISO_8859_1); - UUri uri = MicroUriSerializer.instance().deserialize(microSerializedUuri); - - String testID = (String) jsonData.get("test_id"); - sendToTestManager(uri, ActionCommands.MICRO_DESERIALIZE_URI, testID); - return null; - } - private static void handleOnReceive(UMessage uMessage) { logger.info("Java on_receive called: " + uMessage); if (uMessage.getAttributes().getType().equals(UMessageType.UMESSAGE_TYPE_REQUEST)) { UAttributes reqAttributes = uMessage.getAttributes(); - UAttributes uAttributes = UAttributesBuilder.response(reqAttributes.getSink(), reqAttributes.getSource(), - UPriority.UPRIORITY_CS4, reqAttributes.getId()).build(); + StringValue stringValue = StringValue.newBuilder().setValue("SuccessRPCResponse").build(); Any anyObj = Any.pack(stringValue); + UPayload uPayload = new UPayload(anyObj.toByteString(), UPayloadFormat.UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY); + UMessage resMsg = UMessageBuilder.response(reqAttributes).build(uPayload); - UPayload uPayload = UPayload.newBuilder().setValue(anyObj.toByteString()) - .setFormat(UPayloadFormat.UPAYLOAD_FORMAT_PROTOBUF_WRAPPED_IN_ANY).build(); - - UMessage resMsg = UMessage.newBuilder().setAttributes(uAttributes).setPayload(uPayload).build(); transport.send(resMsg); } else { sendToTestManager(uMessage, ActionCommands.RESPONSE_ON_RECEIVE); diff --git a/test_agent/python/constants/constants.py b/test_agent/python/constants/constants.py index 1dd3fc27..ebfa5399 100644 --- a/test_agent/python/constants/constants.py +++ b/test_agent/python/constants/constants.py @@ -24,5 +24,5 @@ # # ------------------------------------------------------------------------- -TEST_MANAGER_ADDR = ("127.0.0.5", 12345) +TEST_MANAGER_ADDR = ("127.0.0.5", 33333) BYTES_MSG_LENGTH: int = 32767 diff --git a/test_agent/python/testagent.py b/test_agent/python/testagent.py index 17c8ccfe..17177678 100644 --- a/test_agent/python/testagent.py +++ b/test_agent/python/testagent.py @@ -31,30 +31,26 @@ from google.protobuf.descriptor import FieldDescriptor from google.protobuf.message import Message from google.protobuf.wrappers_pb2 import StringValue -from uprotocol.proto.uattributes_pb2 import ( - CallOptions, - UAttributes, - UMessageType, - UPriority, -) -from uprotocol.proto.umessage_pb2 import UMessage -from uprotocol.proto.upayload_pb2 import UPayload, UPayloadFormat -from uprotocol.proto.uri_pb2 import UUri -from uprotocol.proto.ustatus_pb2 import UCode, UStatus -from uprotocol.proto.uuid_pb2 import UUID -from uprotocol.transport.builder.uattributesbuilder import UAttributesBuilder +from uprotocol.communication.calloptions import CallOptions +from uprotocol.communication.upayload import UPayload +from uprotocol.transport.builder.umessagebuilder import UMessageBuilder from uprotocol.transport.ulistener import UListener -from uprotocol.transport.validate import uattributesvalidator -from uprotocol.transport.validate.uattributesvalidator import ( +from uprotocol.transport.validator import uattributesvalidator +from uprotocol.transport.validator.uattributesvalidator import ( UAttributesValidator, ) -from uprotocol.uri.serializer.longuriserializer import LongUriSerializer -from uprotocol.uri.serializer.microuriserializer import MicroUriSerializer +from uprotocol.uri.serializer.uriserializer import UriSerializer from uprotocol.uri.validator.urivalidator import UriValidator from uprotocol.uuid.factory.uuidfactory import Factories from uprotocol.uuid.factory.uuidutils import UUIDUtils -from uprotocol.uuid.serializer.longuuidserializer import LongUuidSerializer -from uprotocol.uuid.validate.uuidvalidator import UuidValidator, Validators +from uprotocol.uuid.serializer.uuidserializer import UuidSerializer +from uprotocol.uuid.validator.uuidvalidator import UuidValidator, Validators +from uprotocol.v1.uattributes_pb2 import UAttributes, UMessageType, UPayloadFormat +from uprotocol.v1.ucode_pb2 import UCode +from uprotocol.v1.umessage_pb2 import UMessage +from uprotocol.v1.uri_pb2 import UUri +from uprotocol.v1.ustatus_pb2 import UStatus +from uprotocol.v1.uuid_pb2 import UUID from uprotocol.validation.validationresult import ValidationResult repo = git.Repo(".", search_parent_directories=True) @@ -70,10 +66,9 @@ class SocketUListener(UListener): def on_receive(self, umsg: UMessage) -> None: logger.info("Listener received") if umsg.attributes.type == UMessageType.UMESSAGE_TYPE_REQUEST: - attributes = UAttributesBuilder.response( + attributes = UMessageBuilder.response( umsg.attributes.sink, umsg.attributes.source, - UPriority.UPRIORITY_CS4, umsg.attributes.id, ).build() any_obj = any_pb2.Any() @@ -164,11 +159,11 @@ def populate_fields(json_obj: Dict[str, Any], proto_obj): else: field_type = type(getattr(proto_obj, field_name)) try: - if field_type == int: + if field_type is int: value = int(value) - elif field_type == float: + elif field_type is float: value = float(value) - elif field_type == bytes: + elif field_type is bytes: if isinstance(value, str): value = value.encode("utf-8") @@ -219,9 +214,9 @@ def handle_response(message): res_future.add_done_callback(handle_response) -def handle_long_serialize_uuri(json_msg: Dict[str, Any]): +def handle_serialize_uuri(json_msg: Dict[str, Any]): uri: UUri = dict_to_proto(json_msg["data"], UUri()) - serialized_uuri: str = LongUriSerializer().serialize(uri) + serialized_uuri: str = UriSerializer.serialize(uri) send_to_test_manager( serialized_uuri, actioncommands.SERIALIZE_URI, @@ -229,8 +224,8 @@ def handle_long_serialize_uuri(json_msg: Dict[str, Any]): ) -def handle_long_deserialize_uri(json_msg: Dict[str, Any]): - uuri: UUri = LongUriSerializer().deserialize(json_msg["data"]) +def handle_deserialize_uri(json_msg: Dict[str, Any]): + uuri: UUri = UriSerializer.deserialize(json_msg["data"]) send_to_test_manager( uuri, actioncommands.DESERIALIZE_URI, @@ -238,8 +233,8 @@ def handle_long_deserialize_uri(json_msg: Dict[str, Any]): ) -def handle_long_deserialize_uuid(json_msg: Dict[str, Any]): - uuid: UUID = LongUuidSerializer().deserialize(json_msg["data"]) +def handle_deserialize_uuid(json_msg: Dict[str, Any]): + uuid: UUID = UuidSerializer.deserialize(json_msg["data"]) send_to_test_manager( uuid, actioncommands.DESERIALIZE_UUID, @@ -247,9 +242,9 @@ def handle_long_deserialize_uuid(json_msg: Dict[str, Any]): ) -def handle_long_serialize_uuid(json_msg: Dict[str, Any]): +def handle_serialize_uuid(json_msg: Dict[str, Any]): uuid: UUID = dict_to_proto(json_msg["data"], UUID()) - serialized_uuid: str = LongUuidSerializer().serialize(uuid) + serialized_uuid: str = UuidSerializer.serialize(uuid) send_to_test_manager( serialized_uuid, actioncommands.SERIALIZE_UUID, @@ -264,17 +259,21 @@ def handle_uri_validate_command(json_msg: Dict[str, Any]): uuri: UUri = dict_to_proto(uuri_data, UUri()) validator_func = { - "uri": UriValidator.validate, - "rpc_response": UriValidator.validate_rpc_response, - "rpc_method": UriValidator.validate_rpc_method, "is_empty": UriValidator.is_empty, - "is_resolved": UriValidator.is_resolved, - "is_micro_form": UriValidator.is_micro_form, - "is_long_form": UriValidator.is_long_form, + "is_rpc_method": UriValidator.is_rpc_method, + "is_rpc_response": UriValidator.is_rpc_response, + "is_notification_destination": UriValidator.is_notification_destination, + "is_default_resource_id": UriValidator.is_default_resource_id, + "is_topic": UriValidator.is_topic, + "matches": UriValidator.matches, }.get(val_type) if validator_func: - status: Union[bool, ValidationResult] = validator_func(uuri) + if val_type == "matches": + uri_to_match = UriSerializer.deserialize(json_msg["data"]["uuri_2"]) + status: Union[bool, ValidationResult] = validator_func(uuri, uri_to_match) + else: + status: Union[bool, ValidationResult] = validator_func(uuri) if isinstance(status, bool): result = str(status) message = "" @@ -297,9 +296,9 @@ def handle_uri_validate_command(json_msg: Dict[str, Any]): ) -def handle_micro_serialize_uri_command(json_msg: Dict[str, Any]): +def handle_serialize_uri_command(json_msg: Dict[str, Any]): uri: UUri = dict_to_proto(json_msg["data"], UUri()) - serialized_uuri: bytes = MicroUriSerializer().serialize(uri) + serialized_uuri: bytes = UriSerializer.serialize(uri) # Use "iso-8859-1" to decode bytes -> str, so no UnicodeDecodeError if "utf-8" decode serialized_uuri_json_packed: str = serialized_uuri.decode("iso-8859-1") send_to_test_manager( @@ -309,11 +308,11 @@ def handle_micro_serialize_uri_command(json_msg: Dict[str, Any]): ) -def handle_micro_deserialize_uri_command(json_msg: Dict[str, Any]): +def handle_deserialize_uri_command(json_msg: Dict[str, Any]): sent_micro_serialized_uuri: str = json_msg["data"] # Incoming micro serialized uuri is sent as an "iso-8859-1" str micro_serialized_uuri: bytes = sent_micro_serialized_uuri.encode("iso-8859-1") - uuri: UUri = MicroUriSerializer().deserialize(micro_serialized_uuri) + uuri: UUri = UriSerializer.deserialize(micro_serialized_uuri) send_to_test_manager( uuri, actioncommands.MICRO_DESERIALIZE_URI, @@ -330,7 +329,7 @@ def handle_uuid_validate_command(json_msg): "invalid": UUID(msb=0, lsb=0), "uprotocol_time": Factories.UPROTOCOL.create(datetime.utcfromtimestamp(0).replace(tzinfo=timezone.utc)), "uuidv6": Factories.UUIDV6.create(), - "uuidv4": LongUuidSerializer().deserialize("195f9bd1-526d-4c28-91b1-ff34c8e3632d"), + "uuidv4": UuidSerializer.deserialize("195f9bd1-526d-4c28-91b1-ff34c8e3632d"), }.get(uuid_type) status = { @@ -447,14 +446,12 @@ def handle_uattributes_validate_command(json_msg: Dict[str, Any]): actioncommands.REGISTER_LISTENER_COMMAND: handle_register_listener_command, actioncommands.UNREGISTER_LISTENER_COMMAND: handle_unregister_listener_command, actioncommands.INVOKE_METHOD_COMMAND: handle_invoke_method_command, - actioncommands.SERIALIZE_URI: handle_long_serialize_uuri, - actioncommands.DESERIALIZE_URI: handle_long_deserialize_uri, - actioncommands.SERIALIZE_UUID: handle_long_serialize_uuid, - actioncommands.DESERIALIZE_UUID: handle_long_deserialize_uuid, + actioncommands.SERIALIZE_URI: handle_serialize_uuri, + actioncommands.DESERIALIZE_URI: handle_deserialize_uri, + actioncommands.SERIALIZE_UUID: handle_serialize_uuid, + actioncommands.DESERIALIZE_UUID: handle_deserialize_uuid, actioncommands.VALIDATE_URI: handle_uri_validate_command, actioncommands.VALIDATE_UATTRIBUTES: handle_uattributes_validate_command, - actioncommands.MICRO_SERIALIZE_URI: handle_micro_serialize_uri_command, - actioncommands.MICRO_DESERIALIZE_URI: handle_micro_deserialize_uri_command, actioncommands.VALIDATE_UUID: handle_uuid_validate_command, } diff --git a/test_agent/rust/src/constants.rs b/test_agent/rust/src/constants.rs index 373a6d16..94e855fc 100644 --- a/test_agent/rust/src/constants.rs +++ b/test_agent/rust/src/constants.rs @@ -27,6 +27,6 @@ pub const SDK_INIT_MESSAGE: &str = pub const RESPONSE_ON_RECEIVE: &str = "onreceive"; -pub const TEST_MANAGER_ADDR: (&str, u16) = ("127.0.0.5", 12345); +pub const TEST_MANAGER_ADDR: (&str, u16) = ("127.0.0.5", 33333); pub const ZENOH_TRANSPORT: &str = "zenoh"; diff --git a/test_manager/features/environment.py b/test_manager/features/environment.py index bfa03033..d4f80489 100644 --- a/test_manager/features/environment.py +++ b/test_manager/features/environment.py @@ -19,6 +19,7 @@ from threading import Thread import git +from behave.model import Scenario from behave.runner import Context repo = git.Repo(".", search_parent_directories=True) @@ -38,6 +39,8 @@ def before_all(context): :return: None """ + Scenario.continue_after_failed_step = True + context.transport = {} context.ues = {} context.dispatcher = {} @@ -45,7 +48,7 @@ def before_all(context): loggerutils.setup_logging() loggerutils.setup_formatted_logging(context) - test_manager = TestManager(context, "127.0.0.5", 12345) + test_manager = TestManager(context, "127.0.0.5", 33333) thread = Thread(target=test_manager.listen_for_incoming_events) thread.start() context.tm = test_manager diff --git a/test_manager/features/steps/tck_step_implementations.py b/test_manager/features/steps/tck_step_implementations.py index 57dfbce4..c4b17223 100644 --- a/test_manager/features/steps/tck_step_implementations.py +++ b/test_manager/features/steps/tck_step_implementations.py @@ -30,8 +30,7 @@ from behave import given, register_type, then, when from behave.runner import Context from hamcrest import assert_that, equal_to -from uprotocol.proto.uattributes_pb2 import UMessageType, UPriority -from uprotocol.proto.ustatus_pb2 import UCode +from uprotocol.v1.ucode_pb2 import UCode PYTHON_TA_PATH = "/test_agent/python/testagent.py" JAVA_TA_PATH = "/test_agent/java/target/tck-test-agent-java-jar-with-dependencies.jar" @@ -99,18 +98,15 @@ def cast(value: str, data_type: str, jsonable: bool = True) -> Union[str, int, b @return Correctly typed value """ - if "UPriority" in value: - enum_member: str = value.split(".")[1] - value = getattr(UPriority, enum_member) - elif "UMessageType" in value: - enum_member: str = value.split(".")[1] - value = getattr(UMessageType, enum_member) - elif "UCode" in value: + if "UCode" in value: enum_member: str = value.split(".")[1] value = getattr(UCode, enum_member) if data_type == "int": - value = int(value) + try: + value = int(value) + except ValueError: + value = None elif data_type == "str": pass elif data_type == "bool": diff --git a/test_manager/features/tests/validators/uri_validator.feature b/test_manager/features/tests/validators/uri_validator.feature index 8606ebde..3e3d962d 100644 --- a/test_manager/features/tests/validators/uri_validator.feature +++ b/test_manager/features/tests/validators/uri_validator.feature @@ -23,24 +23,74 @@ # ------------------------------------------------------------------------- Feature: URI Validation - Scenario Outline: UUri validate completely filled UUri + Scenario Outline: UUri Validation for an empty UUri + Given "uE1" creates data for "uri_deserialize" + + When sends a "uri_deserialize" request with serialized input "" + + Then receives json with following set fields: + | protobuf_field_names | protobuf_field_values | protobuf_field_type | + | authority_name | | str | + | ue_id | 0 | int | + | ue_version_major | 0 | int | + | resource_id | 0 | int | + + When "uE2" creates data for "uri_validate" + And sets "validation_type" to "" + And sets "uuri" to previous response data + And sends "uri_validate" request + + Then receives validation result as "" + + Examples: + | validation_type | bool_result | + | is_empty | True | + | is_rpc_method | False | + | is_rpc_response | False | + | is_notification_destination | False | + | is_default_resource_id | False | + | is_topic | False | + + + Scenario Outline: UUri validation for a UUri with only authority_name + Given "uE1" creates data for "uri_deserialize" + + When sends a "uri_deserialize" request with serialized input "//hi" + + Then receives json with following set fields: + | protobuf_field_names | protobuf_field_values | protobuf_field_type | + | authority_name | hi | str | + | ue_id | 0 | int | + | ue_version_major | 0 | int | + | resource_id | 0 | int | + + When "uE2" creates data for "uri_validate" + And sets "validation_type" to "" + And sets "uuri" to previous response data + And sends "uri_validate" request + + Then receives validation result as "" + + Examples: + | validation_type | bool_result | + | is_empty | False | + | is_rpc_method | False | + | is_rpc_response | True | + | is_notification_destination | True | + | is_default_resource_id | True | + | is_topic | False | + + Scenario Outline: UUri validation for a UUri with resource_id less than min_topic_id Given "uE1" creates data for "uri_deserialize" - When sends a "uri_deserialize" request with serialized input "//authority_name_nameName/name of entity/64/resource name.resource instance#message of resource" + When sends a "uri_deserialize" request with serialized input "//hi/1/1/7FFF" Then receives json with following set fields: | protobuf_field_names | protobuf_field_values | protobuf_field_type | - | authority.ip | | bytes | - | authority.id | | bytes | - | authority.name | authority_name_nameName | str | - | entity.id | 0 | int | - | entity.name | name of entity | str | - | entity.version_major | 64 | int | - | entity.version_minor | 0 | int | - | resource.name | resource name | str | - | resource.instance | resource instance | str | - | resource.message | message of resource | str | - | resource.id | 0 | int | + | authority_name | hi | str | + | ue_id | 1 | int | + | ue_version_major | 1 | int | + | resource_id | 32767 | int | When "uE2" creates data for "uri_validate" And sets "validation_type" to "" @@ -48,39 +98,22 @@ Feature: URI Validation And sends "uri_validate" request Then receives validation result as "" - And receives validation message as "" Examples: - | validation_type | bool_result | message_result | - | uri | True | | - # False for now bc default message="" is set, but should be True - | rpc_response | False | Invalid RPC response type. | - | rpc_method | False | Invalid RPC method uri. Uri should be the method to be called, or method from response. | - | is_empty | False | | - - # is_resolved == is long formed (filled names in uauth, enti, & resrc) and micro formed (existing ids in uauth, enti, & resrc ) - | is_resolved | True | | - | is_micro_form | True | | - | is_long_form | True | | - - Scenario Outline: UUri validate completely filled UUri 2 + | validation_type | bool_result | + | is_rpc_method | True | + + Scenario Outline: UUri validation for a UUri with resource_id greater than min_topic_id Given "uE1" creates data for "uri_deserialize" - When sends a "uri_deserialize" request with serialized input "//uAuthName/entityName/1/resrcName.instance#Message" + When sends a "uri_deserialize" request with serialized input "//hi/1/1/8000" Then receives json with following set fields: | protobuf_field_names | protobuf_field_values | protobuf_field_type | - | authority.ip | | bytes | - | authority.id | | bytes | - | authority.name | uAuthName | str | - | entity.id | 0 | int | - | entity.name | entityName | str | - | entity.version_major | 1 | int | - | entity.version_minor | 0 | int | - | resource.name | resrcName | str | - | resource.instance | instance | str | - | resource.message | Message | str | - | resource.id | 0 | int | + | authority_name | hi | str | + | ue_id | 1 | int | + | ue_version_major | 1 | int | + | resource_id | 32768 | int | When "uE2" creates data for "uri_validate" And sets "validation_type" to "" @@ -88,40 +121,22 @@ Feature: URI Validation And sends "uri_validate" request Then receives validation result as "" - And receives validation message as "" Examples: - | validation_type | bool_result | message_result | - | uri | True | | - # False for now bc default message="" is set, but should be True - | rpc_response | False | Invalid RPC response type. | - # rpc_method: resource.name == "rpc", resource.instance != "" or id < 32768 - | rpc_method | False | Invalid RPC method uri. Uri should be the method to be called, or method from response. | - | is_empty | False | | - - # is_resolved == is long formed (filled names in uauth, enti, & resrc) and micro formed (existing ids in uauth, enti, & resrc ) - | is_resolved | True | | - | is_micro_form | True | | - | is_long_form | True | | - - Scenario Outline: UUri validate completely filled UUri, but no uAuthority + | validation_type | bool_result | + | is_rpc_method | False | + + Scenario Outline: UUri validation for a UUri with resource_id equal to rpc_response_id Given "uE1" creates data for "uri_deserialize" - When sends a "uri_deserialize" request with serialized input "/entityName/1/resrcName.instance#Message" + When sends a "uri_deserialize" request with serialized input "//hi/1/1/8000" Then receives json with following set fields: | protobuf_field_names | protobuf_field_values | protobuf_field_type | - | authority.ip | | bytes | - | authority.id | | bytes | - | authority.name | | str | - | entity.id | 0 | int | - | entity.name | entityName | str | - | entity.version_major | 1 | int | - | entity.version_minor | 0 | int | - | resource.name | resrcName | str | - | resource.instance | instance | str | - | resource.message | Message | str | - | resource.id | 0 | int | + | authority_name | hi | str | + | ue_id | 1 | int | + | ue_version_major | 1 | int | + | resource_id | 32768 | int | When "uE2" creates data for "uri_validate" And sets "validation_type" to "" @@ -129,560 +144,343 @@ Feature: URI Validation And sends "uri_validate" request Then receives validation result as "" - And receives validation message as "" Examples: - | validation_type | bool_result | message_result | - | uri | True | | - # False for now bc default message="" is set, but should be True - | rpc_response | False | Invalid RPC response type. | - # rpc_method: resource.name == "rpc", resource.instance != "" or id < 32768 - | rpc_method | False | Invalid RPC method uri. Uri should be the method to be called, or method from response. | - | is_empty | False | | - - # is_resolved == is long formed (filled names in uauth, enti, & resrc) and micro formed (existing ids in uauth, enti, & resrc ) - | is_resolved | False | | - | is_micro_form | True | | - | is_long_form | False | | - - Scenario Outline: UUri validate completely filled UUri, but no UEntity + | validation_type | bool_result | + | is_rpc_method | False | + + Scenario Outline: UUri matches when equal to //authority/A410/3/1003 Given "uE1" creates data for "uri_deserialize" - When sends a "uri_deserialize" request with serialized input "//uAuthName///resrcName.instance#Message" + When sends a "uri_deserialize" request with serialized input "//authority/A410/3/1003" Then receives json with following set fields: | protobuf_field_names | protobuf_field_values | protobuf_field_type | - | authority.ip | | bytes | - | authority.id | | bytes | - | authority.name | uAuthName | str | - | entity.id | 0 | int | - | entity.name | | str | - | entity.version_major | 0 | int | - | entity.version_minor | 0 | int | - | resource.name | resrcName | str | - | resource.instance | instance | str | - | resource.message | Message | str | - | resource.id | 0 | int | + | authority_name | authority | str | + | ue_id | 42000 | int | + | ue_version_major | 3 | int | + | resource_id | 4099 | int | When "uE2" creates data for "uri_validate" And sets "validation_type" to "" And sets "uuri" to previous response data + And sets "uuri_2" to "//authority/A410/3/1003" And sends "uri_validate" request Then receives validation result as "" - And receives validation message as "" Examples: - | validation_type | bool_result | message_result | - | uri | False | Uri is missing uSoftware Entity name. | - # False for now bc default message="" is set, but should be True - | rpc_response | False | Uri is missing uSoftware Entity name. | - # rpc_method: resource.name == "rpc", resource.instance != "" or id < 32768 - | rpc_method | False | Uri is missing uSoftware Entity name. | - | is_empty | False | | - - # is_resolved == is long formed (filled names in uauth, enti, & resrc) and micro formed (existing ids in uauth, enti, & resrc ) - | is_resolved | False | | - | is_micro_form | True | | - | is_long_form | False | | - - - Scenario Outline: UUri validate completely filled UUri, but no uResource + | validation_type | bool_result | + | matches | True | + + Scenario Outline: UUri matches when wildcard authority equal to //authority/A410/3/1003 Given "uE1" creates data for "uri_deserialize" - When sends a "uri_deserialize" request with serialized input "//uAuthName/entityName/1" + When sends a "uri_deserialize" request with serialized input "//*/A410/3/1003" Then receives json with following set fields: | protobuf_field_names | protobuf_field_values | protobuf_field_type | - | authority.ip | | bytes | - | authority.id | | bytes | - | authority.name | uAuthName | str | - | entity.id | 0 | int | - | entity.name | entityName | str | - | entity.version_major | 1 | int | - | entity.version_minor | 0 | int | - | resource.name | | str | - | resource.instance | | str | - | resource.message | | str | - | resource.id | 0 | int | + | authority_name | * | str | + | ue_id | 42000 | int | + | ue_version_major | 3 | int | + | resource_id | 4099 | int | When "uE2" creates data for "uri_validate" And sets "validation_type" to "" And sets "uuri" to previous response data + And sets "uuri_2" to "//authority/A410/3/1003" And sends "uri_validate" request Then receives validation result as "" - And receives validation message as "" Examples: - | validation_type | bool_result | message_result | - | uri | True | | - # False for now bc default message="" is set, but should be True - | rpc_response | False | Invalid RPC response type. | - # rpc_method: resource.name == "rpc", resource.instance != "" or id < 32768 - | rpc_method | False | Invalid RPC method uri. Uri should be the method to be called, or method from response. | - | is_empty | False | | - - # is_resolved == is long formed (filled names in uauth, enti, & resrc) and micro formed (existing ids in uauth, enti, & resrc ) - | is_resolved | False | | - | is_micro_form | True | | - | is_long_form | False | | - + | validation_type | bool_result | + | matches | True | - Scenario Outline: UUri validate purely remote UUri + Scenario Outline: UUri matches when wildcard authority equal to /A410/3/1003 Given "uE1" creates data for "uri_deserialize" - When sends a "uri_deserialize" request with serialized input "" + When sends a "uri_deserialize" request with serialized input "//*/A410/3/1003" Then receives json with following set fields: | protobuf_field_names | protobuf_field_values | protobuf_field_type | - | authority.ip | | bytes | - | authority.name | | str | - | entity.id | 0 | int | - | entity.name | | str | - | entity.version_major | 0 | int | - | entity.version_minor | 0 | int | - | resource.name | | str | - | resource.instance | | str | - | resource.message | | str | - | resource.id | 0 | int | + | authority_name | * | str | + | ue_id | 42000 | int | + | ue_version_major | 3 | int | + | resource_id | 4099 | int | When "uE2" creates data for "uri_validate" And sets "validation_type" to "" And sets "uuri" to previous response data + And sets "uuri_2" to "/A410/3/1003" And sends "uri_validate" request Then receives validation result as "" - And receives validation message as "" Examples: - | validation_type | bool_result | message_result | - | uri | False | Uri is missing uSoftware Entity name. | - # False for now bc default message="" is set, but should be True - | rpc_response | False | Uri is missing uSoftware Entity name. | - # rpc_method: resource.name == "rpc", resource.instance != "" or id < 32768 - | rpc_method | False | Uri is missing uSoftware Entity name. | - | is_empty | False | | - - # is_resolved == is long formed (filled names in uauth, enti, & resrc) and micro formed (existing ids in uauth, enti, & resrc ) - | is_resolved | False | | - | is_micro_form | True | | - | is_long_form | False | | - - Scenario Outline: UUri validate with random string + | validation_type | bool_result | + | matches | True | + + Scenario Outline: UUri matches when wildcard entity_id equal to //authority/A410/3/1003 Given "uE1" creates data for "uri_deserialize" - When sends a "uri_deserialize" request with serialized input "random string" + When sends a "uri_deserialize" request with serialized input "//authority/FFFF/3/1003" Then receives json with following set fields: | protobuf_field_names | protobuf_field_values | protobuf_field_type | - | authority.ip | | bytes | - | authority.name | | str | - | entity.id | 0 | int | - | entity.name | | str | - | entity.version_major | 0 | int | - | entity.version_minor | 0 | int | - | resource.name | | str | - | resource.instance | | str | - | resource.message | | str | - | resource.id | 0 | int | + | authority_name | authority | str | + | ue_id | 65535 | int | + | ue_version_major | 3 | int | + | resource_id | 4099 | int | When "uE2" creates data for "uri_validate" And sets "validation_type" to "" And sets "uuri" to previous response data + And sets "uuri_2" to "//authority/A410/3/1003" And sends "uri_validate" request Then receives validation result as "" - And receives validation message as "" Examples: - | validation_type | bool_result | message_result | - | uri | False | Uri is missing uSoftware Entity name. | - # False for now bc default message="" is set, but should be True - | rpc_response | False | Uri is missing uSoftware Entity name. | - # rpc_method: resource.name == "rpc", resource.instance != "" or id < 32768 - | rpc_method | False | Uri is missing uSoftware Entity name. | - | is_empty | False | | - - # is_resolved == is long formed (filled names in uauth, enti, & resrc) and micro formed (existing ids in uauth, enti, & resrc ) - | is_resolved | False | | - | is_micro_form | True | | - | is_long_form | False | | - - Scenario Outline: UUri validate just entity name to validate correctly + | validation_type | bool_result | + | matches | True | + + Scenario Outline: UUri matches when matching entity instance equal to //authority/2A410/3/1003 Given "uE1" creates data for "uri_deserialize" - When sends a "uri_deserialize" request with serialized input "/neelam" + When sends a "uri_deserialize" request with serialized input "//authority/A410/3/1003" Then receives json with following set fields: | protobuf_field_names | protobuf_field_values | protobuf_field_type | - | authority.ip | | bytes | - | authority.name | | str | - | entity.id | 0 | int | - | entity.name | neelam | str | - | entity.version_major | 0 | int | - | entity.version_minor | 0 | int | - | resource.name | | str | - | resource.instance | | str | - | resource.message | | str | - | resource.id | 0 | int | + | authority_name | authority | str | + | ue_id | 42000 | int | + | ue_version_major | 3 | int | + | resource_id | 4099 | int | When "uE2" creates data for "uri_validate" And sets "validation_type" to "" And sets "uuri" to previous response data + And sets "uuri_2" to "//authority/2A410/3/1003" And sends "uri_validate" request Then receives validation result as "" - And receives validation message as "" Examples: - | validation_type | bool_result | message_result | - | uri | True | | - # False for now bc default message="" is set, but should be True - | rpc_response | False | Invalid RPC response type. | - # rpc_method: resource.name == "rpc", resource.instance != "" or id < 32768 - | rpc_method | False | Invalid RPC method uri. Uri should be the method to be called, or method from response. | - | is_empty | False | | - - # is_resolved == is long formed (filled names in uauth, enti, & resrc) and micro formed (existing ids in uauth, enti, & resrc ) - | is_resolved | False | | - | is_micro_form | True | | - | is_long_form | False | | - - Scenario Outline: UUri validate filled UAuthority and partially filled UEntity, but no UEntity name + | validation_type | bool_result | + | matches | True | + + Scenario Outline: UUri matches when wildcard entity version equal to //authority/A410/3/1003 Given "uE1" creates data for "uri_deserialize" - When sends a "uri_deserialize" request with serialized input "//VCU.myvin//1" + When sends a "uri_deserialize" request with serialized input "//authority/A410/FF/1003" Then receives json with following set fields: | protobuf_field_names | protobuf_field_values | protobuf_field_type | - | authority.ip | | bytes | - | authority.name | VCU.myvin | str | - | entity.id | 0 | int | - | entity.name | | str | - | entity.version_major | 1 | int | - | entity.version_minor | 0 | int | - | resource.name | | str | - | resource.instance | | str | - | resource.message | | str | - | resource.id | 0 | int | + | authority_name | authority | str | + | ue_id | 42000 | int | + | ue_version_major | 255 | int | + | resource_id | 4099 | int | When "uE2" creates data for "uri_validate" And sets "validation_type" to "" And sets "uuri" to previous response data + And sets "uuri_2" to "//authority/A410/3/1003" And sends "uri_validate" request Then receives validation result as "" - And receives validation message as "" Examples: - | validation_type | bool_result | message_result | - | uri | False | Uri is missing uSoftware Entity name. | - # False for now bc default message="" is set, but should be True - | rpc_response | False | Uri is missing uSoftware Entity name. | - # rpc_method: resource.name == "rpc", resource.instance != "" or id < 32768 - | rpc_method | False | Uri is missing uSoftware Entity name. | - | is_empty | False | | - - # is_resolved == is long formed (filled names in uauth, enti, & resrc) and micro formed (existing ids in uauth, enti, & resrc ) - | is_resolved | False | | - | is_micro_form | True | | - | is_long_form | False | | - - Scenario Outline: UUri validate just UEntity name and version major + | validation_type | bool_result | + | matches | True | + + Scenario Outline: UUri matches when wildcard resource id equal to //authority/A410/3/1003 Given "uE1" creates data for "uri_deserialize" - When sends a "uri_deserialize" request with serialized input "/hartley/1000" + When sends a "uri_deserialize" request with serialized input "//authority/A410/3/FFFF" Then receives json with following set fields: | protobuf_field_names | protobuf_field_values | protobuf_field_type | - | authority.ip | | bytes | - | authority.name | | str | - | entity.id | 0 | int | - | entity.name | hartley | str | - | entity.version_major | 1000 | int | - | entity.version_minor | 0 | int | - | resource.name | | str | - | resource.instance | | str | - | resource.message | | str | - | resource.id | 0 | int | + | authority_name | authority | str | + | ue_id | 42000 | int | + | ue_version_major | 3 | int | + | resource_id | 65535 | int | When "uE2" creates data for "uri_validate" And sets "validation_type" to "" And sets "uuri" to previous response data + And sets "uuri_2" to "//authority/A410/3/1003" And sends "uri_validate" request Then receives validation result as "" - And receives validation message as "" Examples: - | validation_type | bool_result | message_result | - | uri | True | | - # False for now bc default message="" is set, but should be True - | rpc_response | False | Invalid RPC response type. | - # rpc_method: resource.name == "rpc", resource.instance != "" or id < 32768 - | rpc_method | False | Invalid RPC method uri. Uri should be the method to be called, or method from response. | - | is_empty | False | | - - # is_resolved == is long formed (filled names in uauth, enti, & resrc) and micro formed (existing ids in uauth, enti, & resrc ) - | is_resolved | False | | - | is_micro_form | True | | - | is_long_form | False | | - - Scenario Outline: UUri validate random string 2 + | validation_type | bool_result | + | matches | True | + + Scenario Outline: UUri doesn't match when uppercase authorty not equal to //authority/A410/3/1003 Given "uE1" creates data for "uri_deserialize" - When sends a "uri_deserialize" request with serialized input ":" + When sends a "uri_deserialize" request with serialized input "//Authority/A410/3/1003" Then receives json with following set fields: | protobuf_field_names | protobuf_field_values | protobuf_field_type | - | authority.ip | | bytes | - | authority.name | | str | - | entity.id | 0 | int | - | entity.name | | str | - | entity.version_major | 0 | int | - | entity.version_minor | 0 | int | - | resource.name | | str | - | resource.instance | | str | - | resource.message | | str | - | resource.id | 0 | int | + | authority_name | Authority | str | + | ue_id | 42000 | int | + | ue_version_major | 3 | int | + | resource_id | 4099 | int | When "uE2" creates data for "uri_validate" And sets "validation_type" to "" And sets "uuri" to previous response data + And sets "uuri_2" to "//authority/A410/3/1003" And sends "uri_validate" request Then receives validation result as "" - And receives validation message as "" Examples: - | validation_type | bool_result | message_result | - | uri | False | Uri is missing uSoftware Entity name. | - # False for now bc default message="" is set, but should be True - | rpc_response | False | Uri is missing uSoftware Entity name. | - # rpc_method: resource.name == "rpc", resource.instance != "" or id < 32768 - | rpc_method | False | Uri is missing uSoftware Entity name. | - | is_empty | False | | - - # is_resolved == is long formed (filled names in uauth, enti, & resrc) and micro formed (existing ids in uauth, enti, & resrc ) - | is_resolved | False | | - | is_micro_form | True | | - | is_long_form | False | | - - Scenario Outline: UUri validate random string 3 + | validation_type | bool_result | + | matches | False | + + Scenario Outline: UUri doesn't match when local pattern match isn't equal to //authority/A410/3/1003 Given "uE1" creates data for "uri_deserialize" - When sends a "uri_deserialize" request with serialized input "///" + When sends a "uri_deserialize" request with serialized input "/A410/3/1003" Then receives json with following set fields: | protobuf_field_names | protobuf_field_values | protobuf_field_type | - | authority.ip | | bytes | - | authority.name | | str | - | entity.id | 0 | int | - | entity.name | | str | - | entity.version_major | 0 | int | - | entity.version_minor | 0 | int | - | resource.name | | str | - | resource.instance | | str | - | resource.message | | str | - | resource.id | 0 | int | + | authority_name | | str | + | ue_id | 42000 | int | + | ue_version_major | 3 | int | + | resource_id | 4099 | int | When "uE2" creates data for "uri_validate" And sets "validation_type" to "" And sets "uuri" to previous response data + And sets "uuri_2" to "//authority/A410/3/1003" And sends "uri_validate" request Then receives validation result as "" - And receives validation message as "" Examples: - | validation_type | bool_result | message_result | - | uri | False | Uri is missing uSoftware Entity name. | - # False for now bc default message="" is set, but should be True - | rpc_response | False | Uri is missing uSoftware Entity name. | - # rpc_method: resource.name == "rpc", resource.instance != "" or id < 32768 - | rpc_method | False | Uri is missing uSoftware Entity name. | - | is_empty | False | | - - # is_resolved == is long formed (filled names in uauth, enti, & resrc) and micro formed (existing ids in uauth, enti, & resrc ) - | is_resolved | False | | - | is_micro_form | True | | - | is_long_form | False | | - - # Tests UriValidator.validate_rpc_method() - Scenario Outline: UUri validate rpc_method filled entity name, resource name and instance + | validation_type | bool_result | + | matches | False | + + Scenario Outline: UUri doesn't match when different authority to //authority/A410/3/1003 Given "uE1" creates data for "uri_deserialize" - When sends a "uri_deserialize" request with serialized input "/neelam//rpc.echo" + When sends a "uri_deserialize" request with serialized input "//other/A410/3/1003" Then receives json with following set fields: | protobuf_field_names | protobuf_field_values | protobuf_field_type | - | authority.ip | | bytes | - | authority.name | | str | - | entity.id | 0 | int | - | entity.name | neelam | str | - | entity.version_major | 0 | int | - | entity.version_minor | 0 | int | - | resource.name | rpc | str | - | resource.instance | echo | str | - | resource.message | | str | - | resource.id | 0 | int | + | authority_name | other | str | + | ue_id | 42000 | int | + | ue_version_major | 3 | int | + | resource_id | 4099 | int | When "uE2" creates data for "uri_validate" And sets "validation_type" to "" And sets "uuri" to previous response data + And sets "uuri_2" to "//authority/A410/3/1003" And sends "uri_validate" request Then receives validation result as "" - And receives validation message as "" Examples: - | validation_type | bool_result | message_result | - | uri | True | | - # False for now bc default message="" is set, but should be True - | rpc_response | False | Invalid RPC response type. | - # rpc_method: resource.name == "rpc", resource.instance != "" or id < 32768 - | rpc_method | True | | - | is_empty | False | | - - # is_resolved == is long formed (filled names in uauth, enti, & resrc) and micro formed (existing ids in uauth, enti, & resrc ) - | is_resolved | False | | - | is_micro_form | True | | - | is_long_form | False | | - - - Scenario Outline: UUri validate rpc_method as rpc methods 2 + | validation_type | bool_result | + | matches | False | + + Scenario Outline: UUri doesn't match when different entity id to //authority/A410/3/1003 Given "uE1" creates data for "uri_deserialize" - When sends a "uri_deserialize" request with serialized input "//bo.cloud/petapp/1/rpc.response" + When sends a "uri_deserialize" request with serialized input "//authority/45/3/1003" Then receives json with following set fields: | protobuf_field_names | protobuf_field_values | protobuf_field_type | - | authority.ip | | bytes | - | authority.name | bo.cloud | str | - | entity.id | 0 | int | - | entity.name | petapp | str | - | entity.version_major | 1 | int | - | entity.version_minor | 0 | int | - | resource.name | rpc | str | - | resource.instance | response | str | - | resource.message | | str | - | resource.id | 0 | int | + | authority_name | authority | str | + | ue_id | 69 | int | + | ue_version_major | 3 | int | + | resource_id | 4099 | int | When "uE2" creates data for "uri_validate" And sets "validation_type" to "" And sets "uuri" to previous response data + And sets "uuri_2" to "//authority/A410/3/1003" And sends "uri_validate" request Then receives validation result as "" - And receives validation message as "" Examples: - | validation_type | bool_result | message_result | - | uri | True | | - # False for now bc default message="" is set, but should be True - | rpc_response | False | Invalid RPC response type. | - # rpc_method: resource.name == "rpc", resource.instance != "" or id < 32768 - | rpc_method | True | | - | is_empty | False | | - - # is_resolved == is long formed (filled names in uauth, enti, & resrc) and micro formed (existing ids in uauth, enti, & resrc ) - | is_resolved | True | | - | is_micro_form | True | | - | is_long_form | True | | + | validation_type | bool_result | + | matches | False | - - Scenario Outline: UUri validate rpc_method as rpc methods 3 + Scenario Outline: UUri doesn't match when different entity instance to //authority/A410/3/1003 Given "uE1" creates data for "uri_deserialize" - When sends a "uri_deserialize" request with serialized input "/petapp//rpc.response" + When sends a "uri_deserialize" request with serialized input "//authority/30A410/3/1003" Then receives json with following set fields: | protobuf_field_names | protobuf_field_values | protobuf_field_type | - | authority.ip | | bytes | - | authority.name | | str | - | entity.id | 0 | int | - | entity.name | petapp | str | - | entity.version_major | 0 | int | - | entity.version_minor | 0 | int | - | resource.name | rpc | str | - | resource.instance | response | str | - | resource.message | | str | - | resource.id | 0 | int | + | authority_name | authority | str | + | ue_id | 3187728 | int | + | ue_version_major | 3 | int | + | resource_id | 4099 | int | When "uE2" creates data for "uri_validate" And sets "validation_type" to "" And sets "uuri" to previous response data + And sets "uuri_2" to "//authority/A410/3/1003" And sends "uri_validate" request Then receives validation result as "" - And receives validation message as "" Examples: - | validation_type | bool_result | message_result | - | uri | True | | - # False for now bc default message="" is set, but should be True - | rpc_response | False | Invalid RPC response type. | - # rpc_method: resource.name == "rpc", resource.instance != "" or id < 32768 - | rpc_method | True | | - | is_empty | False | | - - # is_resolved == is long formed (filled names in uauth, enti, & resrc) and micro formed (existing ids in uauth, enti, & resrc ) - | is_resolved | False | | - | is_micro_form | True | | - | is_long_form | False | | - - Scenario: UUri validate rpc_method, even tho resource.instance == "", resource id < 32768 so still rpc_method + | validation_type | bool_result | + | matches | False | + + Scenario Outline: UUri doesn't match when different entity version to //authority/A410/3/1003 Given "uE1" creates data for "uri_deserialize" - When sends a "uri_deserialize" request with serialized input "/petapp/1/rpc" + When sends a "uri_deserialize" request with serialized input "//authority/A410/1/1003" Then receives json with following set fields: | protobuf_field_names | protobuf_field_values | protobuf_field_type | - | authority.ip | | bytes | - | authority.name | | str | - | entity.id | 0 | int | - | entity.name | petapp | str | - | entity.version_major | 1 | int | - | entity.version_minor | 0 | int | - | resource.name | rpc | str | - | resource.instance | | str | - | resource.message | | str | - | resource.id | 0 | int | + | authority_name | authority | str | + | ue_id | 42000 | int | + | ue_version_major | 1 | int | + | resource_id | 4099 | int | When "uE2" creates data for "uri_validate" - And sets "validation_type" to "rpc_method" + And sets "validation_type" to "" And sets "uuri" to previous response data + And sets "uuri_2" to "//authority/A410/3/1003" And sends "uri_validate" request - Then receives validation result as "True" - And receives validation message as "" + Then receives validation result as "" + Examples: + | validation_type | bool_result | + | matches | False | - # Below is False, BUT should be TRUE! fix until new UUri signature is implemented by June 10ish, 2024 - Scenario: UUri validate is_rpc_response given inputs + Scenario Outline: UUri doesn't match when different resource id to //authority/A410/3/1003 Given "uE1" creates data for "uri_deserialize" - When sends a "uri_deserialize" request with serialized input "" + When sends a "uri_deserialize" request with serialized input "//authority/A410/3/ABCD" Then receives json with following set fields: | protobuf_field_names | protobuf_field_values | protobuf_field_type | - | authority.ip | | bytes | - | authority.name | | str | - | entity.id | 0 | int | - | entity.name | | str | - | entity.version_major | 0 | int | - | entity.version_minor | 0 | int | - | resource.name | | str | - | resource.instance | | str | - | resource.message | | str | - | resource.id | 0 | int | + | authority_name | authority | str | + | ue_id | 42000 | int | + | ue_version_major | 3 | int | + | resource_id | 43981 | int | When "uE2" creates data for "uri_validate" - And sets "validation_type" to "is_empty" + And sets "validation_type" to "" And sets "uuri" to previous response data + And sets "uuri_2" to "//authority/A410/3/1003" And sends "uri_validate" request - Then receives validation result as "False" - And receives validation message as "" + Then receives validation result as "" + Examples: + | validation_type | bool_result | + | matches | False | diff --git a/test_manager/testData/workflow_test_data.json b/test_manager/testData/workflow_test_data.json index 1b0e049c..c384d362 100644 --- a/test_manager/testData/workflow_test_data.json +++ b/test_manager/testData/workflow_test_data.json @@ -1,73 +1,8 @@ { - "long_uri_deserializer": { - "path": "serializers", - "ue1": ["python", "java"], - "transports": ["socket"] - }, - "long_uri_serializer": { - "path": "serializers", - "ue1": ["python", "java"], - "transports": ["socket"] - }, - "long_uuid_deserializer": { - "path": "serializers", - "ue1": ["python", "java"], - "transports": ["socket"] - }, - "long_uuid_serializer": { - "path": "serializers", - "ue1": ["python", "java"], - "transports": ["socket"] - }, - "micro_uri_deserializer": { - "path": "serializers", - "ue1": ["python", "java"], - "transports": ["socket"] - }, - "micro_uri_serializer": { - "path": "serializers", - "ue1": ["python", "java"], - "transports": ["socket"] - }, - "register_and_invoke": { - "path": "transport_rpc", - "ue1": ["all"], - "transports": ["socket"] - }, - "register_and_send": { - "path": "transport_rpc", - "ue1": ["all"], - "transports": ["socket"] - }, - "register_and_unregister": { - "path": "transport_rpc", - "ue1": ["all"], - "transports": ["socket"] - }, - "register_and_send_zenoh": { - "path": "transport_rpc", - "ue1": ["all"], - "transports": ["zenoh"] - }, - "register_and_unregister_zenoh": { - "path": "transport_rpc", - "ue1": ["all"], - "transports": ["zenoh"] - }, - "uattributes_validator": { - "path": "validators", - "ue1": ["python", "java"], - "transports": ["socket"] - }, "uri_validator": { "path": "validators", "ue1": ["python", "java"], "ue2": ["python", "java"], "transports": ["socket"] - }, - "uuid_validator": { - "path": "validators", - "ue1": ["python", "java"], - "transports": ["socket"] } } \ No newline at end of file diff --git a/up_client_socket/java/pom.xml b/up_client_socket/java/pom.xml index 7f1bc12a..04adfc0f 100644 --- a/up_client_socket/java/pom.xml +++ b/up_client_socket/java/pom.xml @@ -14,13 +14,6 @@ UTF-8 - - - jitpack.io - https://jitpack.io - - - com.google.protobuf @@ -33,9 +26,9 @@ 2.4.2 - com.github.eclipse-uprotocol + org.eclipse.uprotocol up-java - main-SNAPSHOT + 0.1.12-SNAPSHOT org.json diff --git a/up_client_socket/java/src/main/java/org/eclipse/uprotocol/SocketUTransport.java b/up_client_socket/java/src/main/java/org/eclipse/uprotocol/SocketUTransport.java index 9e902271..2784e435 100644 --- a/up_client_socket/java/src/main/java/org/eclipse/uprotocol/SocketUTransport.java +++ b/up_client_socket/java/src/main/java/org/eclipse/uprotocol/SocketUTransport.java @@ -21,12 +21,13 @@ package org.eclipse.uprotocol; -import org.eclipse.uprotocol.rpc.RpcClient; +import org.eclipse.uprotocol.communication.RpcClient; +import org.eclipse.uprotocol.communication.UPayload; import org.eclipse.uprotocol.transport.UListener; import org.eclipse.uprotocol.transport.UTransport; -import org.eclipse.uprotocol.transport.builder.UAttributesBuilder; -import org.eclipse.uprotocol.uri.factory.UResourceBuilder; +import org.eclipse.uprotocol.transport.builder.UMessageBuilder; import org.eclipse.uprotocol.uri.validator.UriValidator; +import org.eclipse.uprotocol.communication.CallOptions; import org.eclipse.uprotocol.v1.*; import org.eclipse.uprotocol.validation.ValidationResult; @@ -48,8 +49,7 @@ public class SocketUTransport implements UTransport, RpcClient { private static final UUri RESPONSE_URI; static { - RESPONSE_URI = UUri.newBuilder().setEntity(UEntity.newBuilder().setName("test_agent_java").setVersionMajor(1)) - .setResource(UResourceBuilder.forRpcResponse()).build(); + RESPONSE_URI = UUri.newBuilder().setUeId(1).setUeVersionMajor(1).setResourceId(0).build(); } private final Socket socket; @@ -178,16 +178,18 @@ private void handleResponseMessage(UMessage umsg) { * @param message The message to be sent. * @return A status indicating the outcome of the send operation. */ - public UStatus send(UMessage message) { + public CompletionStage send(UMessage message) { byte[] umsgSerialized = message.toByteArray(); try { OutputStream outputStream = socket.getOutputStream(); outputStream.write(umsgSerialized); logger.info("uMessage Sent to dispatcher fron java socket transport"); - return UStatus.newBuilder().setCode(UCode.OK).setMessage("OK").build(); + return CompletableFuture.completedFuture(UStatus.newBuilder().setCode(UCode.OK) + .setMessage("uMessage Sent to dispatcher").build()); } catch (IOException e) { logger.log(Level.SEVERE, "INTERNAL ERROR: ", e); - return UStatus.newBuilder().setCode(UCode.INTERNAL).setMessage("INTERNAL ERROR: " + e.getMessage()).build(); + return CompletableFuture.completedFuture(UStatus.newBuilder().setCode(UCode.INTERNAL) + .setMessage("INTERNAL ERROR: " + e.getMessage()).build()); } } @@ -198,13 +200,13 @@ public UStatus send(UMessage message) { * @param listener The listener to be registered. * @return A status indicating the outcome of the registration operation. */ - public UStatus registerListener(UUri topic, UListener listener) { - ValidationResult result = UriValidator.validate(topic); - if (result.isFailure()) { - return result.toStatus(); + public CompletionStage registerListener(UUri sourceFilter, UUri sinkFilter, UListener listener) { + if (!UriValidator.isTopic(sourceFilter)) { + return CompletableFuture.completedFuture(UStatus.newBuilder().setCode(UCode.INVALID_ARGUMENT) + .setMessage("Is not a valid topic URI").build()); } - uri_to_listener.computeIfAbsent(topic, k -> new ArrayList<>()).add(listener); - return UStatus.newBuilder().setCode(UCode.OK).setMessage("OK").build(); + uri_to_listener.computeIfAbsent(sourceFilter, k -> new ArrayList<>()).add(listener); + return CompletableFuture.completedFuture(UStatus.newBuilder().setCode(UCode.OK).setMessage("OK").build()); } /** @@ -214,22 +216,23 @@ public UStatus registerListener(UUri topic, UListener listener) { * @param listener The listener to be removed. * @return A status indicating the outcome of the unregistration operation. */ - public UStatus unregisterListener(UUri topic, UListener listener) { - ValidationResult result = UriValidator.validate(topic); - if (result.isFailure()) { - return result.toStatus(); + public CompletionStage unregisterListener(UUri sourceFilter, UUri sinkFilter, UListener listener) { + if (!UriValidator.isTopic(sourceFilter)) { + return CompletableFuture.completedFuture(UStatus.newBuilder().setCode(UCode.INVALID_ARGUMENT) + .setMessage("Is not a valid topic URI").build()); } - ArrayList listeners = uri_to_listener.get(topic); + ArrayList listeners = uri_to_listener.get(sourceFilter); if (listeners != null && listeners.remove(listener)) { if (listeners.isEmpty()) { - uri_to_listener.remove(topic); + uri_to_listener.remove(sourceFilter); } - return UStatus.newBuilder().setCode(UCode.OK).setMessage("OK").build(); + return CompletableFuture.completedFuture(UStatus.newBuilder().setCode(UCode.OK).setMessage("OK").build()); } - return UStatus.newBuilder().setCode(UCode.NOT_FOUND).setMessage("Listener not found for the given UUri") - .build(); + return CompletableFuture.completedFuture(UStatus.newBuilder().setCode(UCode.NOT_FOUND) + .setMessage("Listener not found for the given URI").build()); } + //TODO: Implement invokeMethod /** * Invokes a remote method with provided parameters and returns a CompletableFuture for the response. * @@ -238,19 +241,17 @@ public UStatus unregisterListener(UUri topic, UListener listener) { * @param options The call options specifying timeout. * @return A CompletableFuture that will hold the response message for the request. */ - public CompletionStage invokeMethod(UUri methodUri, UPayload requestPayload, CallOptions options) { - UAttributes attributes = UAttributesBuilder.request(RESPONSE_URI, methodUri, UPriority.UPRIORITY_CS4, - options.getTtl()).build(); - UUID requestId = attributes.getId(); - CompletableFuture responseFuture = new CompletableFuture<>(); + public CompletionStage invokeMethod(UUri methodUri, UPayload requestPayload, CallOptions options) { + UMessage umsg = UMessageBuilder.request(RESPONSE_URI, methodUri, options.timeout()).build(requestPayload); + UUID requestId = umsg.getAttributes().getId(); + CompletionStage responseFuture = new CompletableFuture<>(); reqid_to_future.put(requestId, responseFuture); - Thread timeoutThread = new Thread(() -> timeoutCounter(responseFuture, requestId, options.getTtl())); + Thread timeoutThread = new Thread(() -> timeoutCounter(responseFuture.toCompletableFuture(), requestId, options.timeout())); timeoutThread.start(); - UMessage umsg = UMessage.newBuilder().setPayload(requestPayload).setAttributes(attributes).build(); send(umsg); - return responseFuture; + return CompletableFuture.completedFuture(null); } /** @@ -271,4 +272,26 @@ private void timeoutCounter(CompletableFuture responseFuture, UUID req Thread.currentThread().interrupt(); } } + + /** + * Closes the socket connection and releases any resources associated with it. + */ + public void close() { + try { + if (!socket.isClosed()) { + socket.close(); + } + } catch (IOException e) { + logger.log(Level.SEVERE, "INTERNAL ERROR: ", e); + } + } + + /** + * Returns the source. + * + * @return The source. + */ + public UUri getSource() { + return RESPONSE_URI; + } } diff --git a/up_client_socket/python/socket_transport.py b/up_client_socket/python/socket_transport.py index c03662e3..2c8f24cf 100644 --- a/up_client_socket/python/socket_transport.py +++ b/up_client_socket/python/socket_transport.py @@ -23,30 +23,26 @@ from concurrent.futures import Future from threading import Lock -from uprotocol.proto.uattributes_pb2 import ( - CallOptions, - UMessageType, - UPriority, -) -from uprotocol.proto.umessage_pb2 import UMessage -from uprotocol.proto.upayload_pb2 import UPayload -from uprotocol.proto.uri_pb2 import UEntity, UUri -from uprotocol.proto.ustatus_pb2 import UCode, UStatus -from uprotocol.rpc.rpcclient import RpcClient -from uprotocol.transport.builder.uattributesbuilder import UAttributesBuilder +from uprotocol.communication.calloptions import CallOptions +from uprotocol.communication.rpcclient import RpcClient +from uprotocol.communication.upayload import UPayload +from uprotocol.transport.builder.umessagebuilder import UMessageBuilder from uprotocol.transport.ulistener import UListener from uprotocol.transport.utransport import UTransport -from uprotocol.uri.factory.uresourcebuilder import UResourceBuilder from uprotocol.uri.validator.urivalidator import UriValidator -from uprotocol.uuid.serializer.longuuidserializer import LongUuidSerializer +from uprotocol.uuid.serializer.uuidserializer import UuidSerializer +from uprotocol.v1.uattributes_pb2 import ( + UMessageType, +) +from uprotocol.v1.ucode_pb2 import UCode +from uprotocol.v1.umessage_pb2 import UMessage +from uprotocol.v1.uri_pb2 import UUri +from uprotocol.v1.ustatus_pb2 import UStatus logger = logging.getLogger(__name__) DISPATCHER_ADDR: tuple = ("127.0.0.1", 44444) BYTES_MSG_LENGTH: int = 32767 -RESPONSE_URI = UUri( - entity=UEntity(name="test_agent_py", version_major=1), - resource=UResourceBuilder.for_rpc_response(), -) +RESPONSE_URI = UUri(ue_id=1, ue_version_major=1, resource_id=0) def timeout_counter(response, req_id, timeout): @@ -55,7 +51,7 @@ def timeout_counter(response, req_id, timeout): response.set_exception( TimeoutError( "Not received response for request " - + LongUuidSerializer.instance().serialize(req_id) + + UuidSerializer.serialize(req_id) + " within " + str(timeout / 1000) + " seconds" @@ -161,27 +157,27 @@ def send(self, message: UMessage) -> UStatus: return UStatus(code=UCode.INTERNAL, message=f"INTERNAL ERROR: {e}") return UStatus(code=UCode.OK, message="OK") - def register_listener(self, topic: UUri, listener: UListener) -> UStatus: + def register_listener(self, source_filter: UUri, listener: UListener, sink_filer: UUri = None) -> UStatus: """ Registers a listener for the specified topic/method URI. """ - status = UriValidator.validate(topic) + status = UriValidator.validate(source_filter) if status.is_failure(): return status.to_status() - uri: bytes = topic.SerializeToString() + uri: bytes = source_filter.SerializeToString() self.uri_to_listener[uri].append(listener) return UStatus(code=UCode.OK, message="OK") - def unregister_listener(self, topic: UUri, listener: UListener) -> UStatus: + def unregister_listener(self, source_filter: UUri, listener: UListener, sink_filer: UUri = None) -> UStatus: """ Unregisters a listener for the specified topic URI. """ - status = UriValidator.validate(topic) + status = UriValidator.validate(source_filter) if status.is_failure(): return status.to_status() - uri: bytes = topic.SerializeToString() + uri: bytes = source_filter.SerializeToString() listeners = self.uri_to_listener.get(uri, []) @@ -200,9 +196,9 @@ def invoke_method(self, method_uri: UUri, request_payload: UPayload, options: Ca """ Invokes a method with the provided URI, request payload, and options. """ - attributes = UAttributesBuilder.request(RESPONSE_URI, method_uri, UPriority.UPRIORITY_CS4, options.ttl).build() + umsg = UMessageBuilder.request(RESPONSE_URI, method_uri, options.timeout).build_from_upayload(request_payload) # Get uAttributes's request id - request_id = attributes.id + request_id = umsg.attributes.id response = Future() self.reqid_to_future[request_id.SerializeToString()] = response @@ -210,7 +206,12 @@ def invoke_method(self, method_uri: UUri, request_payload: UPayload, options: Ca timeout_thread = threading.Thread(target=timeout_counter, args=(response, request_id, options.ttl)) timeout_thread.start() - umsg = UMessage(payload=request_payload, attributes=attributes) self.send(umsg) return response + + def get_source(self) -> UUri: + """ + Returns the source URI of the UTransport. + """ + return RESPONSE_URI